Files
persona/skills/persona-transfer/SKILL.md
T
jiantw83andClaude Opus 5 52a73e81c8 feat: 心裡話與不重複發言、劇場模式同規則、人格匯出匯入
讓人格講話更像正常人,並讓人格可以搬家。

1. 心裡話(inner voice)
   - 新增 `think` 子指令:推導/盤算寫進 state/inner.jsonl,
     只印「💭 心想 N 句」,內容永不回顯給使用者。
   - <persona-context> 每輪帶回最近三句,推論因此有連續性。

2. 短時間內不重複
   - 說出口的話由 Stop hook 自動記進 state/said.jsonl。
   - 新增 `said check|list`:事前確認這句是不是又要說一次。
   - 相似度 = 字元 bigram Jaccard(0.4) + 字集合 Jaccard(0.6),
     門檻 0.72;字集合權重較高才分得開「重排語序」(要擋)
     與「換掉關鍵詞」(是新資訊,放行)。

3. 回話一到三句 + 劇場模式同樣適用
   - 規則注入 turnContext 與 UserPromptSubmit hint。
   - 劇場模式的 CLI 都帶 --quiet,警告會被丟掉,所以 `room post`
     對近似重複與超過三句的發言直接拒收(--allow-repeat / --force 例外),
     host 與 guest 走同一支 CLI,一視同仁。

4. 人格匯出匯入(新 skill persona-transfer)
   - `export` / `import`:單一 JSON bundle(可 gzip)+ sha256 checksum,
     無外部依賴。不帶載入鎖與 guest 租約,journal/ 需明確 --with-journal。
   - 匯出只能匯出本 session 已載入的人格,否則等於跨人格讀取的後門;
     bundle 內的 ../ 逃逸路徑一律拒收。

順帶修正:agents/persona-guest.md 的 CLI 範例都少了 --as-guest,
照著跑會被 requireMember 擋下,guest 根本無法認識自己或發言。

selftest 102 項全綠(新增 ⑪ 說話節制、⑫ 匯出匯入,含重複判定校準對照表)。

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

82 lines
4.3 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-transfer
description: 匯出與匯入人格:把一個人格(身分、靈魂、十二情緒、短期與長期記憶、心智圖、思維導圖、人際關係圖)打包成單一 bundle 檔,或從 bundle 還原/複製成新人格。當使用者說要備份人格、把人格搬到另一台機器或另一個 AI 助理、把人格分享給別人、從檔案還原人格、複製一份人格來做實驗、或問「這個人格能不能帶走」時觸發。不適用於:建立全新人格(用 persona-create 或 persona-anime)、載入既有人格聊天(用 persona-chat)、整理記憶(用 persona-memory)。
---
# 📦 persona-transfer — 人格搬家(匯出/匯入)
**CLI**`node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs"`(一律帶 `--session <PERSONA_SESSION>`
bundle 是**單一 JSON 檔**(可 gzip),不依賴任何外部工具,複製到隨身碟、貼進 git、
傳給另一台機器都可以。
---
## bundle 帶走什麼、不帶什麼
| 帶走 | 不帶 |
| --- | --- |
| `IDENTITY.md` / `SOUL.md` / `AGENTS.md` / `USER.md` | `state/lock.json``state/guests.json`(載入鎖與 guest 租約屬於「那台機器的那個程序」) |
| `state/config.json``state/emotion.json`(十二情緒的 levelsbaseline/半衰期) | `journal/`(原始逐字稿:量大且最私密,要帶請明確加 `--with-journal` |
| `state/inner.jsonl`(心裡話)、`state/said.jsonl`(說過的話) | 任何**其他人格**的資料——一個 bundle 只有一個人格 |
| `memory/`(短期、長期一則一檔、INDEX、inbox | |
| `mindmap/`(心智圖與思維導圖)、`relations/`(關係圖) | |
檔案裡有 `checksum`(sha256),匯入時會驗;對不上就是被改過或損毀。
---
## 匯出
**只能匯出「本 session 目前載入的那個人格」**——這是隔離規則的一部分,
不然匯出就成了把別人的記憶讀出來的後門。所以要先載入它:
```bash
# 1) 先載入(若還沒載入)
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" load --persona <slug> --session <PERSONA_SESSION>
# 2) 匯出
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" export \
--session <PERSONA_SESSION> --out ~/persona-backup/<slug>.persona.json
```
選項:
- `--with-journal`:連逐字稿一起帶(會大很多,而且很私密——**要先問使用者**)。
- `--gzip`:輸出 `.json.gz`(大人格建議加;匯入會自動辨識)。
- `--force`:覆寫已存在的輸出檔。
- 不給 `--out` 就寫到現在的工作目錄,檔名 `<slug>-<時間戳>.persona.json`
**不要把 bundle 寫進人格倉庫裡**`~/.claude/personas/`)——hook 會擋,而且那裡是人格的家,不是備份區。
## 匯入
```bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" import \
--session <PERSONA_SESSION> --file ~/persona-backup/<slug>.persona.json
```
| 情況 | 做法 |
| --- | --- |
| 這台機器還沒有這個人格 | 直接匯入,slug 沿用 bundle 內的名字 |
| 想同時保留兩份(原版 + 實驗版) | `--persona <新 slug>` 換名匯入;`config.json` 會記下它來自誰 |
| 要用匯入的資料**覆蓋**既有人格 | `--force`——**這會蓋掉現有記憶與情緒,先問過使用者**;且該人格不能正被其他程序載入 |
| 匯入後想馬上聊 | 加 `--load`(本 session 沒有載入別的人格時才會生效) |
checksum 對不上會被擋下;要硬吃得加 `--force`,並**主動告訴使用者這份檔案可能被改過**。
## 跟使用者互動的原則
1. **匯出前確認範圍**:要不要帶 `journal/`(逐字稿)。預設不帶。
2. **匯出後回報實際路徑與大小**,還有帶了幾則長期記憶——他要拿去搬家,得知道搬了什麼。
3. **匯入前先 `list`**,看目標 slug 是否已存在:存在就給他「換名匯入 / 覆寫」兩個選擇,
不要自己決定 `--force`
4. 匯入後告訴他 `/jsc-persona:persona-chat <slug>` 就能開始聊。
## 邊界
- 一次一個人格。要搬多個就跑多次(每次都要先 `release``load` 下一個)。
- bundle 內的相對路徑會被驗證,`../` 之類的逃逸路徑一律拒收。
- 匯入不會帶進鎖:新機器上的人格是空閒的,等使用者自己載入。
- 所有面向使用者的輸出使用**繁體中文(台灣用語)**、UTF-8 無亂碼。