Files
persona/hooks/session_start.mjs
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

65 lines
2.5 KiB
JavaScript
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.
#!/usr/bin/env node
// SessionStart:清理死鎖、續租,並把 PERSONA_SESSION 與人格清單注入上下文。
//
// session_id 只有 hook 拿得到,所以這裡把它注入上下文;後續 skill 呼叫 CLI 時
// 必須帶 `--session <這個值>`guard hook 會驗證,程序無法冒用別人的身分。
//
// 人格「由使用者呼叫才載入」:這裡只列出可用人格,不自動載入沒綁過的人格。
import { readEvent, respond } from "./_hook.mjs";
import * as pl from "../scripts/persona-lib.mjs";
const event = readEvent();
if (!event) process.exit(0);
const sessionId = event.session_id || "unknown";
const source = event.source || "startup";
const cwd = event.cwd || null;
pl.gcRuntime();
const data = pl.loadSession(sessionId);
const host = data.host;
const lines = [
"<persona-runtime>",
`PERSONA_SESSION=${sessionId}`,
`人格倉庫:${pl.personaHome()}`,
"規則:",
` 1. 呼叫 persona.mjs 一律帶 \`--session ${sessionId}\`(值不符會被 hook 拒絕)。`,
" 2. 人格**只有使用者叫你載入時才載入**/jsc-persona:persona-chat <slug>),不要自己挑一個人格附身。",
" 3. 一個程序只能載入一個人格;要與別的人格對話請用 /jsc-persona:persona-invite。",
" 4. 禁止直接讀寫非當前人格的目錄,hook 會擋下(跨人格資料隔離)。",
];
if (host && pl.personaExists(host)) {
// resume / compact / clear:把鎖續租回來,並帶回人格狀態
try {
pl.acquireLock(host, sessionId, { cwd });
lines.push(`已接續人格 \`${host}\`session 恢復:${source})。`);
lines.push(pl.turnContext(host, sessionId));
} catch (err) {
lines.push(`⚠ 無法接續人格 \`${host}\`${err.message}`);
}
} else {
const personas = pl.listPersonas();
if (personas.length) {
lines.push("尚未載入人格。可用人格(等使用者指定):");
for (const slug of personas) {
const status = pl.lockStatus(slug);
lines.push(` - ${status.locked ? "🔒" : status.stale ? "⚠" : "🔓"} \`${slug}\` ${pl.identityBrief(slug)}`);
}
lines.push("載入方式:/jsc-persona:persona-chat <slug>");
} else {
lines.push("尚無任何人格。可用 /jsc-persona:persona-create 或 /jsc-persona:persona-anime(動漫作品+角色名)建立。");
}
}
lines.push("</persona-runtime>");
respond({
hookSpecificOutput: {
hookEventName: "SessionStart",
additionalContext: lines.join("\n"),
},
suppressOutput: true,
});