This commit is contained in:
2026-07-29 14:37:20 +00:00
parent 9c0973ead4
commit 4426ede979
33 changed files with 5128 additions and 216 deletions
+221 -155
View File
@@ -1,189 +1,255 @@
# jsc-template AI 助理 Plugin 模板
# jsc-persona — AI 人格化記憶聊天
個可同時被 **Claude Code、Codex、Antigravity、OpenCode** 安裝的 plugin 模板
核心是以 [Agent Skills`SKILL.md`](https://agentskills.io) 標準撰寫的共用 skills(唯一真實來源放在 `skills/`
搭配各助理各自的 plugin manifest,讓**同一個 repo** 可用各家**原生 plugin CLI** 安裝。
在 Claude Code 與 Antigravity 中,skill 以 **`/jsc-template:` 前綴**呼叫(例如 `/jsc-template:hello`
套讓 AI **成為某個人**、而不只是回答問題的 plugin。
**OpenClaw 相同的人格描述**`IDENTITY.md` 五欄位 + `SOUL.md` 四段落)建立人格
再用 **hook 強制**的人格鎖與跨人格隔離,把 **十二情緒**、**語意分析**、
**短期/長期記憶**、**心智圖/思維導圖**、**人際關係圖** 綁在一起
可同時安裝於 **Claude Code、Codex、Antigravity、OpenCode**
skills 是共通標準,**鎖與隔離的強制執行需要 hook,目前只有 Claude Code 支援**(見「跨助理支援度」)。
---
## 前綴與呼叫方式
## 四條硬規則
| 助理 | 安裝方式 | 呼叫 | `/jsc-template:` 前綴 |
| --- | --- | --- | --- |
| Claude Code | `claude plugin`marketplace | `/jsc-template:<name>` 或自動觸發 | ✅ |
| Codex | `codex plugin`marketplace | `$<name>``/skills` 選單 | ❌(用 `$name` |
| Antigravity | `agy plugin install` | `/jsc-template:<name>` 或自動觸發 | ✅ |
| OpenCode | skills 目錄(複製/clone) | 描述需求自動觸發 | ❌(依名稱) |
> Codex 不支援自訂前綴(skill 以 `$name` 呼叫);OpenCode 由模型依描述自動呼叫。兩者皆**不強制**前綴。
| 規則 | 怎麼做到 |
| --- | --- |
| **1. 用與 OpenClaw 相同的描述建立人格** | `persona-create` 逐項索取 `Name` / `Creature` / `Vibe` / `Emoji` / `Avatar`(連括號提示文字都照 OpenClaw 原文),`SOUL.md` 沿用 `Core Truths` / `Boundaries` / `Vibe` / `Continuity` 段落結構 |
| **2. 同一個人格只能被一個程序載入(Sub Agent 不限)** | `state/lock.json`**session_id** 為主鍵、15 分鐘心跳租約;同一 session 的 sub agent 沿用同一把鎖,跨 session 搶佔會被拒;租約過期才可接手(並強制回報 |
| **3. 禁止跨人格讀取資料** | `PreToolUse` hook 對 Read/Write/Edit/Glob/Grep/Bash 做路徑判定(含 `../`、symlink、`$PERSONA_HOME` 繞路),非當前人格一律 deny;CLI 也驗 `--session` 防止冒用身分 |
| **4. 可以邀請人格透過 Sub Agent 一起聊天** | `persona-invite` 建聊天室 + guest 唯讀租約,用 `persona-guest` sub agent 啟動對方;兩邊只能透過聊天室交換「說出口的話」,記憶與情緒互不可見 |
---
## 目錄結
##
同一個 repo 同時帶四種 manifest,彼此以路徑隔離、互不干擾;四家都讀同一份 `skills/`
```
template/
├── .claude-plugin/
│ ├── plugin.json # Claude 外掛定義(name: "jsc-template"
│ └── marketplace.json # Claude marketplacename: "jsc-plugins"source 指向本 repo
├── .codex-plugin/
│ └── plugin.json # Codex 外掛定義(name: "jsc-template"skills: "./skills"
├── .agents/plugins/
│ └── marketplace.json # Codex marketplacename: "jsc-plugins"url source 指向本 repo
├── plugin.json # Antigravity 外掛定義(name: "jsc-template"skills: "./skills/"
├── skills/ # ★ 唯一真實來源:所有 skills
│ └── hello/SKILL.md
├── AGENTS.md # 跨助理共用指引
└── README.md
```mermaid
flowchart TB
subgraph P["主程序(一個 session = 一個人格)"]
U["使用者訊息"] --> H1["UserPromptSubmit hook<br/>注入 情緒+短期記憶+命中的長期記憶+關係"]
H1 --> A["語意分析:意圖/主題/實體/情感/需求"]
A --> E["情緒評估 → 十二情緒 deltas"]
E --> R["以人格語氣回覆"]
R --> W["記憶回寫(短期)"]
W --> H2["Stop hook:情緒衰減+續租+固化提醒"]
end
subgraph G["Sub Agent(受邀人格,唯讀)"]
GA["persona-guest"]
end
subgraph S["人格倉庫 ~/.claude/personas"]
PA["alpha/IDENTITY SOUL 記憶 情緒 心智圖 關係圖"]
PB["beta/|…"]
RM[".rooms/room/transcript.jsonl"]
end
P -->|"只能碰自己"| PA
GA -->|"只能碰自己"| PB
P <-->|"唯一合法交流管道"| RM
GA <--> RM
```
---
## 人格倉庫(預設 `~/.claude/personas/<slug>/`,可用 `PERSONA_HOME` 覆寫)
## 安裝 / 更新 / 移除(各家原生 plugin CLI
> 指令中的 repo 網址換成你的:`https://gitea.jsc.idv.tw/plugins/template.git`
>
> **Claude / Codex 從 git URL 安裝(會 clone 遠端),請先把本 repo `push` 到 gitea。**
> **Antigravity 的 `agy plugin install <url>` 目前只支援 github.com**gitea 請改用「clone + 本地路徑」(見 Antigravity 節)。
> 本機/離線:Claude 可用本地路徑加 marketplaceAntigravity 用本地路徑安裝。
### Claude Code
```bash
# 安裝
claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/template.git
claude plugin install jsc-template@template
# 更新
claude plugin marketplace update template
claude plugin update jsc-template@template
# 移除
claude plugin uninstall jsc-template@template
claude plugin marketplace remove template
```
<slug>/
├── IDENTITY.md # 身分卡:Name / Creature / Vibe / Emoji / AvatarOpenClaw 同欄位)
├── SOUL.md # 靈魂:Core Truths / Boundaries / Vibe / Continuity + 情緒傾向
├── AGENTS.md # 操作規則(與個性分離)
├── USER.md # 對使用者的畫像(事實/推測分開)
├── state/
│ ├── lock.json # 載入鎖(session_id + 心跳租約)
│ ├── guests.json # guest 唯讀租約
│ ├── emotion.json # 十二情緒 levels / baseline / 半衰期
│ └── config.json
├── memory/
│ ├── short-term.jsonl # 短期記憶(語意分析後;上限 240 筆 / 14 天)
│ ├── long-term/*.md # 長期記憶(一則一檔 + frontmatter
│ ├── INDEX.md # 長期記憶索引(自動產生)
│ └── inbox/room-*.jsonl # 當 guest 時留下的見聞,待本體消化
├── mindmap/
│ ├── semantic.mmd # 心智圖:概念的長期關聯(Mermaid mindmap
│ └── threads/*.mmd # 思維導圖:單一話題的推理鏈(Mermaid graph,短期)
├── relations/
│ ├── graph.json # 人際關係圖(親近度/信任度/連線)
│ └── graph.mmd # Mermaid 呈現(自動產生)
└── journal/YYYY-MM.jsonl # 原始逐字 + 情緒史(hook 自動寫)
```
- 工作階段內 slash 版(等價):把 `claude plugin` 換成 `/plugin`
- 本機開發(免 push):`claude plugin marketplace add C:\Users\h3285\source\repos.plugins\template`(本地路徑)後再 install。
- **呼叫**`/jsc-template:<name>`(例 `/jsc-template:hello`)。
## 十二情緒
### Codex
| 六正向 | 六負向 |
| --- | --- |
| 喜悅 `joy`、信任 `trust`、期待 `anticipation`、感激 `gratitude`、平靜 `serenity`、驚喜 `delight` | 憤怒 `anger`、悲傷 `sadness`、恐懼 `fear`、厭惡 `disgust`、羞愧 `shame`、焦慮 `anxiety` |
```bash
# 安裝
codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/template.git
codex plugin add jsc-template@template
- 每種 0–100,各有**不同半衰期**(驚喜 60 分最快、信任 720 分最慢),每輪自動朝 `baseline` 指數衰減。
- 由十二情緒推導 `valence`(正向/中性/負向)與 `arousal`(高張/平穩/低張),決定語氣與句長。
- **主導情緒**取「超出基線最多」的前三名,所以個性底色不會永遠霸榜。
- 觸發規則與事件→delta 對照表:`skills/persona-chat/reference/emotions.md`
# 更新(重新抓取 marketplace 的 git 快照)
codex plugin marketplace upgrade template
## HooksClaude Code
# 移除
codex plugin remove jsc-template@template
codex plugin marketplace remove template
```
| Hook | 做什麼 |
| --- | --- |
| `SessionStart` | 清死鎖、接續人格、把 `PERSONA_SESSION=<session_id>` 與規則注入上下文 |
| `UserPromptSubmit` | 注入 `<persona-context>`:身分、情緒、短期記憶、關鍵詞命中的長期記憶、相關人際關係;並記原始逐字 |
| `PreToolUse` | **人格隔離與鎖驗證的唯一強制點**deny 帶原因) |
| `Stop` | 情緒隨時間衰減、續租、記錄回覆、短期記憶過多時提醒固化 |
| `SubagentStop` | 解除 guest sub agent 的 pin |
| `SessionEnd` | 釋放鎖與 guest 租約,人格才能被下一個程序載入 |
- 安裝 token `jsc-template@template` = plugin 名(`.codex-plugin/plugin.json``name`@ marketplace 名(`.agents/plugins/marketplace.json``name`)。
- 本 repo 的 Codex marketplace 以 `url` 來源指向自己,故 Codex **一律從 gitea 安裝**(需先 push);安裝後重啟 Codex
- **呼叫**`$<name>`(例 `$hello`),或用 `/skills` 選單。
### Antigravity`agy`
> `agy plugin install <url>` 目前**只支援 github.com**gitea 等自架 git 不支援 URL 安裝,請先 `git clone` 再用**本地路徑**安裝。
```bash
# 安裝:clone 後用本地路徑
git clone https://gitea.jsc.idv.tw/plugins/template.git ~/plugins/template
agy plugin install ~/plugins/template
# 更新(agy 無 update 子指令 → git pull 後重裝)
git -C ~/plugins/template pull
agy plugin uninstall jsc-template
agy plugin install ~/plugins/template
# 移除
agy plugin uninstall jsc-template
```
- 若把 skills 放到 GitHub,則可直接 `agy plugin install https://github.com/<owner>/<repo>`
- 其他:`agy plugin list``agy plugin enable jsc-template` / `disable jsc-template``agy plugin validate <path>`。安裝後重啟工作階段。
- **呼叫**`/jsc-template:<name>`(例 `/jsc-template:hello`)或依描述自動觸發。
### OpenCode
OpenCode 的「plugin」是 TypeScript/npm 套件,不適用於 skill 包;skills 改用**目錄安裝**。
OpenCode 會讀 `~/.config/opencode/skills/`(也會讀 `~/.claude/skills/``~/.agents/skills/`)。
```bash
# 安裝
git clone https://gitea.jsc.idv.tw/plugins/template.git ~/plugins/template
mkdir -p ~/.config/opencode/skills
cp -r ~/plugins/template/skills/* ~/.config/opencode/skills/
# 更新
git -C ~/plugins/template pull
cp -r ~/plugins/template/skills/* ~/.config/opencode/skills/
# 移除
rm -rf ~/.config/opencode/skills/hello
```
> **Windows PowerShell**`cp -r A B` → `Copy-Item A B -Recurse -Force`、`rm -rf X` → `Remove-Item X -Recurse -Force`、`~` → `$HOME`。
- **呼叫**:直接描述需求,模型會依 skill 描述自動透過 skill 工具呼叫。
---
## 用 CLI 直接執行 skillheadless / 一次性)
安裝好之後,不必進互動介面,一行指令就能叫某個 skill 跑完並印出結果:
| 助理 | headless 指令 | 執行 `hello` skill |
| --- | --- | --- |
| Claude Code | `claude -p "<prompt>"` | `claude -p "/jsc-template:hello"` |
| Codex | `codex exec "<prompt>"` | `codex exec '$hello'` |
| Antigravity | `agy -p "<prompt>"` | `agy -p "/jsc-template:hello"` |
| OpenCode | `opencode run "<message>"` | `opencode run "用 hello skill 打個招呼"` |
- Claude / Antigravity 支援 `/jsc-template:` 前綴,直接 `-p "/jsc-template:<name>"` 即可。
- Codex 以 `$<name>` 觸發;在 shell 請用**單引號**避免 `$` 被展開:`codex exec '$hello'`
- OpenCode 沒有前綴,用自然語言描述需求,模型會自動透過 skill 工具呼叫。
- 帶引數就接在後面,例如 `claude -p "/jsc-template:hello 參數"``codex exec '$hello 參數'`
> `session_id` 只有 hook 拿得到 → 注入上下文 → skills 呼叫 CLI 時必須帶 `--session`
> hook 會驗證是否相符。**這是「一人格一程序」與「跨人格隔離」不能被繞過的關鍵**
---
## Skills 目錄
> 此區塊列出本 plugin 內含的所有 skills(名稱/描述/使用方法)。
> 新增或修改 skill 後,請同步手動更新標記之間的內容。
<!-- JSC-SKILLS:START -->
### `hello`
### `persona-create`
範例 skill,用來驗證 jsc plugin 是否安裝成功,也是新增 skill 的範本。當使用者輸入 hello、想測試 plugin、或想看 skill 模板長什麼樣子時觸發;回覆一句問候並簡述此 plugin 的用途
建立人格:以 OpenClaw 相同的五個身分欄位與 SOUL 段落訪談使用者,初始化情緒基線、記憶、心智圖與關係圖,並立即取得載入鎖
- **Claude Code / Antigravity**`/jsc-template:hello`
- **Codex**`$hello`,或用 `/skills` 選單
- **OpenCode**:描述需求自動觸發
- **Claude Code / Antigravity**`/jsc-persona:persona-create` **Codex**`$persona-create`
### `persona-chat`
載入人格並對話:取得獨占鎖 → 每輪做語意分析 → 更新十二情緒 → 回想記憶與關係 → 以人格語氣回覆 → 寫回記憶。
- **Claude Code / Antigravity**`/jsc-persona:persona-chat <slug>` **Codex**`$persona-chat`
### `persona-invite`
邀請另一個人格透過 `persona-guest` sub agent 加入聊天室,形成多人格對話;結束後讓它離場並把見聞留在它自己的 inbox。
- **Claude Code / Antigravity**`/jsc-persona:persona-invite <slug>` **Codex**`$persona-invite`
### `persona-memory`
記憶固化:短期 → 長期(一則一檔)、淘汰雜訊、更新心智圖與思維導圖、消化 guest inbox、重建索引。
- **Claude Code / Antigravity**`/jsc-persona:persona-memory` **Codex**`$persona-memory`
### `persona-relation`
人際關係圖維護:節點/連線、親近度與信任度調整、輸出 Mermaid 關係圖。
- **Claude Code / Antigravity**`/jsc-persona:persona-relation` **Codex**`$persona-relation`
### `persona-status`
載入狀態與鎖管理:誰被哪個程序鎖住、guest 租約、釋放、接手死鎖、清理殘留。
- **Claude Code / Antigravity**`/jsc-persona:persona-status` **Codex**`$persona-status`
<!-- JSC-SKILLS:END -->
### Agents
- `persona-guest``agents/persona-guest.md`)— 受邀人格的 sub agent,唯讀、被綁死在自己的人格目錄。
### CLI 與自我測試
所有狀態變更都經過 `scripts/persona.py`(純標準庫,無外部依賴):
```bash
python3 scripts/persona.py --help
python3 scripts/persona.py list
python3 scripts/selftest.py # 51 項驗證:鎖、隔離、情緒、記憶、聊天室、hooks
```
---
## 新增一個 skill
## 跨助理支援度
1. 複製範本:`cp -r skills/hello skills/<your-skill-name>`
2. 編輯 `skills/<your-skill-name>/SKILL.md` 的 frontmatter
- `name`:小寫、數字、連字號(`-`),最長 64 字元。**這就是 Claude Code / Antigravity 的 `/jsc-template:<name>`**。
- `description`:第三人稱,寫清楚「何時用、何時不用」與觸發關鍵字 — 這是各助理自動載入的唯一依據。
3. 在內文寫下 skill 的具體步驟。
4. 手動把這個 skill 補進上方「Skills 目錄」區塊。
5. **bump 版本並 push**:四家都以 git 內容/版本判斷更新,請把 `.claude-plugin/plugin.json``.codex-plugin/plugin.json``plugin.json` 三個 manifest 的 `version` 一起 bumpcommit 後 push 到 gitea。
6. 讓各助理更新:
- Claude`claude plugin update jsc-template@jsc-plugins`
- Codex`codex plugin marketplace upgrade jsc-plugins`
- Antigravity`git -C ~/jsc-plugin pull && agy plugin uninstall jsc-template && agy plugin install ~/jsc-plugin`
- OpenCode`git pull` 後重新複製 `skills/`
| 助理 | skills | hooks(鎖/隔離強制) | 受邀人格 sub agent |
| --- | --- | --- | --- |
| Claude Code | ✅ `/jsc-persona:<name>` | ✅ 完整 | ✅ `jsc-persona:persona-guest` |
| Codex | ✅ `$<name>` | ❌ | ⚠ 需自行以子任務模擬 |
| Antigravity | ✅ `/jsc-persona:<name>` | ❌ | ⚠ |
| OpenCode | ✅ 依描述自動觸發 | ❌ | ⚠ |
> 沒有 hook 的助理仍會遵守 CLI 層的檢查(`--session` 綁定、`require_owner``require_member`、
> guest 唯讀),但那是**自律**而非強制:真正的 deny 只有 Claude Code 的 `PreToolUse` 做得到。
---
## 安裝 / 更新 / 移除
> 指令中的 repo 網址換成你的:`https://gitea.jsc.idv.tw/plugins/persona.git`
> **Claude / Codex 從 git URL 安裝(會 clone 遠端),請先把本 repo `push` 到 gitea。**
### Claude Code
```bash
claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/persona.git
claude plugin install jsc-persona@jsc-plugins
# 更新
claude plugin marketplace update jsc-plugins
claude plugin update jsc-persona@jsc-plugins
# 移除
claude plugin uninstall jsc-persona@jsc-plugins
```
- 工作階段內 slash 版(等價):把 `claude plugin` 換成 `/plugin`
- 本機開發(免 push):`claude plugin marketplace add /home/coder/plugins/persona` 後再 install。
- 安裝後**重啟工作階段**讓 hooks 生效;用 `/hooks` 確認六個 hook 都在。
### Codex
```bash
codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/persona.git
codex plugin add jsc-persona@jsc-plugins
codex plugin marketplace upgrade jsc-plugins # 更新
codex plugin remove jsc-persona@jsc-plugins # 移除
```
### Antigravity`agy`
> `agy plugin install <url>` 目前只支援 github.comgitea 請 clone 後用本地路徑。
```bash
git clone https://gitea.jsc.idv.tw/plugins/persona.git ~/plugins/persona
agy plugin install ~/plugins/persona
# 更新:git -C ~/plugins/persona pull && agy plugin uninstall jsc-persona && agy plugin install ~/plugins/persona
```
### OpenCode
```bash
git clone https://gitea.jsc.idv.tw/plugins/persona.git ~/plugins/persona
mkdir -p ~/.config/opencode/skills
cp -r ~/plugins/persona/skills/* ~/.config/opencode/skills/
```
> **Windows PowerShell**`cp -r A B` → `Copy-Item A B -Recurse -Force`、`~` → `$HOME`。
### headless 一次性執行
| 助理 | 指令 |
| --- | --- |
| Claude Code | `claude -p "/jsc-persona:persona-chat lumi"` |
| Codex | `codex exec '$persona-chat lumi'` |
| Antigravity | `agy -p "/jsc-persona:persona-chat lumi"` |
| OpenCode | `opencode run "用 lumi 這個人格跟我聊聊"` |
---
## 設計取捨(讀之前先知道)
- **記憶是被策展的,不是全存**:逐字稿進 `journal/`,但只有經過語意分析、有顯著度的內容才進短期記憶,
再由 `persona-memory` 決定什麼值得成為長期記憶。**遺忘是功能**。
- **事實與推測分離**:推論走思維導圖(`mindmap/threads/`),驗證後才升格長期記憶。
- **鎖的擁有者是 session 不是 process**CLI 跑完就結束,所以租約判定只看心跳。
- **guest 唯讀**:受邀人格不能在別人的 session 裡改自己的長期記憶(避免兩個程序同時寫),
只能把見聞放進 `memory/inbox/`,等它自己被載入時消化。
- **hook 是強制、SKILL 是引導**SKILL.md 寫的規則模型可能忘記,hook 不會。
## 新增/修改 skill
1. 複製一個現有 skill 目錄,改 `SKILL.md``name``description`(描述要寫清楚何時用、何時不用)。
2. 需要新的狀態操作 → 加到 `scripts/persona.py` 的子指令,並在 `scripts/selftest.py` 補測試。
3. 動到隔離規則 → 一定要在 `selftest.py` 的第 ③/⑦ 區加對應案例,跑到全綠。
4. 把 skill 補進上方「Skills 目錄」區塊。
5. bump `.claude-plugin/plugin.json``.codex-plugin/plugin.json``plugin.json` 三處 `version`commit 後 push。