Files
persona/skills/persona-transfer/SKILL.md
T
jiantw83andClaude Sonnet 5 ac2045e52f feat(persona): 時區改為+08:00等值轉換、補機密遮蔽,並接上shared共用規範
依 todo.md 執行的規範治理專案:
- persona-lib.mjs 的 iso()/nowIso() 改為輸出 +08:00 offset(等值瞬間轉換,
  非加8小時),新增 nowDisplay()(人讀顯示格式)與 todayTaipei()(台北曆日
  日期鍵),修正 11 處原本用 UTC 字串切片產生日期鍵的錯誤用法;新增
  redactSecrets() 並套用到 persona-gitea.mjs 的 Gitea 錯誤路徑,避免機密
  外洩。
- 新增一次性遷移腳本 scripts/migrate-tz.mjs(備份/dry-run/冪等/衝突偵測
  中止),供之後有真實人格資料需要轉換時使用。
- persona 13 個 skill 與 AGENTS.md 接上 /jsc-shared 共用規範(spec-output、
  spec-script-path、spec-subagent、spec-gitea、spec-git-safety、
  spec-skill-invocation 等),不再各自重抄,且完全未變動人格行為本身的規範
  (情緒模型、記憶衰減、劇場模式、鎖與隔離機制等逐字保留)。
- selftest 全數通過(788/788,含本次新增的時區邊界/冪等性測試)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:06:00 +00:00

6.9 KiB
Raw Blame History

name, description
name description
persona-transfer 匯出與匯入人格:把一個人格(身分、靈魂、十二情緒、短期與長期記憶、心智圖、思維導圖、人際關係圖)打包成單一 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、 傳給另一台機器都可以。

只是要在另一台機器接續同一個人格、而且兩邊都連得到 Gitea 的話,不必經過檔案: 用 /jsc-persona:persona-sync 的 clone --code <編號> 直接從存取庫拉一份回來。 這裡的 bundle 是給離線、換助理、或想留一份快照的情境。


共用規範(必要前置)

先載入 /jsc-shared:spec-preflight 並依其流程處理;載入不到即代表 shared plugin 未安裝, 依該 spec 詢問使用者是否安裝 https://gitea.jsc.idv.tw/plugins/shared.git,不安裝則中斷本 skill。 本 skill 需要的規範:spec-output、spec-execution、spec-time-log、spec-script-path


bundle 帶走什麼、不帶什麼

帶走 不帶
IDENTITY.md / SOUL.md / AGENTS.md / USER.md state/lock.json、state/guests.json(載入鎖與 guest 租約屬於「那台機器的那個程序」)
state/config.json、state/emotion.json(十二情緒的 levels/baseline/半衰期) journal/(原始逐字稿:量大且最私密,要帶請明確加 --with-journal)
state/mood.json(當日心情底色)、state/loops.json(懸著的事)、state/probe.jsonl(試探紀錄) 任何其他人格的資料——一個 bundle 只有一個人格
state/inner.jsonl(心裡話)、state/said.jsonl(說過的話)
memory/(短期、長期一則一檔、INDEX、inbox)
mindmap/(心智圖與思維導圖)、relations/(關係圖)

規則很簡單:除了鎖與租約,人格目錄裡的東西都帶走。所以之後新增的狀態檔不必回頭改這張表—— state/lock.json 與 state/guests.json 是唯一兩個明文排除的(它們描述的是「那台機器的那個程序」, 換一台機器就是假的)。

檔案裡有 checksum(sha256),匯入時會驗;對不上就是被改過或損毀。


bundle 版本(目前 v2)

版本 差在哪
v1 長期記憶只有 salience;內文不分層;沒有 mood.json/loops.json/probe.jsonl
v2 長期記憶多了 strength(回想強度)與 when/where/mood(情境索引),內文分「主旨/細節」兩層;狀態多了當日心情底色、未完事項、試探紀錄
  • 舊的 v1 bundle 照樣吃得下:import 寫完檔案會就地跑一次 migration 補齊欄位並切分內文, 所以匯入之後這台機器上只有一種格式,不必到處判版本。
  • 遷移失敗不會讓整個匯入失敗(INDEX 還是要重建),代價是它也不會出現在人看的輸出裡—— 只有 --json 的 migrated 看得到統計,是 null 就代表那次遷移出過錯。 匯進來卻沒升格式的人格,它的老記憶進不了衰減與模糊態,等於最重要的那批記憶反而沒效果, 所以匯入舊 bundle 之後補跑一次比較保險:migrate --session <PERSONA_SESSION> --dry-run 看還有沒有東西要動,有就跑一次不帶 --dry-run 的。
  • 比本版新的 bundle 會被擋下(validateBundle 直接判不合法):未來的欄位沒有辦法猜, 硬吃會把不認得的資料寫進人格目錄。這種時候該更新 plugin,不是加 --force。

匯出

只能匯出「本 session 目前載入的那個人格」——這是隔離規則的一部分, 不然匯出就成了把別人的記憶讀出來的後門。所以要先載入它:

# 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 會擋,而且那裡是人格的家,不是備份區。

匯入

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. 匯入的是 v1 bundle 就講一句:長期記憶已經升成新格式(補回想強度、切主旨/細節)。 這會改變那個人格「記得多清楚」的行為,使用者有權知道搬過來的不完全是原樣。
  5. 匯入後告訴他 /jsc-persona:persona-chat <slug> 就能開始聊。

邊界

  • 一次一個人格。要搬多個就跑多次(每次都要先 release 再 load 下一個)。
  • bundle 內的相對路徑會被驗證,../ 之類的逃逸路徑一律拒收。
  • 匯入不會帶進鎖:新機器上的人格是空閒的,等使用者自己載入。