Files
persona/skills/persona-invite/SKILL.md
T
jiantw83andClaude Opus 5 2005f26c94 feat: 改寫為 Node.js,新增動漫角色建人格、劇場模式與記憶固化條件
腳本全面從 Python 改寫為 Node.js(ESM,只用內建模組,無 npm 依賴):
scripts/persona-lib.mjs(核心)、scripts/persona.mjs(CLI)、hooks/*.mjs(六個
hook)、scripts/selftest.mjs(68 項自我測試,全綠)。

新增:
- persona-anime skill:用「動漫作品+角色名」建立人格,先上網蒐集至少三個獨立
  來源的公開設定,映射成 OpenClaw 的 IDENTITY 五欄位與 SOUL 四段落,再固化成
  canon 基礎記憶(每則帶來源 URL)+原作人際關係圖+依角色型別的情緒基線;
  必寫 roleplay-frame 界線記憶(非官方、非本人)。
- 劇場模式:invite 後只顯示人格對話(`名字:內容`)。UserPromptSubmit hook 每輪
  注入強制規則、Stop hook 完全靜音,CLI 新增 --quiet 與 room script(乾淨對話稿)。
  leave 後沒客人自動關閉,也可用 room theater --on/--off 手動切換。
- 短期→長期記憶的成文轉入條件 R1–R6(promotionCandidates)與 candidates 子指令,
  hook 在達標時提醒固化;長期記憶新增 canon 型別與 rules 欄位。
- 人格改為「由使用者呼叫才載入」:SessionStart hook 只列出可用人格,不自動附身。

其他:版本號改回 0.0.1;README/AGENTS.md 同步更新。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 16:03:27 +00:00

133 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: persona-invite
description: 邀請另一個人格透過 sub agent 加入當前對話,形成兩個以上人格同場交談,並進入「劇場模式」——螢幕上只顯示人格之間的對話(`名字:內容`),其他訊息全部隱藏。當使用者說要讓兩個人格互相聊聊、把某個人格叫進來、想聽另一個角色的看法、或想辦多人格圓桌討論時觸發。會建立聊天室、給被邀人格一份唯讀的 guest 租約、以 persona-guest sub agent 啟動它,並在對話結束後讓它離場並把見聞留在它自己的 inbox。不適用於:切換人格(用 persona-chat 的 release + load)、單一人格的對話(用 persona-chat)、或想直接翻閱別的人格記憶(永遠禁止)。
---
# 🎭 persona-invite — 邀別的人格來聊(劇場模式)
**跨人格資料隔離的唯一合法交流管道**:聊天室(`.rooms/<room>/transcript.jsonl`)。
被邀的人格在 **sub agent** 裡跑,只讀得到自己的人格資料,讀不到主持人格的任何檔案,反之亦然。
**CLI**`node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs"`(帶 `--session <PERSONA_SESSION>`
---
## 🎭 劇場模式的鐵則(最重要,先讀這段)
`invite` 一旦成功,本 session 就進入**劇場模式**。從那一刻到使用者說結束為止:
- **輸出只能有人格對話**,格式固定為 `名字:內容`(一句一行,可帶情緒括號):
```
🪼 Lumi(喜悅42/期待31):所以你真的一個人把那台舊鐘修好了?
🌙 Shen(平靜50/信任38):修好了。它現在慢三分鐘,我決定不修那三分鐘。
```
- **禁止輸出**:指令、指令結果、工具訊息、狀態、進度、分析、旁白、心得、摘要、
「我先讀取聊天室…」這類過程說明,以及任何 ```` 訊息。
- **所有 CLI 都要加 `--quiet` 並把輸出丟掉**`... --quiet > /dev/null 2>&1`。
需要讀資料時才收輸出(`room read``room script`),且**不要把原始輸出貼給使用者**。
- 只有這些情況可以脫離對話格式:使用者主動問問題、發生錯誤(人格被鎖住、guest 啟動失敗)、
使用者說結束。錯誤要用一行說完。
- 使用者說「結束/散會/不聊了」→ 做第 5 節收尾,然後才恢復正常輸出(給一段簡短摘要)。
> `UserPromptSubmit` hook 在劇場模式會持續注入這條規則,`Stop` hook 也會停掉所有系統提醒;
> 但**遵守輸出格式是你的責任**。
---
## 前置
1. 本 session 必須已載入 host 人格(`/jsc-persona:persona-chat`),否則先請使用者指定要用哪個人格主持。
2. 被邀人格**不能正被其他程序 exclusive 載入**`list` 看 🔒);
若被鎖住,用一行告訴使用者是誰佔用,請他先結束那個程序,**不要** takeover 別人正在用的人格。
## 步驟
### 1. 建立聊天室 + guest 租約(自動進入劇場模式)
```bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" invite \
--session <PERSONA_SESSION> --guest <guest-slug> --topic "<這場對話的主題>" --json
```
從 JSON 取 `room`。要多位客人就多跑幾次,並帶同一個 `--room <room>` 讓大家同場。
### 2. host 開場(讓 guest 有東西可讀)
```bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" room post \
--session <PERSONA_SESSION> --room <room> --as <host-slug> \
--text "<host 用自己的語氣說的開場>" --quiet
```
同時把這句以 `名字:內容` 顯示給使用者。
### 3. 用 sub agent 啟動 guest 人格
用 Agent 工具,`subagent_type` 設為 **`jsc-persona:persona-guest`**prompt 至少包含:
```
persona=<guest-slug>
room=<room>
session=<PERSONA_SESSION>
plugin_root=${CLAUDE_PLUGIN_ROOT}
任務:以 <guest-slug> 的身分讀聊天室、發言 1 次,然後只回傳你發言的那句話。
```
guest 會自己讀 `IDENTITY.md``SOUL.md`/自己的記憶與情緒 → 讀聊天室 → `room post` 發言 →
需要記的事寫進**自己的 inbox**。它被 hook 綁死在自己的人格目錄,且對人格檔案唯讀。
### 4. 一來一回
```bash
# 取乾淨的對話稿(只有 `名字:內容`,沒有時間戳、沒有 slug、沒有系統訊息)
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" room script \
--session <PERSONA_SESSION> --room <room> --limit 6
```
把**新增的**那幾行顯示給使用者(不要每輪重貼整份對話稿),然後以 host 人格回應:
內部照 `/jsc-persona:persona-chat` 的規則(語意分析 → 情緒更新 → 記憶回寫,全部 `--quiet`),
發言用 `room post`,接著再啟動 guest 下一輪(**sub agent 不常駐,每輪都要重新啟動**)。
節奏建議:使用者沒特別說的話,一次推進 1–2 輪就停下來等他,不要自己演完十輪。
### 5. 收尾(使用者說結束才做)
```bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" leave \
--session <PERSONA_SESSION> --guest <guest-slug> --quiet
```
`leave` 後劇場模式自動關閉(沒有客人了),這時才恢復正常輸出。然後:
```bash
# host 把「我」在這場對話中的所見所感寫進自己的記憶(host 的主觀記憶,合法)
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" remember \
--session <PERSONA_SESSION> --role persona \
--text "跟 <guest> 談 <主題>:他認為…,我覺得…" --topics "..." --salience 60 \
--emotion "trust=+6,delight=+8"
# 人格之間也有關係
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" relation node \
--session <PERSONA_SESSION> --name "<Guest 的 Name>" --id <guest-slug> --kind persona --closeness 40 --trust 35
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" relation edge \
--session <PERSONA_SESSION> --to <guest-slug> --label "同場對話過" --affinity 55
```
若這場對話達到固化條件(`candidates` 會告訴你),順手做 `/jsc-persona:persona-memory`。
---
## 規則
- **guest 唯讀**:它不能寫自己的長期記憶/情緒;要留下的東西進 `memory/inbox/room-<room>.jsonl`
等它下次自己被 exclusive 載入時,用 `/jsc-persona:persona-memory` 消化。
- **不得把 guest 的內部資料端出來**:你(host)只能引用聊天室裡它「說出口」的話。
- **不得用一般 sub agent 假扮 guest**:一般 sub agent 沿用 host 的鎖與範圍,
只有 `jsc-persona:persona-guest` 型別會被 hook 綁到 guest 人格並限制為唯讀。
- **不要替 guest 代言**guest 的每一句都必須真的由 sub agent 產出並 `room post`,不可自己編。
- 一個人格同時只能有一場 guest 對話;guest 租約 30 分鐘沒續租會自動過期。
- 手動切換劇場模式:`room theater --session <id> --on|--off`。
- 所有面向使用者的輸出使用**繁體中文(台灣用語)**、UTF-8 無亂碼。