@riconext/hermes-repo 0.15.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/config/debugLog.ts","../src/init/paths.ts","../src/config/readConfig.ts","../src/config/findRepoRoot.ts","../src/capture/runLlmJob.ts","../src/config/llmConfig.ts","../src/config/readLlmConfig.ts","../src/capture/claude-code/parseJsonl.ts","../src/capture/enqueueLlmJob.ts","../src/llm/buildSessionDigest.ts","../src/llm/renderCaptureFromJson.ts","../src/llm/chatCompletions.ts","../src/capture/convergence.ts","../src/capture/externalSignals.ts","../src/capture/shouldCapture.ts","../src/capture/formatCapture.ts","../src/capture/writeCapture.ts","../src/hookExit.ts","../src/commands/captureLlm.ts","../src/capture/hookInput.ts","../src/capture/needsLlm.ts","../src/capture/sessionsIndex.ts","../src/consolidate/scheduleConsolidate.ts","../src/inject/constants.ts","../src/consolidate/constants.ts","../src/consolidate/listCaptures.ts","../src/consolidate/parseCapture.ts","../src/consolidate/runConsolidate.ts","../src/feedback/aggregateRefs.ts","../src/markdown/frontmatter.ts","../src/feedback/listRefs.ts","../src/feedback/paths.ts","../src/feedback/skillUsage.ts","../src/feedback/applyFeedback.ts","../src/lifecycle/ignoreMarker.ts","../src/lifecycle/dates.ts","../src/lifecycle/constants.ts","../src/lifecycle/memoryEligibility.ts","../src/lifecycle/archiveCapture.ts","../src/lifecycle/applyLifecycle.ts","../src/consolidate/llmConsolidate.ts","../src/skills/skillIndex.ts","../src/consolidate/buildMemory.ts","../src/consolidate/buildTopics.ts","../src/consolidate/dedupe.ts","../src/consolidate/detectConflict.ts","../src/skills/promoteSkills.ts","../src/skills/parseProcedural.ts","../src/skills/constants.ts","../src/skills/groupProcedural.ts","../src/skills/llmSkill.ts","../src/skills/promoteMarker.ts","../src/skills/repeatCount.ts","../src/skills/renderSkillMd.ts","../src/consolidate/state.ts","../src/consolidate/shouldRunConsolidate.ts","../src/capture/commitCapture.ts","../src/capture/claude-code/resolveSession.ts","../src/capture/claude-code/run.ts","../src/capture/codebuddy/resolveSession.ts","../src/capture/codebuddy/run.ts","../src/capture/cursor/resolveSession.ts","../src/capture/cursor/run.ts","../src/capture/router.ts","../src/capture/runCapture.ts","../src/commands/capture.ts","../src/commands/flush.ts","../src/inject/runInject.ts","../src/commands/inject.ts","../src/init/runInit.ts","../src/init/assistants/claude-code.ts","../src/init/mergeClaudeSettings.ts","../src/init/templateDir.ts","../src/index.ts","../src/init/assistants/codex.ts","../src/init/mergeCodexConfig.ts","../src/init/assistants/codebuddy.ts","../src/init/mergeCodebuddySettings.ts","../src/init/assistants/cursor.ts","../src/init/mergeCursorHooks.ts","../src/init/assistants/registry.ts","../src/init/ensureDirs.ts","../src/init/mergeAssistants.ts","../src/init/mergeGitignore.ts","../src/cli/spinner.ts","../src/coldstart/collectors/existingRules.ts","../src/coldstart/collectors/gitLog.ts","../src/coldstart/collectors/packageJson.ts","../src/coldstart/collectors/repoSignals.ts","../src/coldstart/collectProjectScan.ts","../src/coldstart/constants.ts","../src/coldstart/buildScanCaptures.ts","../src/coldstart/runProjectScan.ts","../src/init/prompts.ts","../src/coldstart/countCaptures.ts","../src/init/writeScaffoldFile.ts","../src/init/mergeConfig.ts","../src/init/mergeAgentsMd.ts","../src/init/mergeLlmConfig.ts","../src/init/scaffoldWrite.ts","../src/commands/init.ts","../src/feedback/writeRef.ts","../src/commands/ref.ts","../src/search/runSearch.ts","../src/commands/search.ts","../src/stats/runStats.ts","../src/commands/stats.ts","../src/promote/runPromote.ts","../src/promote/buildTopicDraft.ts","../src/promote/detectTopicConflict.ts","../src/promote/promoteLlm.ts","../src/promote/suggestTarget.ts","../src/promote/analyzeCandidate.ts","../src/promote/applyDecisions.ts","../src/promote/paths.ts","../src/promote/buildPrBody.ts","../src/promote/listPromoteCandidates.ts","../src/commands/promote.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { runCaptureLlmCommand } from \"./commands/captureLlm.js\";\nimport { runCaptureCommand } from \"./commands/capture.js\";\nimport { runFlushCommandCli } from \"./commands/flush.js\";\nimport { runInjectCommand } from \"./commands/inject.js\";\nimport { runInitCommand } from \"./commands/init.js\";\nimport { runRefCommand } from \"./commands/ref.js\";\nimport { runSearchCommand } from \"./commands/search.js\";\nimport { runStatsCommand } from \"./commands/stats.js\";\nimport { runPromoteCommand } from \"./commands/promote.js\";\nimport { readPkgVersion } from \"./index.js\";\n\nconst MIN_NODE_MAJOR = 20;\n\nfunction assertNodeVersion(): void {\n const major = Number.parseInt(process.versions.node.split(\".\")[0] ?? \"0\", 10);\n if (major < MIN_NODE_MAJOR) {\n console.error(\n `hermes-repo requires Node.js >= ${MIN_NODE_MAJOR}. Current: ${process.versions.node}`,\n );\n process.exit(1);\n }\n}\n\nfunction main(): void {\n assertNodeVersion();\n\n const program = new Command();\n\n program\n .name(\"hermes-repo\")\n .description(\n \"跨编程助手的项目级记忆系统:在 Git 仓库中沉淀约定、踩坑与可复用流程\",\n )\n .version(readPkgVersion(), \"-V, --version\", \"显示版本号\");\n\n program\n .command(\"init\")\n .description(\"在当前 Git 仓库初始化 .memory/ 记忆脚手架\")\n .option(\"-y, --yes\", \"非交互模式,使用默认选项\")\n .option(\"-f, --force\", \"覆盖已存在的脚手架文件(不删除 captures 等内容)\")\n .option(\"-C, --cwd <dir>\", \"目标目录,默认 process.cwd()\")\n .option(\n \"--tools <ids>\",\n \"逗号分隔的助手 id,如 claude-code(须与 -y 合用)\",\n )\n .option(\n \"--scan\",\n \"非交互模式下根据项目扫描生成首批记忆(须与 -y 合用)\",\n )\n .action(\n (options: {\n yes?: boolean;\n force?: boolean;\n cwd?: string;\n tools?: string;\n scan?: boolean;\n }) => {\n void runInitCommand({\n yes: options.yes,\n force: options.force,\n cwd: options.cwd,\n tools: options.tools,\n scan: options.scan,\n });\n },\n );\n\n program\n .command(\"capture\")\n .description(\"Stop hook:捕获当前 Claude Code 会话到 .memory/captures/\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--dry-run\", \"仅预览,不写入文件\")\n .option(\"--strict\", \"失败时 exit 1(hook 默认 exit 0)\")\n .action((options: { cwd?: string; dryRun?: boolean; strict?: boolean }) => {\n runCaptureCommand({\n cwd: options.cwd,\n dryRun: options.dryRun,\n strict: options.strict,\n });\n });\n\n program\n .command(\"capture-llm\")\n .description(\"异步 LLM 升级 capture(由 capture hook 入队,亦可 --flush)\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--job <id>\", \"处理指定 pending job\")\n .option(\"--flush\", \"处理所有 pending job\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action(\n (options: {\n cwd?: string;\n job?: string;\n flush?: boolean;\n strict?: boolean;\n }) => {\n runCaptureLlmCommand({\n cwd: options.cwd,\n job: options.job,\n flush: options.flush,\n strict: options.strict,\n });\n },\n );\n\n program\n .command(\"flush\")\n .description(\n \"手动触发 consolidate:聚合 captures → topics/ + MEMORY.md(与 capture-llm --flush 不同)\",\n )\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--force\", \"重处理全部活跃 capture\")\n .option(\"--dry-run\", \"仅预览,不写入\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action(\n (options: {\n cwd?: string;\n force?: boolean;\n dryRun?: boolean;\n strict?: boolean;\n }) => {\n void runFlushCommandCli({\n cwd: options.cwd,\n force: options.force,\n dryRun: options.dryRun,\n strict: options.strict,\n });\n },\n );\n\n program\n .command(\"inject\")\n .description(\"SessionStart hook:将 MEMORY.md 摘要输出到 stdout\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--strict\", \"失败时 exit 1(hook 默认 exit 0)\")\n .action((options: { cwd?: string; strict?: boolean }) => {\n runInjectCommand({\n cwd: options.cwd,\n strict: options.strict,\n });\n });\n\n program\n .command(\"ref\")\n .description(\"记录对 capture 或 skill 的引用(反馈数据)\")\n .option(\"--capture <path>\", \"capture 相对路径,如 captures/semantic/foo.md\")\n .option(\"--skill <slug>\", \"技能目录名\")\n .requiredOption(\"--reason <text>\", \"引用原因\")\n .option(\"--session <id>\", \"会话 ID\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action(\n (options: {\n capture?: string;\n skill?: string;\n reason?: string;\n session?: string;\n cwd?: string;\n strict?: boolean;\n }) => {\n runRefCommand({\n capture: options.capture,\n skill: options.skill,\n reason: options.reason,\n session: options.session,\n cwd: options.cwd,\n strict: options.strict,\n });\n },\n );\n\n program\n .command(\"search\")\n .description(\"关键词搜索 captures、topics、skills\")\n .argument(\"<keyword>\", \"搜索关键词\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\n \"--type <kind>\",\n \"仅搜索 capture 类型:semantic | episodic | procedural\",\n )\n .option(\"--limit <n>\", \"结果上限\", \"20\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action(\n (\n keyword: string,\n options: {\n cwd?: string;\n type?: string;\n limit?: string;\n strict?: boolean;\n },\n ) => {\n runSearchCommand({\n cwd: options.cwd,\n keyword,\n type: options.type,\n limit: Number.parseInt(options.limit ?? \"20\", 10),\n strict: options.strict,\n });\n },\n );\n\n program\n .command(\"promote\")\n .description(\"团队层记忆晋升:扫描 .promote 侧车,生成 PR 草案或按 manifest 落盘\")\n .option(\"--preview\", \"预览候选与建议,不写盘\")\n .option(\"--pr\", \"生成 PR 正文与 staging 草案(不写正式 topics/)\")\n .option(\"--apply\", \"按 manifest 写入 topics/ 并处理侧车\")\n .option(\"--manifest <path>\", \"decisions.json 路径(与 --apply 合用)\")\n .option(\"--out <path>\", \"PR 正文输出路径(默认 .memory/promote/pr-日期.md)\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--dry-run\", \"仅预览 apply 效果,不写盘\")\n .option(\"--strict\", \"失败时 exit 1\")\n .argument(\n \"[captures...]\",\n \"可选:仅处理指定 capture 路径(如 captures/semantic/foo.md)\",\n )\n .action(\n (\n captures: string[],\n options: {\n preview?: boolean;\n pr?: boolean;\n apply?: boolean;\n manifest?: string;\n out?: string;\n cwd?: string;\n dryRun?: boolean;\n strict?: boolean;\n },\n ) => {\n void runPromoteCommand({\n preview: options.preview,\n pr: options.pr,\n apply: options.apply,\n manifest: options.manifest,\n out: options.out,\n cwd: options.cwd,\n dryRun: options.dryRun,\n strict: options.strict,\n captures,\n });\n },\n );\n\n program\n .command(\"stats\")\n .description(\"查看记忆健康度\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--json\", \"JSON 输出\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action((options: { cwd?: string; json?: boolean; strict?: boolean }) => {\n runStatsCommand({\n cwd: options.cwd,\n json: options.json,\n strict: options.strict,\n });\n });\n\n if (process.argv.length <= 2) {\n program.outputHelp();\n process.exit(0);\n }\n\n program.parse(process.argv);\n}\n\nmain();\n","import { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { RepoContext } from \"./types.js\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport const DEBUG_LOG_FILE = \"hermes-debug.log\";\n\nlet logFilePath: string | null = null;\n\nexport function configureDebugLogging(\n repoRoot: string | null,\n enabled: boolean,\n): void {\n if (!enabled || !repoRoot) {\n logFilePath = null;\n return;\n }\n logFilePath = memoryPath(repoRoot, DEBUG_LOG_FILE);\n}\n\nfunction formatLine(phase: string, message: string): string {\n return `${new Date().toISOString()} hermes-repo [${phase}] ${message}`;\n}\n\nfunction writeToLogFile(line: string): void {\n if (!logFilePath) {\n return;\n }\n mkdirSync(dirname(logFilePath), { recursive: true });\n appendFileSync(logFilePath, `${line}\\n`, \"utf8\");\n}\n\nexport function debugLog(\n enabled: boolean,\n phase: string,\n message: string,\n): void {\n if (!enabled) {\n return;\n }\n const line = formatLine(phase, message);\n console.error(line);\n writeToLogFile(line);\n}\n\nexport function debugFromContext(\n ctx: RepoContext | null | undefined,\n phase: string,\n message: string,\n): void {\n debugLog(ctx?.config.debug === true, phase, message);\n}\n","import { join } from \"node:path\";\n\nexport const MEMORY_DIR = \".memory\";\n\nexport const MEMORY_SUBDIRS = [\n \"captures/semantic\",\n \"captures/episodic\",\n \"captures/procedural\",\n \"personal\",\n \"sessions\",\n \"refs\",\n \"topics\",\n \"skills\",\n \"promote\",\n \"promote/staging\",\n \"promote/staging/topics\",\n \"team/decisions\",\n \"team/conflict-resolutions\",\n \"templates\",\n \".archive\",\n] as const;\n\nexport const GITKEEP_DIRS = [\n \"topics\",\n \"skills\",\n \"team/decisions\",\n \"team/conflict-resolutions\",\n] as const;\n\nexport const EXAMPLE_TEMPLATE_FILES = [\n \"llm.json.example\",\n \"capture-semantic.example.md\",\n \"capture-episodic.example.md\",\n \"capture-procedural.example.md\",\n \"PROMOTE_PR.md\",\n] as const;\n\nexport const SCAFFOLD_RELATIVE_PATHS = [\n \".memory/config.json\",\n \".memory/MEMORY.md\",\n \".memory/sessions/index.json\",\n \".memory/team/steward-log.md\",\n \"AGENTS.md\",\n \".claude/settings.local.json\",\n] as const;\n\nexport function memoryPath(root: string, ...segments: string[]): string {\n return join(root, MEMORY_DIR, ...segments);\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\nimport { findRepoRoot } from \"./findRepoRoot.js\";\nimport type { HermesConfig, RepoContext } from \"./types.js\";\n\nfunction isAssistantId(value: unknown): value is AssistantId {\n return typeof value === \"string\";\n}\n\nexport function readConfigAtRepo(repoRoot: string): HermesConfig | null {\n const configPath = join(repoRoot, \".memory\", \"config.json\");\n try {\n const raw = JSON.parse(readFileSync(configPath, \"utf8\")) as {\n version?: number;\n storage?: { backend?: string };\n assistants?: unknown;\n debug?: unknown;\n };\n if (raw.version !== 1 || raw.storage?.backend !== \"file\") {\n return null;\n }\n const assistants = Array.isArray(raw.assistants)\n ? raw.assistants.filter(isAssistantId)\n : [];\n return {\n version: 1,\n storage: { backend: \"file\" },\n assistants,\n debug: raw.debug === true,\n };\n } catch {\n return null;\n }\n}\n\nexport function loadRepoContext(cwd?: string): RepoContext | null {\n const repoRoot = findRepoRoot(cwd);\n if (!repoRoot) {\n return null;\n }\n const config = readConfigAtRepo(repoRoot);\n if (!config) {\n return null;\n }\n return { repoRoot, config };\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nconst CONFIG_REL = join(\".memory\", \"config.json\");\n\nexport function findRepoRoot(startDir?: string): string | null {\n let dir = resolve(startDir ?? process.cwd());\n\n while (true) {\n if (existsSync(join(dir, CONFIG_REL))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return null;\n }\n dir = parent;\n }\n}\n","import { existsSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport { parseJsonlFile } from \"./claude-code/parseJsonl.js\";\nimport {\n deleteLlmJob,\n listPendingJobs,\n readLlmJob,\n type LlmJobPayload,\n} from \"./enqueueLlmJob.js\";\nimport { llmFormat } from \"./formatCapture.js\";\nimport { renderCaptureMarkdown } from \"./writeCapture.js\";\n\nfunction captureAlreadyUpgraded(repoRoot: string, captureFile: string): boolean {\n const path = join(repoRoot, captureFile);\n if (!existsSync(path)) {\n return false;\n }\n const text = readFileSync(path, \"utf8\");\n return /llmUpgradedAt:/.test(text);\n}\n\nexport async function runLlmJob(\n repoRoot: string,\n job: LlmJobPayload,\n debug?: boolean,\n): Promise<{ ok: boolean; reason?: string }> {\n if (captureAlreadyUpgraded(repoRoot, job.captureFile)) {\n deleteLlmJob(repoRoot, job.jobId);\n return { ok: true, reason: \"already-upgraded\" };\n }\n\n const llm = readLlmConfigAtRepo(repoRoot);\n if (!isLlmAvailable(llm)) {\n return { ok: false, reason: \"llm not available\" };\n }\n\n if (!existsSync(job.jsonlPath)) {\n return { ok: false, reason: \"jsonl missing\" };\n }\n\n const session = parseJsonlFile(job.jsonlPath);\n const upgraded = await llmFormat(session, job.assistant, llm!);\n if (!upgraded) {\n debugLog(debug === true, \"capture-llm\", `llm job failed: ${job.jobId}`);\n return { ok: false, reason: \"llm format failed\" };\n }\n\n const target = join(repoRoot, job.captureFile);\n const temp = `${target}.hermes-tmp`;\n const date = new Date().toISOString().slice(0, 10);\n writeFileSync(temp, renderCaptureMarkdown(upgraded, date), \"utf8\");\n renameSync(temp, target);\n\n deleteLlmJob(repoRoot, job.jobId);\n debugLog(debug === true, \"capture-llm\", `ok: upgraded ${job.captureFile}`);\n return { ok: true };\n}\n\nexport async function runLlmJobById(\n repoRoot: string,\n jobId: string,\n debug?: boolean,\n): Promise<{ ok: boolean; reason?: string }> {\n const job = readLlmJob(repoRoot, jobId);\n if (!job) {\n return { ok: false, reason: \"job not found\" };\n }\n return runLlmJob(repoRoot, job, debug);\n}\n\nexport async function flushPendingLlmJobs(\n repoRoot: string,\n debug?: boolean,\n): Promise<number> {\n const jobs = listPendingJobs(repoRoot);\n let done = 0;\n for (const job of jobs) {\n const result = await runLlmJob(repoRoot, job, debug);\n if (result.ok) {\n done += 1;\n }\n }\n return done;\n}\n","export type LlmCaptureMode = \"async\" | \"sync\";\n\nexport interface LlmConfig {\n enabled: boolean;\n provider?: string;\n baseUrl: string;\n model: string;\n apiKey: string;\n timeoutMs: number;\n maxInputChars: number;\n mode: LlmCaptureMode;\n}\n\nexport const DEFAULT_LLM_TIMEOUT_MS = 60_000;\nexport const DEFAULT_LLM_MAX_INPUT_CHARS = 24_000;\nexport const DEFAULT_LLM_BASE_URL = \"https://api.deepseek.com\";\nexport const DEFAULT_LLM_MODEL = \"deepseek-v4-flash\";\n\nexport function defaultDisabledLlmConfig(): LlmConfig {\n return {\n enabled: false,\n provider: \"openai\",\n baseUrl: DEFAULT_LLM_BASE_URL,\n model: DEFAULT_LLM_MODEL,\n apiKey: \"\",\n timeoutMs: DEFAULT_LLM_TIMEOUT_MS,\n maxInputChars: DEFAULT_LLM_MAX_INPUT_CHARS,\n mode: \"async\",\n };\n}\n\nexport function isLlmAvailable(cfg: LlmConfig | null): boolean {\n if (!cfg?.enabled) {\n return false;\n }\n return (\n Boolean(cfg.apiKey?.trim()) &&\n Boolean(cfg.baseUrl?.trim()) &&\n Boolean(cfg.model?.trim())\n );\n}\n\n/** Env forces sync for tests; otherwise uses llm.json mode */\nexport function effectiveLlmMode(cfg: LlmConfig): LlmCaptureMode {\n const forceSync = process.env.HERMES_LLM_SYNC;\n if (forceSync === \"1\" || forceSync === \"true\") {\n return \"sync\";\n }\n return cfg.mode === \"sync\" ? \"sync\" : \"async\";\n}\n\nexport function parseLlmConfigRaw(raw: Record<string, unknown>): LlmConfig | null {\n if (raw.enabled !== true && raw.enabled !== false) {\n return null;\n }\n const baseUrl = typeof raw.baseUrl === \"string\" ? raw.baseUrl : \"\";\n const model = typeof raw.model === \"string\" ? raw.model : \"\";\n const apiKey = typeof raw.apiKey === \"string\" ? raw.apiKey : \"\";\n const timeoutMs =\n typeof raw.timeoutMs === \"number\" && raw.timeoutMs > 0\n ? raw.timeoutMs\n : DEFAULT_LLM_TIMEOUT_MS;\n const maxInputChars =\n typeof raw.maxInputChars === \"number\" && raw.maxInputChars > 0\n ? raw.maxInputChars\n : DEFAULT_LLM_MAX_INPUT_CHARS;\n const mode = raw.mode === \"sync\" ? \"sync\" : \"async\";\n const provider =\n typeof raw.provider === \"string\" ? raw.provider : \"openai\";\n\n return {\n enabled: raw.enabled,\n provider,\n baseUrl,\n model,\n apiKey,\n timeoutMs,\n maxInputChars,\n mode,\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { memoryPath } from \"../init/paths.js\";\nimport {\n defaultDisabledLlmConfig,\n parseLlmConfigRaw,\n type LlmConfig,\n} from \"./llmConfig.js\";\n\nexport function readLlmConfigAtRepo(repoRoot: string): LlmConfig | null {\n const llmPath = memoryPath(repoRoot, \"llm.json\");\n if (!existsSync(llmPath)) {\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(llmPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n return parseLlmConfigRaw(raw);\n } catch {\n return null;\n }\n}\n\n/** Missing file → disabled-shaped config for init defaults */\nexport function readLlmConfigOrDefault(repoRoot: string): LlmConfig {\n return readLlmConfigAtRepo(repoRoot) ?? defaultDisabledLlmConfig();\n}\n\nexport function serializeLlmConfig(cfg: LlmConfig): string {\n return `${JSON.stringify(cfg, null, 2)}\\n`;\n}\n","import { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport type { ParsedSession, SessionMessage } from \"../types.js\";\n\nconst FILE_CHANGE_TOOLS =\n /^(Write|Edit|MultiEdit|NotebookEdit|write|edit)$/i;\n\n/** CodeBuddy:跳过元数据行,避免干扰统计 */\nconst SKIP_LINE_TYPES = new Set([\n \"file-history-snapshot\",\n \"summary\",\n \"function_call_result\",\n]);\n\nfunction textFromContentParts(content: unknown): string {\n if (!Array.isArray(content)) {\n return \"\";\n }\n return content\n .map((part) => {\n if (!part || typeof part !== \"object\") {\n return \"\";\n }\n const p = part as Record<string, unknown>;\n if (typeof p.text === \"string\") {\n return p.text;\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction extractText(record: Record<string, unknown>): string {\n if (typeof record.content === \"string\") {\n return record.content;\n }\n if (Array.isArray(record.content)) {\n const top = textFromContentParts(record.content);\n if (top) {\n return top;\n }\n }\n const message = record.message;\n if (message && typeof message === \"object\") {\n const msg = message as Record<string, unknown>;\n if (typeof msg.content === \"string\") {\n return msg.content;\n }\n if (Array.isArray(msg.content)) {\n return textFromContentParts(msg.content);\n }\n }\n return \"\";\n}\n\nfunction inferRole(record: Record<string, unknown>): string {\n if (typeof record.role === \"string\") {\n return record.role;\n }\n if (typeof record.type === \"string\") {\n const t = record.type.toLowerCase();\n if (t === \"user\" || t === \"human\") return \"user\";\n if (t === \"assistant\") return \"assistant\";\n }\n return \"unknown\";\n}\n\nfunction isSkippedLine(record: Record<string, unknown>): boolean {\n const t = String(record.type ?? \"\").toLowerCase();\n return SKIP_LINE_TYPES.has(t);\n}\n\nfunction isToolUse(record: Record<string, unknown>): boolean {\n const t = String(record.type ?? \"\").toLowerCase();\n return t === \"tool_use\" || t === \"tool\" || t === \"function_call\";\n}\n\nfunction toolName(record: Record<string, unknown>): string {\n if (typeof record.name === \"string\") return record.name;\n const tool = record.tool;\n if (tool && typeof tool === \"object\" && \"name\" in tool) {\n return String((tool as { name: string }).name);\n }\n return \"\";\n}\n\n/** Cursor 等助手:tool_use 嵌在 message.content 数组内 */\nfunction countNestedTools(record: Record<string, unknown>): {\n toolCalls: number;\n fileChanges: number;\n} {\n let toolCalls = 0;\n let fileChanges = 0;\n const message = record.message;\n if (!message || typeof message !== \"object\") {\n return { toolCalls, fileChanges };\n }\n const content = (message as Record<string, unknown>).content;\n if (!Array.isArray(content)) {\n return { toolCalls, fileChanges };\n }\n for (const part of content) {\n if (!part || typeof part !== \"object\") {\n continue;\n }\n const p = part as Record<string, unknown>;\n const t = String(p.type ?? \"\").toLowerCase();\n if (t !== \"tool_use\" && t !== \"tool\") {\n continue;\n }\n toolCalls += 1;\n const name = typeof p.name === \"string\" ? p.name : \"\";\n if (FILE_CHANGE_TOOLS.test(name)) {\n fileChanges += 1;\n }\n }\n return { toolCalls, fileChanges };\n}\n\nexport function parseJsonlFile(jsonlPath: string): ParsedSession {\n const sessionId = basename(jsonlPath, \".jsonl\");\n const raw = readFileSync(jsonlPath, \"utf8\");\n const messages: SessionMessage[] = [];\n let fileChanges = 0;\n let toolCalls = 0;\n\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const record = JSON.parse(trimmed) as Record<string, unknown>;\n if (isSkippedLine(record)) {\n continue;\n }\n if (isToolUse(record)) {\n toolCalls += 1;\n const name = toolName(record);\n if (FILE_CHANGE_TOOLS.test(name)) {\n fileChanges += 1;\n }\n continue;\n }\n const nested = countNestedTools(record);\n toolCalls += nested.toolCalls;\n fileChanges += nested.fileChanges;\n const role = inferRole(record);\n const text = extractText(record);\n if (text) {\n messages.push({ role, text });\n }\n } catch {\n // skip malformed lines\n }\n }\n\n const text = messages.map((m) => m.text).join(\"\\n\");\n\n return {\n sessionId,\n messages,\n text,\n fileChanges,\n toolCalls,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\n\nexport interface LlmJobPayload {\n jobId: string;\n sessionId: string;\n jsonlPath: string;\n captureFile: string;\n assistant: AssistantId;\n enqueuedAt: string;\n}\n\nfunction pendingDir(repoRoot: string): string {\n return memoryPath(repoRoot, \"captures\", \"pending\");\n}\n\nfunction cliPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"..\", \"cli.js\");\n}\n\nfunction makeJobId(sessionId: string): string {\n const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, \"\").slice(0, 32);\n return `${Date.now()}-${safe || \"session\"}`;\n}\n\nfunction removeStaleJobsForSession(\n repoRoot: string,\n sessionId: string,\n): void {\n const dir = pendingDir(repoRoot);\n if (!existsSync(dir)) {\n return;\n }\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".json\")) {\n continue;\n }\n try {\n const raw = JSON.parse(\n readFileSync(join(dir, name), \"utf8\"),\n ) as LlmJobPayload;\n if (raw.sessionId === sessionId) {\n rmSync(join(dir, name), { force: true });\n }\n } catch {\n // skip\n }\n }\n}\n\nexport function enqueueLlmJob(opts: {\n repoRoot: string;\n sessionId: string;\n jsonlPath: string;\n captureFile: string;\n assistant: AssistantId;\n debug?: boolean;\n}): boolean {\n const { repoRoot, sessionId, jsonlPath, captureFile, assistant, debug } =\n opts;\n const dir = pendingDir(repoRoot);\n mkdirSync(dir, { recursive: true });\n removeStaleJobsForSession(repoRoot, sessionId);\n\n const jobId = makeJobId(sessionId);\n const payload: LlmJobPayload = {\n jobId,\n sessionId,\n jsonlPath,\n captureFile,\n assistant,\n enqueuedAt: new Date().toISOString(),\n };\n writeFileSync(\n join(dir, `${jobId}.json`),\n `${JSON.stringify(payload, null, 2)}\\n`,\n \"utf8\",\n );\n\n const child = spawn(\n process.execPath,\n [cliPath(), \"capture-llm\", \"--job\", jobId, \"-C\", repoRoot],\n {\n detached: true,\n stdio: \"ignore\",\n cwd: repoRoot,\n },\n );\n child.unref();\n\n debugLog(debug === true, \"capture\", `llm job enqueued: ${jobId}`);\n return true;\n}\n\nexport function readLlmJob(\n repoRoot: string,\n jobId: string,\n): LlmJobPayload | null {\n const path = join(pendingDir(repoRoot), `${jobId}.json`);\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as LlmJobPayload;\n } catch {\n return null;\n }\n}\n\nexport function deleteLlmJob(repoRoot: string, jobId: string): void {\n const path = join(pendingDir(repoRoot), `${jobId}.json`);\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nexport function listPendingJobs(repoRoot: string): LlmJobPayload[] {\n const dir = pendingDir(repoRoot);\n if (!existsSync(dir)) {\n return [];\n }\n const jobs: LlmJobPayload[] = [];\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".json\")) {\n continue;\n }\n try {\n jobs.push(\n JSON.parse(readFileSync(join(dir, name), \"utf8\")) as LlmJobPayload,\n );\n } catch {\n // skip\n }\n }\n return jobs;\n}\n","import type { ParsedSession } from \"../capture/types.js\";\n\nexport function buildSessionDigest(\n session: ParsedSession,\n maxChars: number,\n): string {\n const parts: string[] = [\n `sessionId: ${session.sessionId}`,\n `messages: ${session.messages.length}`,\n `toolCalls: ${session.toolCalls}`,\n `fileChanges: ${session.fileChanges}`,\n \"\",\n \"--- transcript (truncated) ---\",\n ];\n\n let used = parts.join(\"\\n\").length;\n const userFirst = [...session.messages].sort((a, b) => {\n if (a.role === \"user\" && b.role !== \"user\") return -1;\n if (b.role === \"user\" && a.role !== \"user\") return 1;\n return 0;\n });\n\n for (const m of userFirst) {\n const block = `[${m.role}]\\n${m.text.slice(0, 2000)}\\n`;\n if (used + block.length > maxChars) {\n parts.push(\"[... truncated ...]\");\n break;\n }\n parts.push(block);\n used += block.length;\n }\n\n return parts.join(\"\\n\");\n}\n","import type { CaptureMemoryType } from \"../capture/types.js\";\n\nexport interface LlmExtractResult {\n type: CaptureMemoryType;\n tags: string[];\n scope: string;\n title?: string;\n context: string;\n findings?: string;\n impact?: string;\n goal?: string;\n steps?: string[];\n cautions?: string[];\n verification?: string[];\n}\n\nconst VALID_TYPES = new Set<CaptureMemoryType>([\n \"semantic\",\n \"episodic\",\n \"procedural\",\n]);\n\nexport function parseLlmExtractJson(raw: unknown): LlmExtractResult | null {\n if (!raw || typeof raw !== \"object\") {\n return null;\n }\n const o = raw as Record<string, unknown>;\n const type = o.type;\n if (typeof type !== \"string\" || !VALID_TYPES.has(type as CaptureMemoryType)) {\n return null;\n }\n const context = typeof o.context === \"string\" ? o.context.trim() : \"\";\n if (!context) {\n return null;\n }\n const tags = Array.isArray(o.tags)\n ? o.tags.filter((t): t is string => typeof t === \"string\")\n : [];\n const scope =\n typeof o.scope === \"string\" && o.scope.trim()\n ? o.scope.trim()\n : \"all\";\n\n return {\n type: type as CaptureMemoryType,\n tags,\n scope,\n title: typeof o.title === \"string\" ? o.title : undefined,\n context,\n findings: typeof o.findings === \"string\" ? o.findings : undefined,\n impact: typeof o.impact === \"string\" ? o.impact : undefined,\n goal: typeof o.goal === \"string\" ? o.goal : undefined,\n steps: Array.isArray(o.steps)\n ? o.steps.filter((s): s is string => typeof s === \"string\")\n : undefined,\n cautions: Array.isArray(o.cautions)\n ? o.cautions.filter((s): s is string => typeof s === \"string\")\n : undefined,\n verification: Array.isArray(o.verification)\n ? o.verification.filter((s): s is string => typeof s === \"string\")\n : undefined,\n };\n}\n\nfunction listSection(title: string, items: string[] | undefined): string {\n if (!items?.length) {\n return \"\";\n }\n return `\\n\\n## ${title}\\n\\n${items.map((s, i) => `${i + 1}. ${s}`).join(\"\\n\")}`;\n}\n\nexport function renderBodyFromExtract(extract: LlmExtractResult): string {\n if (extract.type === \"procedural\") {\n const steps =\n extract.steps?.map((s, i) => `${i + 1}. ${s}`).join(\"\\n\") ??\n extract.findings ??\n \"(无步骤)\";\n const cautions =\n extract.cautions?.map((s) => `- ${s}`).join(\"\\n\") ?? \"(无)\";\n const verification =\n extract.verification?.map((s) => `- ${s}`).join(\"\\n\") ?? \"(无)\";\n return `## 目标\n\n${extract.goal ?? extract.context}\n\n## 步骤\n\n${steps}\n${extract.cautions?.length ? `\\n\\n## 注意\\n\\n${cautions}` : \"\"}\n${extract.verification?.length ? `\\n\\n## 验证\\n\\n${verification}` : \"\"}`;\n }\n\n return `## 上下文\n\n${extract.context}\n\n## 发现\n\n${extract.findings ?? extract.title ?? \"(见上下文)\"}\n\n## 影响\n\n${extract.impact ?? \"(待 consolidate 或人工补充)\"}`;\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport { buildSessionDigest } from \"./buildSessionDigest.js\";\nimport {\n parseLlmExtractJson,\n type LlmExtractResult,\n} from \"./renderCaptureFromJson.js\";\nimport type { ParsedSession } from \"../capture/types.js\";\n\nconst SYSTEM_PROMPT = `You extract project memory from an AI coding session transcript.\nRespond with a single JSON object only (no markdown fence), matching this shape:\n{\n \"type\": \"semantic\" | \"episodic\" | \"procedural\",\n \"tags\": [\"tag1\"],\n \"scope\": \"all\" | \"frontend\" | \"backend\",\n \"title\": \"short summary\",\n \"context\": \"what was being done\",\n \"findings\": \"facts/decisions/root cause (semantic/episodic)\",\n \"impact\": \"effect on future work\",\n \"goal\": \"for procedural only\",\n \"steps\": [\"step 1\"],\n \"cautions\": [\"pitfall\"],\n \"verification\": [\"how to verify\"]\n}\nUse procedural only for repeatable multi-step workflows. Use Chinese for content when the session is mainly Chinese.`;\n\nexport async function extractCaptureViaLlm(\n session: ParsedSession,\n llm: LlmConfig,\n): Promise<LlmExtractResult | null> {\n const digest = buildSessionDigest(session, llm.maxInputChars);\n const url = `${llm.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), llm.timeoutMs);\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${llm.apiKey}`,\n },\n body: JSON.stringify({\n model: llm.model,\n response_format: { type: \"json_object\" },\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n {\n role: \"user\",\n content: `Extract memory from this session:\\n\\n${digest}`,\n },\n ],\n temperature: 0.2,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n return parseLlmExtractJson(parsed);\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import type { ParsedSession } from \"./types.js\";\n\nexport interface MessagePattern {\n userCorrections: number;\n lastUserMessage: string;\n hasFinalApproval: boolean;\n hasUncertainty: boolean;\n}\n\n/**\n * 分析对话的收敛性:是否最后有明确的结论/批准?\n * 用于判断\"改来改去但没结束\"这类低价值对话\n */\nexport function analyzeMessagePattern(session: ParsedSession): MessagePattern {\n let userCorrections = 0;\n let lastUserMessage = \"\";\n\n // 后向扫描:从最后开始找用户的最后一条消息\n for (let i = session.messages.length - 1; i >= 0; i--) {\n const msg = session.messages[i];\n\n if (msg.role === \"user\") {\n lastUserMessage = msg.text;\n\n // 统计所有的纠正信号\n for (const userMsg of session.messages) {\n if (\n userMsg.role === \"user\" &&\n /不对|错了|改|改成|改为|应该是|应该用/i.test(userMsg.text)\n ) {\n userCorrections++;\n }\n }\n\n break; // 只关心最后一条用户消息\n }\n }\n\n // 检查最后的态度\n const hasFinalApproval =\n /好的|可以|就这样|同意|对|yes|ok|looks good|perfect|确认|同意/i.test(\n lastUserMessage\n );\n\n // 检查是否表示不确定/未解决\n const hasUncertainty =\n /不明白|还是|有问题|不太对|感觉|好像|可能|应该|不是很|似乎/i.test(\n lastUserMessage\n );\n\n return {\n userCorrections,\n lastUserMessage,\n hasFinalApproval,\n hasUncertainty,\n };\n}\n\n/**\n * 判断对话是否收敛(最后有明确结论)\n * 返回 true = 有价值(收敛或无纠正)\n * 返回 false = 低价值(多次纠正但无结论)\n */\nexport function isConvergent(session: ParsedSession): boolean {\n const pattern = analyzeMessagePattern(session);\n\n // 情况 1:有明确批准 = 收敛(高价值)\n if (pattern.hasFinalApproval) {\n return true;\n }\n\n // 情况 2:多次纠正但无明确结论 = 未收敛(低价值)\n if (pattern.userCorrections > 1 && !pattern.hasFinalApproval) {\n // 还额外检查是否表示不确定\n if (pattern.hasUncertainty) {\n return false; // 明确丢弃:改来改去 + 仍不确定\n }\n // 如果只是\"改来改去\"但最后默认接受,还是算收敛\n return true;\n }\n\n // 情况 3:无纠正或单次纠正 = 默认收敛\n return true;\n}\n","import type { ParsedSession } from \"./types.js\";\n\n/**\n * 修复 2:CI/外部反馈信号集成\n * 根据 CI 结果和用户反应加权调整捕获决策\n */\n\nexport interface ExternalSignals {\n hasCIFailed: boolean; // AI 修改导致 CI 失败\n hasCIPassed: boolean; // AI 修改导致 CI 通过\n hasUserDislike: boolean; // 用户明确表示不满意\n hasUserLike: boolean; // 用户明确表示满意\n}\n\nexport function analyzeExternalSignals(session: ParsedSession): ExternalSignals {\n return {\n hasCIFailed: session.ciStatus === \"failed\",\n hasCIPassed: session.ciStatus === \"passed\",\n hasUserDislike: session.userEmoji === \"👎\",\n hasUserLike: session.userEmoji === \"👍\",\n };\n}\n\n/**\n * 评估外部信号对捕获决策的影响\n * 返回值:\n * > 0 = 增加保留倾向\n * = 0 = 不影响\n * < 0 = 增加丢弃倾向\n */\nexport function scoreExternalSignals(session: ParsedSession): number {\n const signals = analyzeExternalSignals(session);\n let score = 0;\n\n // 用户明确反馈最重要\n if (signals.hasUserLike) {\n score += 2; // 用户喜欢,高价值\n }\n if (signals.hasUserDislike) {\n score -= 2; // 用户不满意,低价值\n }\n\n // CI 结果是客观反馈\n if (signals.hasCIPassed && session.fileChanges > 0) {\n score += 1; // AI 修改导致 CI 通过 = 有效\n }\n if (signals.hasCIFailed && session.fileChanges > 0) {\n score -= 1.5; // AI 修改导致 CI 失败 = 无效(权重更大)\n }\n\n return score;\n}\n\n/**\n * 判断外部信号是否应该拒绝捕获\n * 返回 true = 应该拒绝(低价值)\n * 返回 false = 可以保留\n */\nexport function shouldRejectByExternalSignals(session: ParsedSession): boolean {\n // 如果没有外部信号,不做决定\n if (\n !session.ciStatus &&\n !session.userEmoji\n ) {\n return false;\n }\n\n const signals = analyzeExternalSignals(session);\n const score = scoreExternalSignals(session);\n\n // 有文件修改但 CI 失败 + 有纠正 = 低价值(应拒绝)\n if (\n signals.hasCIFailed &&\n session.fileChanges > 0 &&\n score < -0.5\n ) {\n return true;\n }\n\n // 用户明确表示不满意 = 拒绝\n if (signals.hasUserDislike) {\n return true;\n }\n\n return false;\n}\n","import type { ParsedSession } from \"./types.js\";\nimport { isConvergent } from \"./convergence.js\";\nimport { shouldRejectByExternalSignals } from \"./externalSignals.js\";\n\nconst CHINESE_STRONG_SIGNALS = [\n \"修复\",\n \"因为\",\n \"改成\",\n \"注意\",\n \"约定\",\n \"不要\",\n \"必须\",\n \"最佳实践\",\n \"根因\",\n \"原因\",\n \"架构\",\n \"决策\",\n];\n\n/** 整词匹配,避免 fix/note/pattern 子串误伤 */\nconst ENGLISH_STRONG_SIGNAL_PATTERNS: RegExp[] = [\n /\\bfix\\b/i,\n /\\bbecause\\b/i,\n /\\bchange to\\b/i,\n /\\bnote\\b/i,\n /\\bconvention\\b/i,\n /\\bnever\\b/i,\n /\\balways\\b/i,\n /\\broot cause\\b/i,\n /\\bpattern\\b/i,\n];\n\nconst CORRECTION_RE =\n /不对|错了|不是这样|不应该|别用|stop|wrong|incorrect|改成|修正/i;\n\nconst SEMANTIC_SIGNAL_RE =\n /约定|必须|架构|决策|规范|convention|pattern|always|never/i;\n\nfunction countUserMessages(session: ParsedSession): number {\n return session.messages.filter((m) => m.role === \"user\").length;\n}\n\nfunction hasStrongSignal(text: string): boolean {\n const lower = text.toLowerCase();\n if (CHINESE_STRONG_SIGNALS.some((w) => lower.includes(w.toLowerCase()))) {\n return true;\n }\n return ENGLISH_STRONG_SIGNAL_PATTERNS.some((re) => re.test(text));\n}\n\nexport function hasUserCorrection(session: ParsedSession): boolean {\n return session.messages.some(\n (m) => m.role === \"user\" && CORRECTION_RE.test(m.text),\n );\n}\n\n/** v0.2:不因 fileChanges===0 单独否决(见 phase-2 已确认决策)\n * 优化 v2(修复 1):添加收敛性分析,避免\"改来改去但没结束\"\n * 优化 v3(修复 2):集成 CI/外部反馈信号 */\nexport function shouldCapture(session: ParsedSession): boolean {\n // 修复 2:外部信号否决(最高优先级的否决)\n if (shouldRejectByExternalSignals(session)) {\n return false;\n }\n\n // 有强信号:立即接受(即使短对话),这是最高优先级\n if (hasStrongSignal(session.text) || hasUserCorrection(session)) {\n // 但检查收敛性:多次纠正但没有结束 = 低价值\n if (hasUserCorrection(session) && !isConvergent(session)) {\n return false;\n }\n return true;\n }\n\n // 复杂任务:多工具调用说明有实质工作\n if (session.toolCalls > 5) {\n return true;\n }\n\n // 有文件修改 + 多轮对话:接受\n if (session.fileChanges > 0 && session.messages.length >= 3) {\n return true;\n }\n\n // 无任何实质信号的短对话才拒绝(greeting only)\n const isGreetingOnly = session.messages.length <= 2 && session.toolCalls === 0 && session.fileChanges === 0;\n if (isGreetingOnly) {\n return false;\n }\n\n return false;\n}\n\nexport function inferCaptureType(session: ParsedSession): \"semantic\" | \"episodic\" {\n if (SEMANTIC_SIGNAL_RE.test(session.text)) {\n return \"semantic\";\n }\n return \"episodic\";\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport { extractCaptureViaLlm } from \"../llm/chatCompletions.js\";\nimport {\n renderBodyFromExtract,\n type LlmExtractResult,\n} from \"../llm/renderCaptureFromJson.js\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\nimport { inferCaptureType } from \"./shouldCapture.js\";\nimport type { CaptureMemoryType, ParsedSession } from \"./types.js\";\n\nexport interface FormattedCapture {\n type: CaptureMemoryType;\n sessionId: string;\n tags: string[];\n scope: string;\n bodyMarkdown: string;\n llmUpgradedAt?: string;\n}\n\nfunction assistantLabel(assistant: AssistantId): string {\n return assistant;\n}\n\nexport function simpleFormat(\n session: ParsedSession,\n assistant: AssistantId,\n): FormattedCapture {\n const type = inferCaptureType(session);\n const recent = session.messages.slice(-6);\n const context = recent\n .map((m) => `**${m.role}**: ${m.text.slice(0, 500)}`)\n .join(\"\\n\\n\");\n\n const bodyMarkdown = `## 上下文\n\n自动捕获自 ${assistantLabel(assistant)} 会话 \\`${session.sessionId}\\`。\n\n## 发现\n\n${context || \"(无提取内容)\"}\n\n## 影响\n\n(待 consolidate 或人工补充)`;\n\n return {\n type,\n sessionId: session.sessionId,\n tags: [\"auto-capture\", assistant],\n scope: \"all\",\n bodyMarkdown,\n };\n}\n\nexport function formattedFromLlmExtract(\n session: ParsedSession,\n assistant: AssistantId,\n extract: LlmExtractResult,\n): FormattedCapture {\n const tagSet = new Set([\"auto-capture\", assistant, ...extract.tags]);\n return {\n type: extract.type,\n sessionId: session.sessionId,\n tags: [...tagSet],\n scope: extract.scope,\n bodyMarkdown: renderBodyFromExtract(extract),\n llmUpgradedAt: new Date().toISOString(),\n };\n}\n\nexport async function llmFormat(\n session: ParsedSession,\n assistant: AssistantId,\n llm: LlmConfig,\n): Promise<FormattedCapture | null> {\n const extract = await extractCaptureViaLlm(session, llm);\n if (!extract) {\n return null;\n }\n return formattedFromLlmExtract(session, assistant, extract);\n}\n","import { existsSync, mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { FormattedCapture } from \"./formatCapture.js\";\nimport type { CaptureMemoryType } from \"./types.js\";\n\nfunction todayString(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport function nextCaptureFilename(\n repoRoot: string,\n type: CaptureMemoryType,\n): string {\n const dir = memoryPath(repoRoot, \"captures\", type);\n mkdirSync(dir, { recursive: true });\n const date = todayString();\n const prefix = `capture-${date}-`;\n let max = 0;\n if (existsSync(dir)) {\n for (const name of readdirSync(dir)) {\n if (name.startsWith(prefix) && name.endsWith(\".md\")) {\n const num = Number.parseInt(name.slice(prefix.length, -3), 10);\n if (!Number.isNaN(num) && num > max) {\n max = num;\n }\n }\n }\n }\n const seq = String(max + 1).padStart(3, \"0\");\n return `capture-${date}-${seq}.md`;\n}\n\nfunction formatTags(tags: string[]): string {\n return tags.map((t) => JSON.stringify(t)).join(\", \");\n}\n\nexport function renderCaptureMarkdown(\n formatted: FormattedCapture,\n date: string,\n): string {\n const lines = [\n \"---\",\n `type: ${formatted.type}`,\n `date: ${date}`,\n `session: ${formatted.sessionId}`,\n `tags: [${formatTags(formatted.tags)}]`,\n `scope: ${formatted.scope}`,\n \"confidence: pending\",\n ];\n if (formatted.llmUpgradedAt) {\n lines.push(`llmUpgradedAt: ${formatted.llmUpgradedAt}`);\n }\n if (formatted.type === \"procedural\") {\n const stepCount = (formatted.bodyMarkdown.match(/^## 步骤/m) ? 1 : 0) +\n (formatted.bodyMarkdown.split(\"\\n\").filter((l) => /^\\d+\\./.test(l)).length);\n lines.push(`step_count: ${stepCount || 0}`);\n lines.push(\"repeat_count: 1\");\n }\n lines.push(\"---\", \"\", formatted.bodyMarkdown);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport function writeCaptureFile(\n repoRoot: string,\n formatted: FormattedCapture,\n filename?: string,\n): { absolutePath: string; filename: string; type: CaptureMemoryType } {\n const type = formatted.type;\n const name = filename ?? nextCaptureFilename(repoRoot, type);\n const absolutePath = memoryPath(repoRoot, \"captures\", type, name);\n const date = todayString();\n const content = renderCaptureMarkdown(formatted, date);\n mkdirSync(join(absolutePath, \"..\"), { recursive: true });\n writeFileSync(absolutePath, content, \"utf8\");\n return { absolutePath, filename: name, type };\n}\n\n/** Replace capture file content in place (LLM upgrade) */\nexport function replaceCaptureFile(\n repoRoot: string,\n captureFile: string,\n formatted: FormattedCapture,\n): void {\n const absolutePath = join(repoRoot, captureFile);\n const date = todayString();\n writeFileSync(absolutePath, renderCaptureMarkdown(formatted, date), \"utf8\");\n}\n","import { debugLog } from \"./config/debugLog.js\";\n\n/** Hook 路径下失败仍 exit 0,避免阻塞 Claude Code */\nexport function hookExit(code: number, strict?: boolean): never {\n process.exit(strict ? code : code === 0 ? 0 : 0);\n}\n\nexport function finalizeHookCommand(\n fn: () => void | Promise<void>,\n strict?: boolean,\n debug?: boolean,\n): void {\n void (async () => {\n try {\n await fn();\n process.exit(0);\n } catch (error) {\n debugLog(debug === true, \"hook\", error instanceof Error ? error.message : String(error));\n process.exit(strict ? 1 : 0);\n }\n })();\n}\n","import { configureDebugLogging } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { flushPendingLlmJobs, runLlmJobById } from \"../capture/runLlmJob.js\";\nimport { finalizeHookCommand } from \"../hookExit.js\";\n\nexport interface CaptureLlmCommandOptions {\n cwd?: string;\n job?: string;\n flush?: boolean;\n strict?: boolean;\n}\n\nexport function runCaptureLlmCommand(opts: CaptureLlmCommandOptions): void {\n const ctx = loadRepoContext(opts.cwd);\n const debug = ctx?.config.debug === true;\n configureDebugLogging(ctx?.repoRoot ?? null, debug);\n\n finalizeHookCommand(async () => {\n if (!ctx) {\n console.error(\"hermes-repo: not initialized\");\n return;\n }\n const repoRoot = ctx.repoRoot;\n\n if (opts.flush) {\n const n = await flushPendingLlmJobs(repoRoot, debug);\n if (debug) {\n console.error(`hermes-repo: flushed ${n} llm job(s)`);\n }\n return;\n }\n\n if (!opts.job) {\n console.error(\"hermes-repo capture-llm: require --job <id> or --flush\");\n return;\n }\n\n const result = await runLlmJobById(repoRoot, opts.job, debug);\n if (!result.ok && opts.strict) {\n throw new Error(result.reason ?? \"capture-llm failed\");\n }\n }, opts.strict, debug);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport type HookInput = {\n /** Claude / CodeBuddy Stop hook(文件存在时已 resolve) */\n transcriptPath?: string;\n /** hook stdin 中的 transcript_path 原值(无论文件是否存在) */\n transcriptPathRaw?: string;\n hookEventName?: string;\n sessionId?: string;\n conversationId?: string;\n workspaceRoots?: string[];\n status?: string;\n};\n\nfunction pickString(obj: Record<string, unknown>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const v = obj[key];\n if (typeof v === \"string\" && v.length > 0) {\n return v;\n }\n }\n return undefined;\n}\n\nfunction pickStringArray(\n obj: Record<string, unknown>,\n ...keys: string[]\n): string[] | undefined {\n for (const key of keys) {\n const v = obj[key];\n if (Array.isArray(v)) {\n const roots = v.filter((x): x is string => typeof x === \"string\");\n if (roots.length > 0) {\n return roots;\n }\n }\n }\n return undefined;\n}\n\n/** 路径是否属于某助手 transcript 根目录 */\nexport function isTranscriptUnderAssistant(\n transcriptPath: string | undefined,\n segment: \".codebuddy\" | \".claude\",\n): boolean {\n if (!transcriptPath) {\n return false;\n }\n const normalized = transcriptPath.replace(/\\\\/g, \"/\");\n return normalized.includes(`${segment}/`);\n}\n\nexport function parseHookInputJson(raw: string): HookInput | null {\n const trimmed = raw.trim();\n if (!trimmed) {\n return null;\n }\n try {\n const parsed = JSON.parse(trimmed) as Record<string, unknown>;\n const transcriptRaw = pickString(parsed, \"transcript_path\", \"transcriptPath\");\n const transcriptPath =\n transcriptRaw && existsSync(transcriptRaw) ? resolve(transcriptRaw) : undefined;\n\n return {\n transcriptPath,\n transcriptPathRaw: transcriptRaw,\n hookEventName: pickString(parsed, \"hook_event_name\", \"hookEventName\"),\n sessionId: pickString(parsed, \"session_id\", \"sessionId\"),\n conversationId: pickString(parsed, \"conversation_id\", \"conversationId\"),\n workspaceRoots: pickStringArray(parsed, \"workspace_roots\", \"workspaceRoots\"),\n status: pickString(parsed, \"status\"),\n };\n } catch {\n return null;\n }\n}\n\n/** 从 hook stdin 读取一次(非 TTY 时) */\nexport function readHookInputSync(): HookInput | null {\n if (process.stdin.isTTY) {\n return null;\n }\n try {\n const raw = readFileSync(0, \"utf8\");\n return parseHookInputJson(raw);\n } catch {\n return null;\n }\n}\n\nexport function isCodebuddyCaptureHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n return (\n isTranscriptUnderAssistant(hook.transcriptPath, \".codebuddy\") ||\n isTranscriptUnderAssistant(hook.transcriptPathRaw, \".codebuddy\")\n );\n}\n\nexport function isClaudeCaptureHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n if (isCodebuddyCaptureHook(hook)) {\n return false;\n }\n if (isTranscriptUnderAssistant(hook.transcriptPath, \".claude\")) {\n return true;\n }\n if (hook.transcriptPath) {\n return true;\n }\n const name = hook.hookEventName?.toLowerCase();\n return name === \"stop\" && !hook.sessionId && !hook.conversationId;\n}\n\nexport function isCursorCaptureHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n if (hook.transcriptPath) {\n if (\n isTranscriptUnderAssistant(hook.transcriptPath, \".codebuddy\") ||\n isTranscriptUnderAssistant(hook.transcriptPath, \".claude\")\n ) {\n return false;\n }\n }\n const name = hook.hookEventName?.toLowerCase();\n if (name === \"stop\") {\n return true;\n }\n return Boolean(hook.sessionId || hook.conversationId);\n}\n\nexport function isCursorInjectHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n const name = hook.hookEventName?.toLowerCase();\n return name === \"sessionstart\";\n}\n","import type { ParsedSession } from \"./types.js\";\nimport { hasUserCorrection } from \"./shouldCapture.js\";\n\nconst ARCHITECTURE_SIGNAL_RE =\n /约定|必须|架构|决策|规范|根因|migration|refactor|convention|root cause/i;\n\nexport function hasArchitectureSignal(text: string): boolean {\n return ARCHITECTURE_SIGNAL_RE.test(text);\n}\n\n/** 复杂会话才走 LLM(需 isLlmAvailable 同时为 true) */\nexport function needsLlm(session: ParsedSession): boolean {\n return (\n session.messages.length >= 20 ||\n session.fileChanges >= 3 ||\n hasArchitectureSignal(session.text) ||\n hasUserCorrection(session)\n );\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport interface SessionIndexEntry {\n id: string;\n capturedAt: string;\n captureFile: string;\n assistant: string;\n}\n\ninterface SessionsIndexFile {\n version: number;\n sessions: SessionIndexEntry[];\n}\n\nexport function readSessionsIndex(repoRoot: string): SessionsIndexFile {\n const indexPath = memoryPath(repoRoot, \"sessions\", \"index.json\");\n try {\n const data = JSON.parse(readFileSync(indexPath, \"utf8\")) as SessionsIndexFile;\n if (data.version === 1 && Array.isArray(data.sessions)) {\n return data;\n }\n } catch {\n // fall through\n }\n return { version: 1, sessions: [] };\n}\n\nexport function appendSessionIndex(\n repoRoot: string,\n entry: SessionIndexEntry,\n): void {\n const index = readSessionsIndex(repoRoot);\n index.sessions.push(entry);\n const indexPath = memoryPath(repoRoot, \"sessions\", \"index.json\");\n writeFileSync(indexPath, `${JSON.stringify(index, null, 2)}\\n`, \"utf8\");\n}\n\nexport function relativeCapturePath(\n type: string,\n filename: string,\n): string {\n return join(\".memory\", \"captures\", type, filename).replace(/\\\\/g, \"/\");\n}\n","import { spawn } from \"node:child_process\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { CONSOLIDATE_LOCK_TTL_MS } from \"./constants.js\";\nimport {\n filterActiveCaptures,\n listAllCaptures,\n} from \"./listCaptures.js\";\nimport { runConsolidate, type RunConsolidateResult } from \"./runConsolidate.js\";\nimport { isLockStale, readConsolidateLock } from \"./state.js\";\nimport { shouldRunConsolidate } from \"./shouldRunConsolidate.js\";\n\nfunction cliPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"..\", \"cli.js\");\n}\n\nexport function maybeScheduleConsolidate(opts: {\n repoRoot: string;\n debug?: boolean;\n}): void {\n const { repoRoot, debug } = opts;\n const check = shouldRunConsolidate({ repoRoot });\n if (!check.shouldRun) {\n if (check.deferredPendingLlm) {\n debugLog(\n debug === true,\n \"capture\",\n \"consolidate-deferred: pending llm jobs\",\n );\n }\n return;\n }\n\n const lock = readConsolidateLock(repoRoot);\n if (lock && !isLockStale(lock, CONSOLIDATE_LOCK_TTL_MS)) {\n debugLog(debug === true, \"capture\", \"consolidate-skip: lock held\");\n return;\n }\n\n const child = spawn(\n process.execPath,\n [cliPath(), \"flush\", \"-C\", repoRoot],\n {\n detached: true,\n stdio: \"ignore\",\n cwd: repoRoot,\n },\n );\n child.unref();\n debugLog(\n debug === true,\n \"capture\",\n `consolidate scheduled (${check.reason}, ${check.newCaptureCount} new)`,\n );\n}\n\nexport async function runFlushCommand(opts: {\n cwd?: string;\n force?: boolean;\n dryRun?: boolean;\n debug?: boolean;\n}): Promise<RunConsolidateResult> {\n const ctx = loadRepoContext(opts.cwd);\n if (!ctx) {\n console.error(\n \"hermes-repo flush: not initialized (.memory/config.json missing)\",\n );\n return {\n ran: false,\n reason: \"not-initialized\",\n memoryUpdated: false,\n topicsWritten: 0,\n skillsWritten: 0,\n newProcessed: 0,\n refsAggregated: 0,\n archived: 0,\n demotedFromMemory: 0,\n };\n }\n\n const active = filterActiveCaptures(listAllCaptures(ctx.repoRoot));\n if (active.length === 0) {\n console.error(\"hermes-repo flush: no captures to consolidate\");\n return {\n ran: false,\n reason: \"no-captures\",\n memoryUpdated: false,\n topicsWritten: 0,\n skillsWritten: 0,\n newProcessed: 0,\n refsAggregated: 0,\n archived: 0,\n demotedFromMemory: 0,\n };\n }\n\n return runConsolidate({\n repoRoot: ctx.repoRoot,\n force: opts.force,\n dryRun: opts.dryRun,\n debug: opts.debug ?? ctx.config.debug,\n manual: true,\n });\n}\n","/** Level 0 注入上限(参考设计文档 ~2.2K chars) */\nexport const INJECT_MAX_CHARS = 2200;\n","/** 自上次 consolidate 以来新 capture 数量阈值 */\nexport const CONSOLIDATE_COUNT_THRESHOLD = 10;\n\n/** 时间驱动:小时 */\nexport const CONSOLIDATE_HOURS_THRESHOLD = 24;\n\n/** 运行锁过期(毫秒) */\nexport const CONSOLIDATE_LOCK_TTL_MS = 30 * 60 * 1000;\n\n/** MEMORY 注入上限(与 inject 一致) */\nexport { INJECT_MAX_CHARS } from \"../inject/constants.js\";\n\n/** 最近经验窗口(天) */\nexport const RECENT_EXPERIENCE_DAYS = 7;\n\n/** 规则 MEMORY 最近条目上限 */\nexport const RECENT_EXPERIENCE_MAX = 8;\n\n/** 活跃主题 tag 上限 */\nexport const ACTIVE_TOPIC_MAX = 6;\n","import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { CaptureMemoryType } from \"../capture/types.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { parseCaptureMarkdown, type ParsedCapture } from \"./parseCapture.js\";\n\nconst TYPES: CaptureMemoryType[] = [\"semantic\", \"episodic\", \"procedural\"];\n\nexport function listAllCaptures(repoRoot: string): ParsedCapture[] {\n const results: ParsedCapture[] = [];\n for (const type of TYPES) {\n const dir = memoryPath(repoRoot, \"captures\", type);\n if (!existsSync(dir)) {\n continue;\n }\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".md\")) {\n continue;\n }\n const relativePath = `captures/${type}/${name}`;\n const absolutePath = join(dir, name);\n try {\n const content = readFileSync(absolutePath, \"utf8\");\n const parsed = parseCaptureMarkdown(\n content,\n relativePath,\n absolutePath,\n );\n if (parsed) {\n results.push(parsed);\n }\n } catch {\n // skip unreadable\n }\n }\n }\n return results;\n}\n\nexport function filterActiveCaptures(\n captures: ParsedCapture[],\n): ParsedCapture[] {\n return captures.filter((c) => c.confidence !== \"superseded\");\n}\n\nexport function selectNewCaptures(\n captures: ParsedCapture[],\n processedPaths: string[],\n force: boolean,\n): ParsedCapture[] {\n const active = filterActiveCaptures(captures);\n if (force) {\n return active;\n }\n const processed = new Set(processedPaths);\n return active.filter((c) => !processed.has(c.path));\n}\n\nexport function captureMtimeMs(capture: ParsedCapture): number {\n try {\n const st = statSync(capture.absolutePath);\n return st.mtimeMs;\n } catch {\n return 0;\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { CaptureMemoryType } from \"../capture/types.js\";\n\nexport interface ParsedCapture {\n /** 相对路径,如 captures/semantic/capture-2026-05-20-001.md */\n path: string;\n absolutePath: string;\n type: CaptureMemoryType;\n date: string;\n session: string;\n tags: string[];\n scope: string;\n confidence: string;\n supersededBy?: string;\n llmUpgradedAt?: string;\n stepCount?: number;\n repeatCount?: number;\n useCount?: number;\n lastUsed?: string;\n bodyMarkdown: string;\n findings: string;\n summary: string;\n /** 存在 captures/.../file.md.promote 侧车 */\n hasPromoteMarker?: boolean;\n}\n\nconst CAPTURE_TYPES: CaptureMemoryType[] = [\n \"semantic\",\n \"episodic\",\n \"procedural\",\n];\n\nexport function captureTypeFromPath(\n relativePath: string,\n): CaptureMemoryType | null {\n for (const t of CAPTURE_TYPES) {\n if (relativePath.startsWith(`captures/${t}/`)) {\n return t;\n }\n }\n return null;\n}\n\nfunction parseTagsLine(line: string): string[] {\n const m = line.match(/^tags:\\s*(.+)$/i);\n if (!m) {\n return [];\n }\n const raw = m[1].trim();\n if (raw.startsWith(\"[\")) {\n try {\n const arr = JSON.parse(raw.replace(/'/g, '\"')) as unknown;\n if (Array.isArray(arr)) {\n return arr.filter((x) => typeof x === \"string\") as string[];\n }\n } catch {\n // fall through\n }\n const inner = raw.slice(1, -1);\n return inner\n .split(\",\")\n .map((s) => s.trim().replace(/^[\"']|[\"']$/g, \"\"))\n .filter(Boolean);\n }\n return raw.split(\",\").map((s) => s.trim()).filter(Boolean);\n}\n\nfunction parseScalar(line: string, key: string): string | undefined {\n const re = new RegExp(`^${key}:\\\\s*(.+)$`, \"i\");\n const m = line.match(re);\n return m?.[1]?.trim();\n}\n\nexport function parseCaptureMarkdown(\n content: string,\n relativePath: string,\n absolutePath: string,\n): ParsedCapture | null {\n const type = captureTypeFromPath(relativePath);\n if (!type) {\n return null;\n }\n\n const parts = content.split(/^---\\s*$/m);\n if (parts.length < 3) {\n return null;\n }\n\n const fmLines = parts[1].split(\"\\n\");\n const meta: Record<string, string> = {};\n let tags: string[] = [];\n\n for (const line of fmLines) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n if (/^tags:/i.test(trimmed)) {\n tags = parseTagsLine(trimmed);\n continue;\n }\n const colon = trimmed.indexOf(\":\");\n if (colon > 0) {\n const key = trimmed.slice(0, colon).trim().toLowerCase();\n meta[key] = trimmed.slice(colon + 1).trim();\n }\n }\n\n const bodyMarkdown = parts.slice(2).join(\"---\").trim();\n const findings = extractSection(bodyMarkdown, \"发现\");\n const goal = extractSection(bodyMarkdown, \"目标\");\n const stepsSection = extractSection(bodyMarkdown, \"步骤\");\n let summary =\n findings.split(\"\\n\").find((l) => l.trim() && !l.startsWith(\"#\"))?.trim() ??\n findings.slice(0, 120).trim();\n if (!summary && type === \"procedural\") {\n summary =\n goal ||\n stepsSection\n .split(\"\\n\")\n .find((l) => l.trim() && !l.startsWith(\"#\"))\n ?.trim() ||\n \"(无摘要)\";\n }\n if (!summary) {\n summary = \"(无摘要)\";\n }\n\n const stepCount = parseIntMeta(meta.step_count);\n const repeatCount = parseIntMeta(meta.repeat_count);\n const useCount = parseIntMeta(meta.use_count);\n const lastUsed = meta.last_used;\n\n return {\n path: relativePath,\n absolutePath,\n type: meta.type === type ? type : type,\n date: meta.date ?? \"\",\n session: meta.session ?? \"\",\n tags,\n scope: meta.scope ?? \"all\",\n confidence: meta.confidence ?? \"pending\",\n supersededBy: meta.superseded_by,\n llmUpgradedAt: meta.llmupgradedat ?? meta[\"llm-upgraded-at\"],\n stepCount,\n repeatCount,\n useCount,\n lastUsed,\n bodyMarkdown,\n findings,\n summary,\n };\n}\n\nfunction parseIntMeta(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n const n = Number.parseInt(value, 10);\n return Number.isNaN(n) ? undefined : n;\n}\n\nexport function extractSection(body: string, heading: string): string {\n const re = new RegExp(\n `^##\\\\s*${heading}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=^##\\\\s|$)`,\n \"m\",\n );\n const m = body.match(re);\n return m?.[1]?.trim() ?? \"\";\n}\n\nexport function readCaptureFile(\n repoRoot: string,\n relativePath: string,\n): ParsedCapture | null {\n const absolutePath = join(repoRoot, \".memory\", relativePath);\n try {\n const content = readFileSync(absolutePath, \"utf8\");\n return parseCaptureMarkdown(content, relativePath, absolutePath);\n } catch {\n return null;\n }\n}\n\nexport function primaryTag(capture: ParsedCapture): string {\n const skip = new Set([\"auto-capture\", \"claude-code\", \"cursor\", \"codebuddy\"]);\n const t = capture.tags.find((tag) => !skip.has(tag));\n return t ?? capture.tags[0] ?? \"general\";\n}\n\nexport function tagToSlug(tag: string): string {\n return tag\n .toLowerCase()\n .replace(/[^a-z0-9\\u4e00-\\u9fff]+/gi, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 48) || \"general\";\n}\n","import { appendFileSync, existsSync, writeFileSync } from \"node:fs\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport { applyFeedback } from \"../feedback/applyFeedback.js\";\nimport { readSkillUsage } from \"../feedback/skillUsage.js\";\nimport { applyLifecycle } from \"../lifecycle/applyLifecycle.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { buildMemory } from \"./buildMemory.js\";\nimport { buildTopics } from \"./buildTopics.js\";\nimport { dedupeCaptures } from \"./dedupe.js\";\nimport { detectConflicts } from \"./detectConflict.js\";\nimport {\n filterActiveCaptures,\n listAllCaptures,\n selectNewCaptures,\n} from \"./listCaptures.js\";\nimport { promoteSkills } from \"../skills/promoteSkills.js\";\nimport {\n filterSkillIndexForMemory,\n listSkillIndex,\n} from \"../skills/skillIndex.js\";\nimport {\n readConsolidateState,\n releaseConsolidateLock,\n writeConsolidateLock,\n writeConsolidateState,\n} from \"./state.js\";\n\nexport interface RunConsolidateOptions {\n repoRoot: string;\n force?: boolean;\n dryRun?: boolean;\n debug?: boolean;\n /** 手动 flush:无新 capture 时也重建 MEMORY */\n manual?: boolean;\n}\n\nexport interface RunConsolidateResult {\n ran: boolean;\n reason?: string;\n memoryUpdated: boolean;\n topicsWritten: number;\n skillsWritten: number;\n newProcessed: number;\n refsAggregated: number;\n archived: number;\n demotedFromMemory: number;\n}\n\nexport async function runConsolidate(\n opts: RunConsolidateOptions,\n): Promise<RunConsolidateResult> {\n const { repoRoot, force, dryRun, debug, manual } = opts;\n\n const emptyStats = {\n refsAggregated: 0,\n archived: 0,\n demotedFromMemory: 0,\n };\n\n writeConsolidateLock(repoRoot);\n try {\n const state = readConsolidateState(repoRoot);\n const all = listAllCaptures(repoRoot);\n const allActive = filterActiveCaptures(all);\n let newOnes = selectNewCaptures(\n allActive,\n state.processedCapturePaths,\n force === true,\n );\n\n if (newOnes.length === 0 && !force && !manual) {\n debugLog(debug === true, \"consolidate\", \"skip: no new captures\");\n return {\n ran: false,\n reason: \"no-new-captures\",\n memoryUpdated: false,\n topicsWritten: 0,\n skillsWritten: 0,\n newProcessed: 0,\n ...emptyStats,\n };\n }\n\n const toProcess =\n force === true || manual === true\n ? allActive\n : newOnes.length > 0\n ? newOnes\n : allActive;\n\n const { active: dedupedActive, supersededPaths } = dedupeCaptures(toProcess);\n const conflicts = detectConflicts(allActive);\n const llm = readLlmConfigAtRepo(repoRoot);\n\n if (dryRun) {\n const drySkills = await promoteSkills({\n repoRoot,\n captures: allActive,\n dryRun: true,\n debug,\n llm,\n });\n const feedback = applyFeedback(repoRoot, true);\n const lifecycle = applyLifecycle(repoRoot, allActive, true);\n debugLog(\n debug === true,\n \"consolidate\",\n `[dry-run] ${dedupedActive.length} captures, ${conflicts.length} conflicts, ${feedback.refsAggregated} refs, ${lifecycle.archived} archive`,\n );\n return {\n ran: true,\n reason: \"dry-run\",\n memoryUpdated: false,\n topicsWritten: 0,\n skillsWritten: drySkills.skillIndex.length,\n newProcessed: dedupedActive.length,\n refsAggregated: feedback.refsAggregated,\n archived: lifecycle.archived,\n demotedFromMemory: lifecycle.demotedFromMemory,\n };\n }\n\n const topicFiles = await buildTopics(repoRoot, dedupedActive, llm);\n const { skillsWritten, skillIndex: rawSkillIndex } = await promoteSkills({\n repoRoot,\n captures: allActive,\n dryRun: false,\n debug,\n llm,\n });\n\n const feedback = applyFeedback(repoRoot, false);\n const lifecycle = applyLifecycle(repoRoot, allActive, false);\n\n const allActiveAfter = filterActiveCaptures(listAllCaptures(repoRoot));\n const skillUsage = readSkillUsage(repoRoot);\n const skillIndex = filterSkillIndexForMemory(\n rawSkillIndex.length > 0 ? rawSkillIndex : listSkillIndex(repoRoot),\n skillUsage,\n repoRoot,\n );\n\n const memory = await buildMemory(\n allActiveAfter,\n lifecycle.memoryCaptures,\n dedupedActive,\n conflicts,\n state.lastConsolidatedAt,\n topicFiles,\n llm,\n skillIndex,\n {\n demotedFromMemory: lifecycle.demotedFromMemory,\n archivedCount: lifecycle.archived,\n },\n );\n\n const memoryPathAbs = memoryPath(repoRoot, \"MEMORY.md\");\n writeFileSync(memoryPathAbs, memory, \"utf8\");\n\n const stewardPath = memoryPath(repoRoot, \"team\", \"steward-log.md\");\n if (existsSync(stewardPath)) {\n const line = `- ${new Date().toISOString()} consolidate: ${dedupedActive.length} new, ${supersededPaths.length} superseded, ${topicFiles.length} topics, ${skillsWritten} skills, ${feedback.refsAggregated} refs, ${lifecycle.archived} archived\\n`;\n appendFileSync(stewardPath, line, \"utf8\");\n }\n\n const processed = new Set(state.processedCapturePaths);\n for (const c of newOnes) {\n processed.add(c.path);\n }\n for (const p of supersededPaths) {\n processed.add(p);\n }\n\n writeConsolidateState(repoRoot, {\n version: 1,\n lastConsolidatedAt: new Date().toISOString(),\n processedCapturePaths: [...processed],\n });\n\n debugLog(\n debug === true,\n \"consolidate\",\n `ok: MEMORY.md, ${feedback.refsAggregated} refs, ${lifecycle.archived} archived`,\n );\n\n return {\n ran: true,\n memoryUpdated: true,\n topicsWritten: topicFiles.length,\n skillsWritten,\n newProcessed: dedupedActive.length,\n refsAggregated: feedback.refsAggregated,\n archived: lifecycle.archived,\n demotedFromMemory: lifecycle.demotedFromMemory,\n };\n } finally {\n releaseConsolidateLock(repoRoot);\n }\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { setFrontmatterScalars } from \"../markdown/frontmatter.js\";\nimport { parseCaptureMarkdown } from \"../consolidate/parseCapture.js\";\nimport { listRefFiles, readRefFile, deleteRefFile } from \"./listRefs.js\";\nimport { mergeSkillUsage, readSkillUsage, writeSkillUsage } from \"./skillUsage.js\";\nimport type { RefRecord } from \"./types.js\";\n\nfunction isCaptureTarget(target: string): boolean {\n return target.startsWith(\"captures/\");\n}\n\nfunction isSkillTarget(target: string): boolean {\n return target.startsWith(\"skills/\") && target.endsWith(\"/SKILL.md\");\n}\n\nfunction maxDate(a: string, b: string): string {\n return a > b ? a : b;\n}\n\nexport interface AggregateRefsResult {\n refsAggregated: number;\n capturesUpdated: number;\n skillsUpdated: number;\n}\n\nexport function aggregateRefs(\n repoRoot: string,\n dryRun?: boolean,\n): AggregateRefsResult {\n const grouped = new Map<string, RefRecord[]>();\n\n for (const name of listRefFiles(repoRoot)) {\n const rec = readRefFile(repoRoot, name);\n if (!rec) {\n if (!dryRun) {\n deleteRefFile(repoRoot, name);\n }\n continue;\n }\n const list = grouped.get(rec.target) ?? [];\n list.push(rec);\n grouped.set(rec.target, list);\n }\n\n let capturesUpdated = 0;\n let skillsUpdated = 0;\n let skillUsage = readSkillUsage(repoRoot);\n\n for (const [target, refs] of grouped) {\n const addCount = refs.length;\n const lastUsed = refs.reduce(\n (max, r) => maxDate(max, r.date),\n refs[0]?.date ?? \"\",\n );\n\n if (isCaptureTarget(target)) {\n const abs = join(repoRoot, \".memory\", target);\n try {\n const raw = readFileSync(abs, \"utf8\");\n const parsed = parseCaptureMarkdown(raw, target, abs);\n const prevCount = parsed?.useCount ?? 0;\n const prevUsed = parsed?.lastUsed ?? \"\";\n const nextCount = prevCount + addCount;\n const nextUsed = maxDate(prevUsed, lastUsed);\n\n if (!dryRun) {\n const updated = setFrontmatterScalars(raw, {\n use_count: nextCount,\n last_used: nextUsed,\n });\n writeFileSync(abs, updated, \"utf8\");\n }\n capturesUpdated++;\n } catch {\n // skip invalid capture\n }\n } else if (isSkillTarget(target)) {\n skillUsage = mergeSkillUsage(skillUsage, target, addCount, lastUsed);\n skillsUpdated++;\n }\n }\n\n if (!dryRun) {\n if (skillsUpdated > 0) {\n writeSkillUsage(repoRoot, skillUsage);\n }\n for (const name of listRefFiles(repoRoot)) {\n deleteRefFile(repoRoot, name);\n }\n }\n\n const refsAggregated = [...grouped.values()].reduce((n, arr) => n + arr.length, 0);\n return { refsAggregated, capturesUpdated, skillsUpdated };\n}\n","/** Split markdown into [before, frontmatter, body] or null if invalid */\nexport function splitFrontmatter(content: string): {\n frontmatter: string;\n body: string;\n} | null {\n const parts = content.split(/^---\\s*$/m);\n if (parts.length < 3) {\n return null;\n }\n return {\n frontmatter: parts[1],\n body: parts.slice(2).join(\"---\"),\n };\n}\n\nexport function joinFrontmatter(frontmatter: string, body: string): string {\n const fm = frontmatter.trimEnd();\n const b = body.startsWith(\"\\n\") ? body : `\\n${body}`;\n return `---\\n${fm}\\n---${b}`;\n}\n\n/** Set or replace a scalar frontmatter key (snake_case as written) */\nexport function setFrontmatterScalar(\n content: string,\n key: string,\n value: string | number,\n): string {\n const split = splitFrontmatter(content);\n if (!split) {\n return content;\n }\n const line = `${key}: ${value}`;\n let fm = split.frontmatter;\n const re = new RegExp(`^${key}:\\\\s*.+$`, \"im\");\n if (re.test(fm)) {\n fm = fm.replace(re, line);\n } else {\n fm = `${fm.trimEnd()}\\n${line}\\n`;\n }\n return joinFrontmatter(fm, split.body);\n}\n\nexport function setFrontmatterScalars(\n content: string,\n fields: Record<string, string | number>,\n): string {\n let out = content;\n for (const [key, value] of Object.entries(fields)) {\n out = setFrontmatterScalar(out, key, value);\n }\n return out;\n}\n","import { existsSync, readdirSync, readFileSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { RefRecord } from \"./types.js\";\nimport { refsDir } from \"./paths.js\";\n\nexport function listRefFiles(repoRoot: string): string[] {\n const dir = refsDir(repoRoot);\n if (!existsSync(dir)) {\n return [];\n }\n return readdirSync(dir).filter((n) => n.endsWith(\".json\"));\n}\n\nexport function readRefFile(repoRoot: string, fileName: string): RefRecord | null {\n try {\n const raw = readFileSync(join(refsDir(repoRoot), fileName), \"utf8\");\n const parsed = JSON.parse(raw) as RefRecord;\n if (\n typeof parsed.target !== \"string\" ||\n typeof parsed.reason !== \"string\" ||\n typeof parsed.date !== \"string\"\n ) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport function listAllRefs(repoRoot: string): RefRecord[] {\n const out: RefRecord[] = [];\n for (const name of listRefFiles(repoRoot)) {\n const rec = readRefFile(repoRoot, name);\n if (rec) {\n out.push(rec);\n }\n }\n return out;\n}\n\nexport function deleteRefFile(repoRoot: string, fileName: string): void {\n try {\n unlinkSync(join(refsDir(repoRoot), fileName));\n } catch {\n // best effort\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport function refsDir(repoRoot: string): string {\n return memoryPath(repoRoot, \"refs\");\n}\n\nexport function skillUsagePath(repoRoot: string): string {\n return memoryPath(repoRoot, \"skill-usage.json\");\n}\n\nexport function refFileName(target: string, date: string): string {\n const hash = createHash(\"sha256\").update(target).digest(\"hex\").slice(0, 8);\n return `${date}-${hash}.json`;\n}\n\nexport function refFilePath(repoRoot: string, target: string, date: string): string {\n return join(refsDir(repoRoot), refFileName(target, date));\n}\n\nexport function normalizeCaptureTarget(input: string): string {\n let p = input.replace(/\\\\/g, \"/\").trim();\n if (p.startsWith(\".memory/\")) {\n p = p.slice(\".memory/\".length);\n }\n if (!p.startsWith(\"captures/\")) {\n throw new Error(`capture path must start with captures/: ${input}`);\n }\n return p;\n}\n\nexport function normalizeSkillTarget(slug: string): string {\n const s = slug.replace(/\\\\/g, \"/\").trim().replace(/^\\/+|\\/+$/g, \"\");\n return `skills/${s}/SKILL.md`;\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport type { SkillUsageMap } from \"./types.js\";\nimport { skillUsagePath } from \"./paths.js\";\n\nexport function readSkillUsage(repoRoot: string): SkillUsageMap {\n const path = skillUsagePath(repoRoot);\n if (!existsSync(path)) {\n return {};\n }\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as SkillUsageMap;\n return parsed && typeof parsed === \"object\" ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport function writeSkillUsage(repoRoot: string, map: SkillUsageMap): void {\n writeFileSync(\n skillUsagePath(repoRoot),\n `${JSON.stringify(map, null, 2)}\\n`,\n \"utf8\",\n );\n}\n\nexport function mergeSkillUsage(\n existing: SkillUsageMap,\n target: string,\n addCount: number,\n lastUsed: string,\n): SkillUsageMap {\n const prev = existing[target];\n const prevCount = prev?.use_count ?? 0;\n const prevDate = prev?.last_used ?? \"\";\n return {\n ...existing,\n [target]: {\n use_count: prevCount + addCount,\n last_used: lastUsed > prevDate ? lastUsed : prevDate || lastUsed,\n },\n };\n}\n","import { aggregateRefs, type AggregateRefsResult } from \"./aggregateRefs.js\";\n\nexport function applyFeedback(\n repoRoot: string,\n dryRun?: boolean,\n): AggregateRefsResult {\n return aggregateRefs(repoRoot, dryRun);\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport function ignoreMarkerPath(repoRoot: string, capturePath: string): string {\n return join(repoRoot, \".memory\", `${capturePath}.ignore`);\n}\n\nexport function hasIgnoreMarker(repoRoot: string, capturePath: string): boolean {\n return existsSync(ignoreMarkerPath(repoRoot, capturePath));\n}\n","const MS_PER_DAY = 24 * 60 * 60 * 1000;\n\nexport function utcToday(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport function parseDateMs(dateStr: string): number | null {\n if (!dateStr || !/^\\d{4}-\\d{2}-\\d{2}/.test(dateStr)) {\n return null;\n }\n const ms = Date.parse(`${dateStr.slice(0, 10)}T00:00:00.000Z`);\n return Number.isNaN(ms) ? null : ms;\n}\n\nexport function daysSince(dateStr: string, nowMs: number = Date.now()): number {\n const ms = parseDateMs(dateStr);\n if (ms === null) {\n return Number.POSITIVE_INFINITY;\n }\n return Math.floor((nowMs - ms) / MS_PER_DAY);\n}\n\nexport function isWithinDays(dateStr: string, days: number, nowMs?: number): boolean {\n return daysSince(dateStr, nowMs) <= days;\n}\n","/** 可进入 MEMORY 活跃区的天数 */\nexport const LIFECYCLE_ACTIVE_DAYS = 30;\n\n/** 移入 .archive 的天数 */\nexport const LIFECYCLE_ARCHIVE_DAYS = 90;\n\n/** Skill 从 MEMORY 索引移除的天数 */\nexport const SKILL_MEMORY_ACTIVE_DAYS = 30;\n\nexport const SKILL_MEMORY_ARCHIVE_DAYS = 90;\n","import type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport { hasIgnoreMarker } from \"./ignoreMarker.js\";\nimport { daysSince, isWithinDays } from \"./dates.js\";\nimport {\n LIFECYCLE_ACTIVE_DAYS,\n LIFECYCLE_ARCHIVE_DAYS,\n} from \"./constants.js\";\n\nexport function shouldArchiveCapture(\n capture: ParsedCapture,\n repoRoot: string,\n nowMs: number = Date.now(),\n): boolean {\n if (hasIgnoreMarker(repoRoot, capture.path)) {\n return true;\n }\n\n const lastRef = capture.lastUsed;\n const created = capture.date;\n\n if (lastRef && isWithinDays(lastRef, LIFECYCLE_ARCHIVE_DAYS, nowMs)) {\n return false;\n }\n if (!lastRef && created && isWithinDays(created, LIFECYCLE_ARCHIVE_DAYS, nowMs)) {\n return false;\n }\n\n const refAge = lastRef ? daysSince(lastRef, nowMs) : Number.POSITIVE_INFINITY;\n const createAge = created ? daysSince(created, nowMs) : Number.POSITIVE_INFINITY;\n const idleDays = Math.min(refAge, createAge);\n\n return idleDays >= LIFECYCLE_ARCHIVE_DAYS;\n}\n\nexport function isMemoryEligible(\n capture: ParsedCapture,\n nowMs: number = Date.now(),\n): boolean {\n if (capture.date && isWithinDays(capture.date, LIFECYCLE_ACTIVE_DAYS, nowMs)) {\n return true;\n }\n if (capture.lastUsed && isWithinDays(capture.lastUsed, LIFECYCLE_ACTIVE_DAYS, nowMs)) {\n return true;\n }\n return false;\n}\n\nexport function filterMemoryEligible(\n captures: ParsedCapture[],\n nowMs?: number,\n): ParsedCapture[] {\n return captures.filter((c) => isMemoryEligible(c, nowMs));\n}\n","import { existsSync, mkdirSync, renameSync, unlinkSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { ignoreMarkerPath } from \"./ignoreMarker.js\";\n\nexport function archiveCapturePath(\n repoRoot: string,\n captureRelativePath: string,\n): string {\n return memoryPath(repoRoot, \".archive\", captureRelativePath);\n}\n\nexport function moveCaptureToArchive(\n repoRoot: string,\n captureRelativePath: string,\n): boolean {\n const src = join(repoRoot, \".memory\", captureRelativePath);\n if (!existsSync(src)) {\n return false;\n }\n const dest = archiveCapturePath(repoRoot, captureRelativePath);\n mkdirSync(dirname(dest), { recursive: true });\n renameSync(src, dest);\n\n const ignore = ignoreMarkerPath(repoRoot, captureRelativePath);\n if (existsSync(ignore)) {\n try {\n unlinkSync(ignore);\n } catch {\n // best effort\n }\n }\n const promote = join(repoRoot, \".memory\", `${captureRelativePath}.promote`);\n if (existsSync(promote)) {\n try {\n unlinkSync(promote);\n } catch {\n // best effort\n }\n }\n return true;\n}\n","import type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport {\n filterMemoryEligible,\n shouldArchiveCapture,\n} from \"./memoryEligibility.js\";\nimport { moveCaptureToArchive } from \"./archiveCapture.js\";\n\nexport interface ApplyLifecycleResult {\n archived: number;\n demotedFromMemory: number;\n memoryCaptures: ParsedCapture[];\n}\n\nexport function applyLifecycle(\n repoRoot: string,\n allActive: ParsedCapture[],\n dryRun?: boolean,\n nowMs: number = Date.now(),\n): ApplyLifecycleResult {\n const remaining: ParsedCapture[] = [];\n let archived = 0;\n\n for (const c of allActive) {\n if (shouldArchiveCapture(c, repoRoot, nowMs)) {\n if (!dryRun) {\n if (moveCaptureToArchive(repoRoot, c.path)) {\n archived++;\n }\n } else {\n archived++;\n }\n continue;\n }\n remaining.push(c);\n }\n\n const memoryCaptures = filterMemoryEligible(remaining, nowMs);\n const demotedFromMemory = remaining.length - memoryCaptures.length;\n\n return { archived, demotedFromMemory, memoryCaptures };\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\n\nasync function chatJson(\n llm: LlmConfig,\n system: string,\n user: string,\n): Promise<unknown | null> {\n const url = `${llm.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), llm.timeoutMs);\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${llm.apiKey}`,\n },\n body: JSON.stringify({\n model: llm.model,\n response_format: { type: \"json_object\" },\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n temperature: 0.2,\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n return null;\n }\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n return null;\n }\n return JSON.parse(content) as unknown;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nconst TOPIC_SYSTEM = `You maintain a project memory topic file in Markdown.\nRespond with JSON only: { \"body\": \"<markdown without frontmatter>\" }\nUse Chinese when source captures are Chinese. Keep concise bullets and headings.`;\n\nconst MEMORY_SYSTEM = `You generate a project MEMORY.md summary for AI session injection.\nRespond with JSON only:\n{\n \"activeTopics\": \"markdown bullet list\",\n \"recentExperience\": \"markdown bullet list\",\n \"conventions\": \"markdown bullet list\",\n \"skills\": \"markdown bullet list for available skills (name + one line description)\",\n \"conflicts\": \"markdown bullet list or empty\"\n}\nEach section is markdown fragments only (no top-level #). Stay under 1800 characters total.`;\n\nconst COMPRESS_SYSTEM = `Compress the MEMORY.md draft to fit injection limit.\nRespond with JSON only: { \"memory\": \"<full markdown document starting with # 项目记忆>\" }\nPreserve section structure. Use Chinese if input is Chinese.`;\n\nexport async function updateTopicViaLlm(\n llm: LlmConfig,\n tag: string,\n existingBody: string,\n newSummaries: string[],\n): Promise<string | null> {\n const user = `Tag: ${tag}\nExisting topic:\n${existingBody.slice(0, 4000)}\n\nNew captures:\n${newSummaries.join(\"\\n---\\n\").slice(0, 6000)}`;\n\n const parsed = (await chatJson(llm, TOPIC_SYSTEM, user)) as {\n body?: string;\n } | null;\n return typeof parsed?.body === \"string\" ? parsed.body : null;\n}\n\nexport async function generateMemoryViaLlm(\n llm: LlmConfig,\n topicSummaries: string,\n recentLines: string,\n conflictsText: string,\n statsLine: string,\n skillsText = \"\",\n): Promise<{\n activeTopics: string;\n recentExperience: string;\n conventions: string;\n skills: string;\n conflicts: string;\n} | null> {\n const user = `Stats: ${statsLine}\nTopic summaries:\n${topicSummaries.slice(0, 5000)}\n\nRecent captures:\n${recentLines.slice(0, 4000)}\n\nAvailable skills:\n${skillsText.slice(0, 2000)}\n\nConflicts:\n${conflictsText}`;\n\n const parsed = (await chatJson(llm, MEMORY_SYSTEM, user)) as {\n activeTopics?: string;\n recentExperience?: string;\n conventions?: string;\n skills?: string;\n conflicts?: string;\n } | null;\n\n if (!parsed) {\n return null;\n }\n return {\n activeTopics: parsed.activeTopics ?? \"\",\n recentExperience: parsed.recentExperience ?? \"\",\n conventions: parsed.conventions ?? \"\",\n skills: parsed.skills ?? \"\",\n conflicts: parsed.conflicts ?? \"\",\n };\n}\n\nexport async function compressMemoryViaLlm(\n llm: LlmConfig,\n draft: string,\n maxChars: number,\n): Promise<string | null> {\n const user = `Max chars: ${maxChars}\\n\\nDraft:\\n${draft}`;\n const parsed = (await chatJson(llm, COMPRESS_SYSTEM, user)) as {\n memory?: string;\n } | null;\n return typeof parsed?.memory === \"string\" ? parsed.memory : null;\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { SkillUsageMap } from \"../feedback/types.js\";\nimport { isWithinDays } from \"../lifecycle/dates.js\";\nimport { SKILL_MEMORY_ARCHIVE_DAYS } from \"../lifecycle/constants.js\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport interface SkillIndexEntry {\n slug: string;\n name: string;\n description: string;\n triggerTags: string[];\n path: string;\n}\n\nfunction parseSkillFrontmatter(content: string): {\n name: string;\n description: string;\n triggerTags: string[];\n} {\n const parts = content.split(/^---\\s*$/m);\n if (parts.length < 3) {\n return { name: \"\", description: \"\", triggerTags: [] };\n }\n const fm = parts[1];\n const name = fm.match(/^name:\\s*(.+)$/im)?.[1]?.trim() ?? \"\";\n let description = \"\";\n const descBlock = fm.match(/description:\\s*>\\s*\\n([\\s\\S]*?)(?=\\n[a-z])/i);\n if (descBlock) {\n description = descBlock[1].replace(/\\n\\s+/g, \" \").trim();\n } else {\n description = fm.match(/^description:\\s*(.+)$/im)?.[1]?.trim() ?? \"\";\n }\n const tagsMatch = fm.match(/^trigger-tags:\\s*\\[([^\\]]*)\\]/im);\n const triggerTags: string[] = [];\n if (tagsMatch) {\n const inner = tagsMatch[1];\n try {\n const arr = JSON.parse(`[${inner}]`) as unknown;\n if (Array.isArray(arr)) {\n triggerTags.push(...arr.filter((x) => typeof x === \"string\"));\n }\n } catch {\n inner.split(\",\").forEach((t) => {\n const s = t.trim().replace(/^[\"']|[\"']$/g, \"\");\n if (s) {\n triggerTags.push(s);\n }\n });\n }\n }\n return { name, description, triggerTags };\n}\n\nexport function listSkillIndex(repoRoot: string): SkillIndexEntry[] {\n const skillsDir = memoryPath(repoRoot, \"skills\");\n if (!existsSync(skillsDir)) {\n return [];\n }\n const entries: SkillIndexEntry[] = [];\n for (const slug of readdirSync(skillsDir)) {\n const skillFile = join(skillsDir, slug, \"SKILL.md\");\n if (!existsSync(skillFile)) {\n continue;\n }\n try {\n const content = readFileSync(skillFile, \"utf8\");\n const { name, description, triggerTags } = parseSkillFrontmatter(content);\n entries.push({\n slug,\n name: name || slug,\n description: description.slice(0, 120),\n triggerTags,\n path: `skills/${slug}/SKILL.md`,\n });\n } catch {\n // skip\n }\n }\n return entries.sort((a, b) => a.slug.localeCompare(b.slug));\n}\n\nexport function filterSkillIndexForMemory(\n entries: SkillIndexEntry[],\n skillUsage: SkillUsageMap,\n repoRoot: string,\n nowMs: number = Date.now(),\n): SkillIndexEntry[] {\n const skillsDir = memoryPath(repoRoot, \"skills\");\n const kept: { entry: SkillIndexEntry; useCount: number; lastUsed: string }[] = [];\n\n for (const entry of entries) {\n const usage = skillUsage[entry.path];\n if (usage?.last_used && isWithinDays(usage.last_used, SKILL_MEMORY_ARCHIVE_DAYS, nowMs)) {\n kept.push({\n entry,\n useCount: usage.use_count,\n lastUsed: usage.last_used,\n });\n continue;\n }\n const abs = join(skillsDir, entry.slug, \"SKILL.md\");\n if (existsSync(abs)) {\n const mtime = statSync(abs).mtimeMs;\n const mtimeDate = new Date(mtime).toISOString().slice(0, 10);\n if (isWithinDays(mtimeDate, SKILL_MEMORY_ARCHIVE_DAYS, nowMs)) {\n kept.push({\n entry,\n useCount: usage?.use_count ?? 0,\n lastUsed: usage?.last_used ?? mtimeDate,\n });\n }\n }\n }\n\n return kept\n .sort((a, b) => b.useCount - a.useCount || b.lastUsed.localeCompare(a.lastUsed))\n .map((x) => x.entry);\n}\n\nexport function formatSkillsSectionForMemory(\n entries: SkillIndexEntry[],\n maxItems = 8,\n): string {\n if (entries.length === 0) {\n return \"(暂无)\";\n }\n return entries\n .slice(0, maxItems)\n .map((e) => {\n const tags =\n e.triggerTags.length > 0\n ? ` [匹配标签: ${e.triggerTags.slice(0, 4).join(\", \")}]`\n : \"\";\n return `- **${e.name}**: ${e.description || \"见 SKILL.md\"}${tags}`;\n })\n .join(\"\\n\");\n}\n","import type { MemoryConflict } from \"./detectConflict.js\";\nimport {\n ACTIVE_TOPIC_MAX,\n INJECT_MAX_CHARS,\n RECENT_EXPERIENCE_DAYS,\n RECENT_EXPERIENCE_MAX,\n} from \"./constants.js\";\nimport type { LlmConfig } from \"../config/llmConfig.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport { captureMtimeMs } from \"./listCaptures.js\";\nimport { primaryTag, tagToSlug, type ParsedCapture } from \"./parseCapture.js\";\nimport {\n compressMemoryViaLlm,\n generateMemoryViaLlm,\n} from \"./llmConsolidate.js\";\nimport {\n formatSkillsSectionForMemory,\n type SkillIndexEntry,\n} from \"../skills/skillIndex.js\";\n\nfunction countByType(captures: ParsedCapture[]): {\n semantic: number;\n episodic: number;\n procedural: number;\n} {\n const counts = { semantic: 0, episodic: 0, procedural: 0 };\n for (const c of captures) {\n counts[c.type]++;\n }\n return counts;\n}\n\nfunction tagScore(captures: ParsedCapture[]): Map<string, number> {\n const freq = new Map<string, number>();\n for (const c of captures) {\n const tag = primaryTag(c);\n const boost = (c.useCount ?? 0) * 2;\n freq.set(tag, (freq.get(tag) ?? 0) + 1 + boost);\n }\n return freq;\n}\n\nfunction topTagsByUsage(captures: ParsedCapture[], limit: number): string[] {\n const freq = tagScore(captures);\n return [...freq.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, limit)\n .map(([tag]) => tag);\n}\n\nfunction recentCaptures(\n captures: ParsedCapture[],\n days: number,\n max: number,\n): ParsedCapture[] {\n const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;\n return captures\n .filter((c) => captureMtimeMs(c) >= cutoff || Date.parse(c.date) >= cutoff)\n .sort((a, b) => {\n const uc = (b.useCount ?? 0) - (a.useCount ?? 0);\n if (uc !== 0) {\n return uc;\n }\n return captureMtimeMs(b) - captureMtimeMs(a);\n })\n .slice(0, max);\n}\n\nfunction conventionCaptures(captures: ParsedCapture[]): ParsedCapture[] {\n return captures.filter(\n (c) =>\n c.type === \"semantic\" &&\n (c.tags.includes(\"convention\") ||\n c.tags.includes(\"conventions\") ||\n /约定|架构|规范/.test(c.summary + c.findings)),\n );\n}\n\nfunction ruleSectionBullets(\n captures: ParsedCapture[],\n prefix: (c: ParsedCapture) => string,\n): string {\n if (captures.length === 0) {\n return \"(暂无)\";\n }\n return captures.map((c) => `- ${prefix(c)}`).join(\"\\n\");\n}\n\nfunction formatConflicts(conflicts: MemoryConflict[]): string {\n if (conflicts.length === 0) {\n return \"\";\n }\n return conflicts\n .map(\n (x) =>\n `- [${x.tag}/${x.scope}] ${x.pathA} vs ${x.pathB} — ${x.reason}`,\n )\n .join(\"\\n\");\n}\n\nexport interface BuildMemoryOptions {\n allActive: ParsedCapture[];\n memoryCaptures: ParsedCapture[];\n newCaptures: ParsedCapture[];\n conflicts: MemoryConflict[];\n lastConsolidatedAt: string;\n skillIndex?: SkillIndexEntry[];\n demotedFromMemory?: number;\n archivedCount?: number;\n}\n\nexport function buildMemoryRule(opts: BuildMemoryOptions): string {\n const {\n allActive,\n memoryCaptures,\n newCaptures,\n conflicts,\n lastConsolidatedAt,\n skillIndex = [],\n demotedFromMemory = 0,\n archivedCount = 0,\n } = opts;\n\n const counts = countByType(allActive);\n const total = allActive.length;\n const now = new Date().toISOString().slice(0, 10);\n const tags = topTagsByUsage(memoryCaptures, ACTIVE_TOPIC_MAX);\n const recent = recentCaptures(\n memoryCaptures,\n RECENT_EXPERIENCE_DAYS,\n RECENT_EXPERIENCE_MAX,\n );\n const conv = conventionCaptures(memoryCaptures);\n\n const activeTopics =\n tags.length > 0\n ? tags\n .map(\n (t) =>\n `- **${t}**: 见 \\`.memory/topics/${tagToSlug(t)}.md\\``,\n )\n .join(\"\\n\")\n : \"(暂无)\";\n\n const recentExp = ruleSectionBullets(\n recent,\n (c) => `[${c.date}] [${c.type}] ${c.summary.slice(0, 80)}`,\n );\n\n const conventions = ruleSectionBullets(conv.slice(0, 6), (c) =>\n c.summary.slice(0, 100),\n );\n\n const conflictBlock = formatConflicts(conflicts);\n const conflictSection = conflictBlock\n ? `\\n## 待解决冲突\\n\\n${conflictBlock}\\n`\n : \"\";\n\n const skillsSection = formatSkillsSectionForMemory(skillIndex);\n\n const lifecycleNote =\n demotedFromMemory > 0 || archivedCount > 0\n ? ` | 降级 ${demotedFromMemory} 条 | 归档 ${archivedCount} 条`\n : \"\";\n\n return `# 项目记忆\n\n最后更新: ${now} | 总计: ${total} 条捕获(${counts.semantic} 语义 + ${counts.episodic} 情景 + ${counts.procedural} 流程)${lifecycleNote}\n上次 consolidate: ${lastConsolidatedAt.slice(0, 10)} | 本次新处理: ${newCaptures.length} 条\n\n## 活跃主题\n\n${activeTopics}\n\n## 最近经验(7天内)\n\n${recentExp}\n\n## 项目约定\n\n${conventions}\n${conflictSection}\n## 可用技能\n\n${skillsSection}\n\n使用: 任务匹配时读取 \\`.memory/skills/<name>/SKILL.md\\`\n\n## 检索提示\n\n- 搜索记忆: \\`npx @riconext/hermes-repo search <关键词>\\`\n- 查看捕获: \\`ls .memory/captures/\\` 或 \\`cat .memory/captures/<type>/<文件>.md\\`\n- 查看主题: \\`ls .memory/topics/\\`\n- 查看技能: \\`ls .memory/skills/\\`\n- 记录引用: \\`npx @riconext/hermes-repo ref --capture <path> --reason \"...\"\\`\n- 健康度: \\`npx @riconext/hermes-repo stats\\`\n- 手动整理: \\`npx @riconext/hermes-repo flush\\`\n`;\n}\n\nexport async function buildMemory(\n allActive: ParsedCapture[],\n memoryCaptures: ParsedCapture[],\n newCaptures: ParsedCapture[],\n conflicts: MemoryConflict[],\n lastConsolidatedAt: string,\n topicFiles: string[],\n llm: LlmConfig | null,\n skillIndex: SkillIndexEntry[] = [],\n lifecycleMeta?: { demotedFromMemory: number; archivedCount: number },\n): Promise<string> {\n const ruleOpts: BuildMemoryOptions = {\n allActive,\n memoryCaptures,\n newCaptures,\n conflicts,\n lastConsolidatedAt,\n skillIndex,\n demotedFromMemory: lifecycleMeta?.demotedFromMemory,\n archivedCount: lifecycleMeta?.archivedCount,\n };\n\n const ruleDraft = buildMemoryRule(ruleOpts);\n\n if (!isLlmAvailable(llm)) {\n return trimToMax(ruleDraft, INJECT_MAX_CHARS);\n }\n\n const counts = countByType(allActive);\n const statsLine = `${allActive.length} captures (${counts.semantic}s/${counts.episodic}e/${counts.procedural}p), ${memoryCaptures.length} in MEMORY`;\n const topicSummaries = topicFiles.join(\", \") || \"none\";\n const recent = recentCaptures(\n memoryCaptures,\n RECENT_EXPERIENCE_DAYS,\n RECENT_EXPERIENCE_MAX,\n );\n const recentLines = recent\n .map((c) => `[${c.date}] ${c.type}: ${c.summary}`)\n .join(\"\\n\");\n const conflictsText = formatConflicts(conflicts) || \"none\";\n const skillsText = formatSkillsSectionForMemory(skillIndex);\n\n const sections = await generateMemoryViaLlm(\n llm!,\n topicSummaries,\n recentLines,\n conflictsText,\n statsLine,\n skillsText,\n );\n\n if (!sections) {\n return trimToMax(ruleDraft, INJECT_MAX_CHARS);\n }\n\n const now = new Date().toISOString().slice(0, 10);\n const lifecycleNote =\n (lifecycleMeta?.demotedFromMemory ?? 0) > 0 ||\n (lifecycleMeta?.archivedCount ?? 0) > 0\n ? ` | 降级 ${lifecycleMeta?.demotedFromMemory ?? 0} | 归档 ${lifecycleMeta?.archivedCount ?? 0}`\n : \"\";\n\n let draft = `# 项目记忆\n\n最后更新: ${now} | 总计: ${allActive.length} 条捕获(${counts.semantic} 语义 + ${counts.episodic} 情景 + ${counts.procedural} 流程)${lifecycleNote}\n上次 consolidate: ${lastConsolidatedAt.slice(0, 10)} | 本次新处理: ${newCaptures.length} 条\n\n## 活跃主题\n\n${sections.activeTopics || \"(暂无)\"}\n\n## 最近经验(7天内)\n\n${sections.recentExperience || \"(暂无)\"}\n\n## 项目约定\n\n${sections.conventions || \"(暂无)\"}\n`;\n\n if (sections.conflicts?.trim()) {\n draft += `\\n## 待解决冲突\\n\\n${sections.conflicts}\\n`;\n }\n\n draft += `\n## 可用技能\n\n${sections.skills?.trim() || formatSkillsSectionForMemory(skillIndex)}\n\n使用: 任务匹配时读取 \\`.memory/skills/<name>/SKILL.md\\`\n\n## 检索提示\n\n- 搜索记忆: \\`npx @riconext/hermes-repo search <关键词>\\`\n- 查看捕获: \\`ls .memory/captures/\\`\n- 查看主题: \\`ls .memory/topics/\\`\n- 查看技能: \\`ls .memory/skills/\\`\n- 记录引用: \\`npx @riconext/hermes-repo ref --capture <path> --reason \"...\"\\`\n- 健康度: \\`npx @riconext/hermes-repo stats\\`\n- 手动整理: \\`npx @riconext/hermes-repo flush\\`\n`;\n\n if (draft.length <= INJECT_MAX_CHARS) {\n return draft.endsWith(\"\\n\") ? draft : `${draft}\\n`;\n }\n\n const compressed = await compressMemoryViaLlm(llm!, draft, INJECT_MAX_CHARS);\n if (compressed) {\n return trimToMax(compressed, INJECT_MAX_CHARS);\n }\n return trimToMax(ruleDraft, INJECT_MAX_CHARS);\n}\n\nfunction trimToMax(text: string, max: number): string {\n if (text.length <= max) {\n return text.endsWith(\"\\n\") ? text : `${text}\\n`;\n }\n return `${text.slice(0, max - 20)}\\n\\n...(truncated)\\n`;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport type { LlmConfig } from \"../config/llmConfig.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { primaryTag, tagToSlug, type ParsedCapture } from \"./parseCapture.js\";\nimport { updateTopicViaLlm } from \"./llmConsolidate.js\";\n\nfunction groupByPrimaryTag(\n captures: ParsedCapture[],\n): Map<string, ParsedCapture[]> {\n const map = new Map<string, ParsedCapture[]>();\n for (const c of captures) {\n const tag = primaryTag(c);\n const list = map.get(tag) ?? [];\n list.push(c);\n map.set(tag, list);\n }\n return map;\n}\n\nfunction ruleTopicBody(\n tag: string,\n captures: ParsedCapture[],\n existing: string,\n): string {\n const lines = captures.map(\n (c) =>\n `- [${c.date}] [${c.type}] ${c.summary.slice(0, 120)} (${c.path})`,\n );\n const header = `# ${tag}\\n\\n`;\n if (existing.trim()) {\n return `${existing.trimEnd()}\\n\\n## 更新 ${new Date().toISOString().slice(0, 10)}\\n\\n${lines.join(\"\\n\")}\\n`;\n }\n return `${header}由 consolidate 自动生成。\\n\\n${lines.join(\"\\n\")}\\n`;\n}\n\nexport async function buildTopics(\n repoRoot: string,\n captures: ParsedCapture[],\n llm: LlmConfig | null,\n): Promise<string[]> {\n const written: string[] = [];\n const groups = groupByPrimaryTag(captures);\n const topicsDir = memoryPath(repoRoot, \"topics\");\n mkdirSync(topicsDir, { recursive: true });\n\n for (const [tag, group] of groups) {\n const slug = tagToSlug(tag);\n const rel = `topics/${slug}.md`;\n const abs = memoryPath(repoRoot, \"topics\", `${slug}.md`);\n let existing = \"\";\n if (existsSync(abs)) {\n try {\n existing = readFileSync(abs, \"utf8\");\n } catch {\n existing = \"\";\n }\n }\n\n const summaries = group.map(\n (c) => `[${c.type}] ${c.summary}\\n${c.findings.slice(0, 300)}`,\n );\n\n let body: string | null = null;\n if (isLlmAvailable(llm)) {\n body = await updateTopicViaLlm(llm!, tag, existing, summaries);\n }\n if (!body) {\n body = ruleTopicBody(tag, group, existing);\n }\n\n writeFileSync(abs, body.endsWith(\"\\n\") ? body : `${body}\\n`, \"utf8\");\n written.push(rel);\n }\n\n return written;\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport type { ParsedCapture } from \"./parseCapture.js\";\n\nfunction normalizeText(text: string): string {\n return text.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\nfunction groupKey(c: ParsedCapture): string {\n const tags = [...c.tags].sort().join(\",\");\n return `${c.scope}::${tags}`;\n}\n\nfunction similarity(a: ParsedCapture, b: ParsedCapture): number {\n const na = normalizeText(a.summary).slice(0, 200);\n const nb = normalizeText(b.summary).slice(0, 200);\n if (!na || !nb) {\n return 0;\n }\n if (na === nb) {\n return 1;\n }\n const shorter = na.length < nb.length ? na : nb;\n const longer = na.length >= nb.length ? na : nb;\n return longer.includes(shorter) ? 0.85 : 0;\n}\n\nfunction updateFrontmatterConfidence(\n content: string,\n confidence: string,\n supersededBy?: string,\n): string {\n const parts = content.split(/^---\\s*$/m);\n if (parts.length < 3) {\n return content;\n }\n let fm = parts[1];\n fm = fm.replace(/^confidence:\\s*.+$/im, `confidence: ${confidence}`);\n if (supersededBy) {\n if (/^superseded_by:/im.test(fm)) {\n fm = fm.replace(/^superseded_by:\\s*.+$/im, `superseded_by: ${supersededBy}`);\n } else {\n fm = `${fm.trimEnd()}\\nsuperseded_by: ${supersededBy}\\n`;\n }\n }\n return `---\\n${fm}---${parts.slice(2).join(\"---\")}`;\n}\n\nexport interface DedupeResult {\n /** 参与 consolidate 的有效 capture(去重后保留的代表) */\n active: ParsedCapture[];\n supersededPaths: string[];\n}\n\nexport function dedupeCaptures(captures: ParsedCapture[]): DedupeResult {\n const groups = new Map<string, ParsedCapture[]>();\n for (const c of captures) {\n const key = groupKey(c);\n const list = groups.get(key) ?? [];\n list.push(c);\n groups.set(key, list);\n }\n\n const active: ParsedCapture[] = [];\n const supersededPaths: string[] = [];\n\n for (const list of groups.values()) {\n if (list.length === 1) {\n active.push(list[0]);\n continue;\n }\n const sorted = [...list].sort((a, b) => {\n const llmA = a.llmUpgradedAt ? 1 : 0;\n const llmB = b.llmUpgradedAt ? 1 : 0;\n if (llmB !== llmA) {\n return llmB - llmA;\n }\n return b.date.localeCompare(a.date);\n });\n const keeper = sorted[0];\n active.push(keeper);\n for (let i = 1; i < sorted.length; i++) {\n const dup = sorted[i];\n if (similarity(keeper, dup) >= 0.8) {\n markSuperseded(dup, keeper.path);\n supersededPaths.push(dup.path);\n } else {\n active.push(dup);\n }\n }\n }\n\n return { active, supersededPaths };\n}\n\nfunction markSuperseded(capture: ParsedCapture, keeperPath: string): void {\n try {\n const raw = readFileSync(capture.absolutePath, \"utf8\");\n const updated = updateFrontmatterConfidence(\n raw,\n \"superseded\",\n keeperPath,\n );\n writeFileSync(capture.absolutePath, updated, \"utf8\");\n capture.confidence = \"superseded\";\n capture.supersededBy = keeperPath;\n } catch {\n // best effort\n }\n}\n","import { primaryTag, type ParsedCapture } from \"./parseCapture.js\";\n\nexport interface MemoryConflict {\n tag: string;\n scope: string;\n pathA: string;\n pathB: string;\n reason: string;\n}\n\n/** 互斥关键词对(小写匹配 findings/summary) */\nconst MUTEX_PAIRS: [string, string][] = [\n [\"localstorage\", \"httponly\"],\n [\"local storage\", \"httponly\"],\n [\"mysql\", \"postgresql\"],\n [\"mysql\", \"postgres\"],\n [\"javascript\", \"typescript-only\"],\n [\"npm\", \"pnpm-only\"],\n];\n\nfunction textBlob(c: ParsedCapture): string {\n return `${c.summary} ${c.findings}`.toLowerCase();\n}\n\nfunction hasTerm(blob: string, term: string): boolean {\n return blob.includes(term.toLowerCase());\n}\n\nfunction pairConflicts(a: string, b: string): boolean {\n for (const [x, y] of MUTEX_PAIRS) {\n const hasX = hasTerm(a, x) && hasTerm(b, y);\n const hasY = hasTerm(a, y) && hasTerm(b, x);\n if (hasX || hasY) {\n return true;\n }\n }\n return false;\n}\n\nexport function detectConflicts(captures: ParsedCapture[]): MemoryConflict[] {\n const conflicts: MemoryConflict[] = [];\n const byTagScope = new Map<string, ParsedCapture[]>();\n\n for (const c of captures) {\n if (c.confidence === \"superseded\") {\n continue;\n }\n const tag = primaryTag(c);\n const key = `${c.scope}::${tag}`;\n const list = byTagScope.get(key) ?? [];\n list.push(c);\n byTagScope.set(key, list);\n }\n\n for (const [key, list] of byTagScope) {\n if (list.length < 2) {\n continue;\n }\n const [scopePart, tag] = key.split(\"::\");\n for (let i = 0; i < list.length; i++) {\n for (let j = i + 1; j < list.length; j++) {\n const a = list[i];\n const b = list[j];\n const blobA = textBlob(a);\n const blobB = textBlob(b);\n if (pairConflicts(blobA, blobB)) {\n conflicts.push({\n tag,\n scope: scopePart,\n pathA: a.path,\n pathB: b.path,\n reason: \"互斥断言(规则检测)\",\n });\n }\n }\n }\n }\n\n return conflicts;\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport type { LlmConfig } from \"../config/llmConfig.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport {\n filterActiveCaptures,\n listAllCaptures,\n} from \"../consolidate/listCaptures.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport {\n groupProceduralCaptures,\n groupsToPromote,\n type ProceduralGroup,\n} from \"./groupProcedural.js\";\nimport {\n applyLlmSkillToMarkdown,\n generateSkillViaLlm,\n} from \"./llmSkill.js\";\nimport { attachPromoteMarkers } from \"./promoteMarker.js\";\nimport { writeRepeatCountsForGroups } from \"./repeatCount.js\";\nimport {\n readExistingSkill,\n renderSkillMarkdown,\n skillBodyHash,\n} from \"./renderSkillMd.js\";\nimport {\n listSkillIndex,\n type SkillIndexEntry,\n} from \"./skillIndex.js\";\n\nexport interface PromoteSkillsOptions {\n repoRoot: string;\n captures: ParsedCapture[];\n dryRun?: boolean;\n debug?: boolean;\n llm: LlmConfig | null;\n}\n\nexport interface PromoteSkillsResult {\n skillsWritten: number;\n skillIndex: SkillIndexEntry[];\n}\n\nasync function writeSkillForGroup(\n repoRoot: string,\n group: ProceduralGroup,\n llm: LlmConfig | null,\n debug?: boolean,\n): Promise<boolean> {\n const skillDir = memoryPath(repoRoot, \"skills\", group.skillSlug);\n const skillFile = join(skillDir, \"SKILL.md\");\n const existing = readExistingSkill(skillFile);\n const existingHash = existing ? skillBodyHash(existing) : \"\";\n\n let content = renderSkillMarkdown({ group, existingContent: existing });\n\n if (isLlmAvailable(llm)) {\n const extract = await generateSkillViaLlm(llm!, group, existing);\n if (extract) {\n content = applyLlmSkillToMarkdown(content, extract, group);\n debugLog(debug === true, \"skills\", `llm ok: ${group.skillSlug}`);\n } else {\n debugLog(debug === true, \"skills\", `skill-llm-fallback: ${group.skillSlug}`);\n }\n }\n\n const newHash = skillBodyHash(content);\n if (existing && existingHash === newHash && !group.forcedByPromote) {\n return false;\n }\n\n mkdirSync(skillDir, { recursive: true });\n writeFileSync(skillFile, content.endsWith(\"\\n\") ? content : `${content}\\n`, \"utf8\");\n return true;\n}\n\nexport async function promoteSkills(\n opts: PromoteSkillsOptions,\n): Promise<PromoteSkillsResult> {\n const { repoRoot, captures, dryRun, debug, llm } = opts;\n\n const allCaps =\n captures.length > 0 ? captures : listAllCaptures(repoRoot);\n attachPromoteMarkers(repoRoot, allCaps, debug);\n\n const procedural = filterActiveCaptures(allCaps).filter(\n (c) => c.type === \"procedural\",\n );\n\n const allGroups = groupProceduralCaptures(procedural);\n writeRepeatCountsForGroups(allGroups);\n\n const toPromote = groupsToPromote(allGroups);\n\n if (dryRun) {\n debugLog(\n debug === true,\n \"skills\",\n `[dry-run] would promote ${toPromote.length} skill(s)`,\n );\n return {\n skillsWritten: toPromote.length,\n skillIndex: listSkillIndex(repoRoot),\n };\n }\n\n let written = 0;\n for (const group of toPromote) {\n const didWrite = await writeSkillForGroup(repoRoot, group, llm, debug);\n if (didWrite) {\n written++;\n debugLog(debug === true, \"skills\", `promoted: skills/${group.skillSlug}/SKILL.md`);\n }\n }\n\n const skillIndex = listSkillIndex(repoRoot);\n return { skillsWritten: written, skillIndex };\n}\n","import { extractSection, type ParsedCapture } from \"../consolidate/parseCapture.js\";\n\nexport interface ProceduralSections {\n goal: string;\n steps: string;\n cautions: string;\n verification: string;\n}\n\nexport function parseProceduralSections(capture: ParsedCapture): ProceduralSections {\n const body = capture.bodyMarkdown;\n return {\n goal: extractSection(body, \"目标\"),\n steps: extractSection(body, \"步骤\"),\n cautions: extractSection(body, \"注意\"),\n verification: extractSection(body, \"验证\"),\n };\n}\n\nexport function countStepsInText(stepsText: string): number {\n if (!stepsText.trim()) {\n return 0;\n }\n const numbered = stepsText.match(/^\\s*\\d+\\./gm);\n if (numbered && numbered.length > 0) {\n return numbered.length;\n }\n return stepsText.split(\"\\n\").filter((l) => l.trim().length > 0).length;\n}\n\nexport function proceduralSummary(capture: ParsedCapture): string {\n const { goal, steps } = parseProceduralSections(capture);\n const firstStep = steps\n .split(\"\\n\")\n .find((l) => l.trim() && !l.startsWith(\"#\"))\n ?.trim();\n return (goal || firstStep || capture.summary).slice(0, 120);\n}\n\nexport function captureTextBlob(capture: ParsedCapture): string {\n const { goal, steps, cautions } = parseProceduralSections(capture);\n return `${capture.tags.join(\" \")} ${goal} ${steps} ${cautions} ${capture.summary}`.toLowerCase();\n}\n","/** 同主 tag 的 procedural 达到此次数可晋升 Skill */\nexport const SKILL_PROMOTE_COUNT_THRESHOLD = 3;\n\n/** 步骤数 ≤ 此值且非高风险、无 .promote 时不晋升 */\nexport const SKILL_MIN_STEPS_FOR_PROMOTE = 3;\n\nexport const HIGH_RISK_KEYWORDS = [\n \"deploy\",\n \"deployment\",\n \"migration\",\n \"migrate\",\n \"rollback\",\n \"release\",\n \"restore\",\n \"recovery\",\n \"发布\",\n \"部署\",\n \"迁移\",\n \"回滚\",\n] as const;\n","import {\n primaryTag,\n tagToSlug,\n type ParsedCapture,\n} from \"../consolidate/parseCapture.js\";\nimport {\n captureTextBlob,\n countStepsInText,\n parseProceduralSections,\n} from \"./parseProcedural.js\";\nimport {\n HIGH_RISK_KEYWORDS,\n SKILL_MIN_STEPS_FOR_PROMOTE,\n SKILL_PROMOTE_COUNT_THRESHOLD,\n} from \"./constants.js\";\n\nexport interface ProceduralGroup {\n skillSlug: string;\n primaryTagName: string;\n captures: ParsedCapture[];\n forcedByPromote: boolean;\n}\n\nexport function isHighRiskGroup(captures: ParsedCapture[]): boolean {\n for (const c of captures) {\n const blob = captureTextBlob(c);\n if (HIGH_RISK_KEYWORDS.some((kw) => blob.includes(kw.toLowerCase()))) {\n return true;\n }\n }\n return false;\n}\n\nexport function effectiveStepCount(capture: ParsedCapture): number {\n if (typeof capture.stepCount === \"number\" && capture.stepCount > 0) {\n return capture.stepCount;\n }\n const { steps } = parseProceduralSections(capture);\n return countStepsInText(steps);\n}\n\nexport function shouldPromoteGroup(group: ProceduralGroup): boolean {\n const { captures, forcedByPromote } = group;\n if (forcedByPromote) {\n return true;\n }\n const count = captures.length;\n if (count >= SKILL_PROMOTE_COUNT_THRESHOLD) {\n return true;\n }\n if (isHighRiskGroup(captures) && count >= 1) {\n return true;\n }\n const maxSteps = Math.max(...captures.map((c) => effectiveStepCount(c)), 0);\n if (maxSteps <= SKILL_MIN_STEPS_FOR_PROMOTE) {\n return false;\n }\n return false;\n}\n\nexport function groupProceduralCaptures(\n procedural: ParsedCapture[],\n): ProceduralGroup[] {\n const map = new Map<string, ParsedCapture[]>();\n\n for (const c of procedural) {\n if (c.confidence === \"superseded\") {\n continue;\n }\n const tag = primaryTag(c);\n const slug = tagToSlug(tag);\n const list = map.get(slug) ?? [];\n list.push(c);\n map.set(slug, list);\n }\n\n const groups: ProceduralGroup[] = [];\n for (const [skillSlug, caps] of map) {\n const sorted = [...caps].sort((a, b) => b.date.localeCompare(a.date));\n const forcedByPromote = sorted.some((c) => c.hasPromoteMarker === true);\n groups.push({\n skillSlug,\n primaryTagName: primaryTag(sorted[0]),\n captures: sorted,\n forcedByPromote,\n });\n }\n\n return groups;\n}\n\nexport function groupsToPromote(groups: ProceduralGroup[]): ProceduralGroup[] {\n return groups.filter(shouldPromoteGroup);\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport type { ProceduralGroup } from \"./groupProcedural.js\";\n\nasync function chatJson(\n llm: LlmConfig,\n system: string,\n user: string,\n): Promise<unknown | null> {\n const url = `${llm.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), llm.timeoutMs);\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${llm.apiKey}`,\n },\n body: JSON.stringify({\n model: llm.model,\n response_format: { type: \"json_object\" },\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n temperature: 0.2,\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n return null;\n }\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n return null;\n }\n return JSON.parse(content) as unknown;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nconst SKILL_SYSTEM = `You generate a SKILL.md file for an AI coding agent (agentskills.io style).\nRespond with JSON only:\n{\n \"description\": \"one paragraph when to use this skill\",\n \"steps\": \"markdown numbered steps body under ## 步骤 (no frontmatter)\",\n \"cautions\": \"bullet list for pitfalls or empty string\",\n \"verification\": \"bullet list for verification or empty string\"\n}\nUse Chinese when captures are Chinese. Merge duplicate steps from multiple captures.`;\n\nexport interface LlmSkillExtract {\n description: string;\n steps: string;\n cautions: string;\n verification: string;\n}\n\nexport async function generateSkillViaLlm(\n llm: LlmConfig,\n group: ProceduralGroup,\n existingSkill?: string,\n): Promise<LlmSkillExtract | null> {\n const sources = group.captures\n .map((c) => `--- ${c.path} ---\\n${c.bodyMarkdown}`)\n .join(\"\\n\\n\")\n .slice(0, 12000);\n\n const user = `Skill slug: ${group.skillSlug}\nPrimary tag: ${group.primaryTagName}\nExisting SKILL (if any):\n${(existingSkill ?? \"\").slice(0, 6000)}\n\nProcedural captures:\n${sources}`;\n\n const parsed = (await chatJson(llm, SKILL_SYSTEM, user)) as {\n description?: string;\n steps?: string;\n cautions?: string;\n verification?: string;\n } | null;\n\n if (!parsed?.steps) {\n return null;\n }\n return {\n description: parsed.description ?? \"\",\n steps: parsed.steps,\n cautions: parsed.cautions ?? \"\",\n verification: parsed.verification ?? \"\",\n };\n}\n\nexport function applyLlmSkillToMarkdown(\n baseMarkdown: string,\n extract: LlmSkillExtract,\n group: ProceduralGroup,\n): string {\n const parts = baseMarkdown.split(/^---\\s*$/m);\n if (parts.length < 3) {\n return baseMarkdown;\n }\n let fm = parts[1];\n if (extract.description) {\n fm = fm.replace(\n /description:\\s*>[\\s\\S]*?(?=\\n[a-z])/i,\n `description: >\\n ${extract.description.replace(/\\n/g, \" \")}\\n`,\n );\n }\n\n const cautionsBlock = extract.cautions.trim()\n ? `\\n## 常见陷阱\\n\\n${extract.cautions}\\n`\n : \"\";\n\n const body = `## 步骤\n\n${extract.steps}\n${cautionsBlock}\n## 验证\n\n${extract.verification || \"(无)\"}\n`;\n\n return `---\\n${fm}---\\n${body}`;\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport type { ParsedCapture } from \"../consolidate/parseCapture.js\";\n\nexport function promoteMarkerPath(\n repoRoot: string,\n capturePath: string,\n): string {\n return join(repoRoot, \".memory\", `${capturePath}.promote`);\n}\n\nexport function hasPromoteMarker(\n repoRoot: string,\n capturePath: string,\n): boolean {\n return existsSync(promoteMarkerPath(repoRoot, capturePath));\n}\n\nexport function attachPromoteMarkers(\n repoRoot: string,\n captures: ParsedCapture[],\n debug?: boolean,\n): void {\n for (const c of captures) {\n c.hasPromoteMarker = hasPromoteMarker(repoRoot, c.path);\n if (c.hasPromoteMarker && c.type !== \"procedural\") {\n debugLog(\n debug === true,\n \"skills\",\n `warn: .promote on non-procedural ${c.path}, skipped for skill promotion`,\n );\n }\n }\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { setFrontmatterScalar } from \"../markdown/frontmatter.js\";\nimport type { ProceduralGroup } from \"./groupProcedural.js\";\n\n/** 同 tag 组写回 repeat_count(组大小) */\nexport function writeRepeatCountsForGroups(groups: ProceduralGroup[]): void {\n for (const group of groups) {\n const count = group.captures.length;\n for (const c of group.captures) {\n try {\n const raw = readFileSync(c.absolutePath, \"utf8\");\n writeFileSync(\n c.absolutePath,\n setFrontmatterScalar(raw, \"repeat_count\", count),\n \"utf8\",\n );\n c.repeatCount = count;\n } catch {\n // best effort\n }\n }\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport type { ProceduralGroup } from \"./groupProcedural.js\";\nimport { parseProceduralSections, proceduralSummary } from \"./parseProcedural.js\";\n\nexport interface RenderSkillInput {\n group: ProceduralGroup;\n existingContent?: string;\n}\n\nfunction parseVersion(content: string): string {\n const m = content.match(/^version:\\s*([^\\n]+)/im);\n return m?.[1]?.trim() ?? \"1.0.0\";\n}\n\nfunction bumpPatchVersion(version: string): string {\n const parts = version.split(\".\").map((p) => Number.parseInt(p, 10));\n if (parts.length >= 3 && parts.every((n) => !Number.isNaN(n))) {\n parts[2] += 1;\n return parts.join(\".\");\n }\n return \"1.0.1\";\n}\n\nfunction parseCreatedFrom(content: string): string[] {\n const lines: string[] = [];\n let inBlock = false;\n for (const line of content.split(\"\\n\")) {\n if (/^created-from:/i.test(line)) {\n inBlock = true;\n continue;\n }\n if (inBlock) {\n if (/^\\s+-\\s+/.test(line)) {\n lines.push(line.replace(/^\\s+-\\s+/, \"\").trim());\n } else if (line.trim() && !line.startsWith(\" \")) {\n break;\n }\n }\n }\n return lines;\n}\n\nfunction formatTagsYaml(tags: string[]): string {\n const unique = [...new Set(tags.filter(Boolean))];\n return `[${unique.map((t) => JSON.stringify(t)).join(\", \")}]`;\n}\n\nexport function renderSkillMarkdown(input: RenderSkillInput): string {\n const { group, existingContent } = input;\n const latest = group.captures[0];\n const sections = parseProceduralSections(latest);\n const description =\n proceduralSummary(latest) ||\n `可复用流程:${group.primaryTagName}`;\n\n const createdFrom = new Set<string>(\n existingContent ? parseCreatedFrom(existingContent) : [],\n );\n for (const c of group.captures) {\n createdFrom.add(c.path);\n }\n\n const version = existingContent\n ? bumpPatchVersion(parseVersion(existingContent))\n : \"1.0.0\";\n\n const triggerTags = [\n group.primaryTagName,\n ...latest.tags.filter(\n (t) =>\n ![\"auto-capture\", \"claude-code\", \"cursor\", \"codebuddy\"].includes(t),\n ),\n ];\n\n const stepsBody =\n sections.steps.trim() ||\n group.captures\n .map((c) => parseProceduralSections(c).steps)\n .find((s) => s.trim()) ||\n \"(见来源捕获)\";\n\n const cautions =\n sections.cautions.trim() ||\n group.captures\n .map((c) => parseProceduralSections(c).cautions)\n .filter(Boolean)\n .join(\"\\n\") ||\n \"(无)\";\n\n const verification =\n sections.verification.trim() ||\n group.captures\n .map((c) => parseProceduralSections(c).verification)\n .filter(Boolean)\n .join(\"\\n\") ||\n \"(无)\";\n\n const cautionsBlock =\n cautions === \"(无)\"\n ? \"\"\n : `\\n## 常见陷阱\\n\\n${cautions.split(\"\\n\").map((l) => (l.startsWith(\"-\") ? l : `- ${l}`)).join(\"\\n\")}\\n`;\n\n const createdYaml = [...createdFrom]\n .map((p) => ` - ${p}`)\n .join(\"\\n\");\n\n return `---\nname: ${group.skillSlug}\ndescription: >\n ${description.replace(/\\n/g, \" \")}\nversion: ${version}\nauthor: @riconext/hermes-repo\nplatforms: [linux, macos]\ntrigger-tags: ${formatTagsYaml(triggerTags)}\ncreated-from:\n${createdYaml}\n---\n\n## 步骤\n\n${stepsBody}\n${cautionsBlock}\n## 验证\n\n${verification.split(\"\\n\").map((l) => (l.startsWith(\"-\") ? l : `- ${l}`)).join(\"\\n\")}\n`;\n}\n\nexport function readExistingSkill(skillPath: string): string | undefined {\n try {\n return readFileSync(skillPath, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nexport function skillBodyHash(content: string): string {\n const body = content.split(/^---\\s*$/m).slice(2).join(\"---\");\n return body.replace(/\\s+/g, \" \").trim().slice(0, 500);\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport interface ConsolidateState {\n version: 1;\n lastConsolidatedAt: string;\n processedCapturePaths: string[];\n}\n\nconst EMPTY_STATE: ConsolidateState = {\n version: 1,\n lastConsolidatedAt: new Date(0).toISOString(),\n processedCapturePaths: [],\n};\n\nexport function consolidateStatePath(repoRoot: string): string {\n return memoryPath(repoRoot, \"consolidate-state.json\");\n}\n\nexport function consolidateLockPath(repoRoot: string): string {\n return memoryPath(repoRoot, \".consolidate.lock\");\n}\n\nexport function readConsolidateState(repoRoot: string): ConsolidateState {\n const path = consolidateStatePath(repoRoot);\n if (!existsSync(path)) {\n return { ...EMPTY_STATE, processedCapturePaths: [] };\n }\n try {\n const raw = JSON.parse(readFileSync(path, \"utf8\")) as Partial<ConsolidateState>;\n if (raw.version !== 1) {\n return { ...EMPTY_STATE, processedCapturePaths: [] };\n }\n return {\n version: 1,\n lastConsolidatedAt:\n typeof raw.lastConsolidatedAt === \"string\"\n ? raw.lastConsolidatedAt\n : EMPTY_STATE.lastConsolidatedAt,\n processedCapturePaths: Array.isArray(raw.processedCapturePaths)\n ? raw.processedCapturePaths.filter((p) => typeof p === \"string\")\n : [],\n };\n } catch {\n return { ...EMPTY_STATE, processedCapturePaths: [] };\n }\n}\n\nexport function writeConsolidateState(\n repoRoot: string,\n state: ConsolidateState,\n): void {\n const path = consolidateStatePath(repoRoot);\n mkdirSync(memoryPath(repoRoot), { recursive: true });\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`, \"utf8\");\n}\n\nexport interface ConsolidateLock {\n pid: number;\n startedAt: string;\n}\n\nexport function readConsolidateLock(repoRoot: string): ConsolidateLock | null {\n const path = consolidateLockPath(repoRoot);\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as ConsolidateLock;\n } catch {\n return null;\n }\n}\n\nexport function writeConsolidateLock(repoRoot: string): void {\n const payload: ConsolidateLock = {\n pid: process.pid,\n startedAt: new Date().toISOString(),\n };\n mkdirSync(memoryPath(repoRoot), { recursive: true });\n writeFileSync(\n consolidateLockPath(repoRoot),\n `${JSON.stringify(payload, null, 2)}\\n`,\n \"utf8\",\n );\n}\n\nexport function releaseConsolidateLock(repoRoot: string): void {\n const path = consolidateLockPath(repoRoot);\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nexport function isLockStale(\n lock: ConsolidateLock,\n ttlMs: number,\n): boolean {\n const started = Date.parse(lock.startedAt);\n if (Number.isNaN(started)) {\n return true;\n }\n return Date.now() - started > ttlMs;\n}\n","import { listPendingJobs } from \"../capture/enqueueLlmJob.js\";\nimport {\n CONSOLIDATE_COUNT_THRESHOLD,\n CONSOLIDATE_HOURS_THRESHOLD,\n} from \"./constants.js\";\nimport { detectConflicts } from \"./detectConflict.js\";\nimport { filterActiveCaptures, listAllCaptures, selectNewCaptures } from \"./listCaptures.js\";\nimport { readConsolidateState } from \"./state.js\";\n\nexport interface ShouldConsolidateInput {\n repoRoot: string;\n force?: boolean;\n manual?: boolean;\n}\n\nexport interface ShouldConsolidateResult {\n shouldRun: boolean;\n reason?: string;\n newCaptureCount: number;\n hasConflict: boolean;\n deferredPendingLlm?: boolean;\n}\n\nexport function shouldRunConsolidate(\n input: ShouldConsolidateInput,\n): ShouldConsolidateResult {\n const { repoRoot, force, manual } = input;\n\n if (force || manual) {\n const all = filterActiveCaptures(listAllCaptures(repoRoot));\n return {\n shouldRun: all.length > 0 || force === true,\n reason: manual ? \"manual\" : \"force\",\n newCaptureCount: all.length,\n hasConflict: detectConflicts(all).length > 0,\n };\n }\n\n const pending = listPendingJobs(repoRoot);\n if (pending.length > 0) {\n return {\n shouldRun: false,\n reason: \"pending-llm-jobs\",\n newCaptureCount: 0,\n hasConflict: false,\n deferredPendingLlm: true,\n };\n }\n\n const state = readConsolidateState(repoRoot);\n const all = listAllCaptures(repoRoot);\n const active = filterActiveCaptures(all);\n const newOnes = selectNewCaptures(active, state.processedCapturePaths, false);\n\n if (detectConflicts(active).length > 0 && newOnes.length > 0) {\n return {\n shouldRun: true,\n reason: \"conflict\",\n newCaptureCount: newOnes.length,\n hasConflict: true,\n };\n }\n\n if (newOnes.length >= CONSOLIDATE_COUNT_THRESHOLD) {\n return {\n shouldRun: true,\n reason: \"count\",\n newCaptureCount: newOnes.length,\n hasConflict: false,\n };\n }\n\n const lastMs = Date.parse(state.lastConsolidatedAt);\n const hoursSince =\n Number.isNaN(lastMs) ? Infinity : (Date.now() - lastMs) / (1000 * 60 * 60);\n\n if (hoursSince >= CONSOLIDATE_HOURS_THRESHOLD && newOnes.length >= 1) {\n return {\n shouldRun: true,\n reason: \"time\",\n newCaptureCount: newOnes.length,\n hasConflict: false,\n };\n }\n\n return {\n shouldRun: false,\n newCaptureCount: newOnes.length,\n hasConflict: false,\n };\n}\n","import { debugLog } from \"../config/debugLog.js\";\nimport { effectiveLlmMode, isLlmAvailable } from \"../config/llmConfig.js\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\nimport { enqueueLlmJob } from \"./enqueueLlmJob.js\";\nimport { llmFormat, simpleFormat } from \"./formatCapture.js\";\nimport { needsLlm } from \"./needsLlm.js\";\nimport {\n appendSessionIndex,\n relativeCapturePath,\n} from \"./sessionsIndex.js\";\nimport type { CaptureResult } from \"./types.js\";\nimport { maybeScheduleConsolidate } from \"../consolidate/scheduleConsolidate.js\";\nimport { replaceCaptureFile, writeCaptureFile } from \"./writeCapture.js\";\nimport type { ParsedSession } from \"./types.js\";\n\nfunction finishCapture(\n repoRoot: string,\n debug: boolean | undefined,\n result: CaptureResult,\n): CaptureResult {\n if (result.written) {\n maybeScheduleConsolidate({ repoRoot, debug });\n }\n return result;\n}\n\nexport interface CommitCaptureOptions {\n repoRoot: string;\n session: ParsedSession;\n jsonlPath: string;\n assistant: AssistantId;\n dryRun?: boolean;\n debug?: boolean;\n}\n\nexport async function commitCapture(\n opts: CommitCaptureOptions,\n): Promise<CaptureResult> {\n const { repoRoot, session, jsonlPath, assistant, dryRun, debug } = opts;\n const formatted = simpleFormat(session, assistant);\n const type = formatted.type;\n\n if (dryRun) {\n debugLog(\n debug === true,\n \"capture\",\n `[dry-run] would capture ${type} session=${session.sessionId} from ${jsonlPath}`,\n );\n return { written: false, reason: \"dry-run\", jsonlPath };\n }\n\n const { filename } = writeCaptureFile(repoRoot, formatted);\n const captureFile = relativeCapturePath(type, filename);\n\n appendSessionIndex(repoRoot, {\n id: session.sessionId,\n capturedAt: new Date().toISOString(),\n captureFile,\n assistant,\n });\n\n const llm = readLlmConfigAtRepo(repoRoot);\n if (!isLlmAvailable(llm) || !needsLlm(session)) {\n debugLog(\n debug === true,\n \"capture\",\n `ok: ${captureFile} (format=simple)`,\n );\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n }\n\n const mode = effectiveLlmMode(llm!);\n if (mode === \"sync\") {\n const upgraded = await llmFormat(session, assistant, llm!);\n if (upgraded) {\n replaceCaptureFile(repoRoot, captureFile, upgraded);\n debugLog(debug === true, \"capture\", `ok: ${captureFile} (format=llm-sync)`);\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n }\n debugLog(\n debug === true,\n \"capture\",\n `ok: ${captureFile} (format=simple, llm-fallback)`,\n );\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n }\n\n const enqueued = enqueueLlmJob({\n repoRoot,\n sessionId: session.sessionId,\n jsonlPath,\n captureFile,\n assistant,\n debug,\n });\n if (enqueued) {\n debugLog(\n debug === true,\n \"capture\",\n `ok: ${captureFile} (format=simple, llm-enqueued)`,\n );\n } else {\n debugLog(\n debug === true,\n \"capture\",\n `ok: ${captureFile} (format=simple, llm-skip-enqueue)`,\n );\n }\n\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join, resolve } from \"node:path\";\n\n/** Claude Code:项目目录名 = 绝对路径将 `/` 替换为 `-`(见官方 ~/.claude/projects/) */\nexport function encodeClaudeProjectDir(absPath: string): string {\n return resolve(absPath).replace(/\\//g, \"-\");\n}\n\nexport interface ResolveSessionOptions {\n /** Claude Stop hook stdin JSON 的 transcript_path(官方首选) */\n transcriptPath?: string;\n cwd?: string;\n}\n\n/**\n * 解析 Claude Code 会话 JSONL 路径。\n * 依据 https://code.claude.com/docs/en/claude-directory#application-data\n *\n * 优先级:\n * 1. HERMES_SESSION_JSONL(测试 / 手动覆盖)\n * 2. transcriptPath(hook stdin 的 transcript_path)\n * 3. ~/.claude/projects/<encoded-cwd>/*.jsonl(当前仓库)\n * 4. 全局 projects 下最新 .jsonl(含旧版 sessions 子目录回退)\n */\nexport function resolveSessionJsonlPath(\n repoRoot: string,\n options: ResolveSessionOptions = {},\n): string | null {\n const override = process.env.HERMES_SESSION_JSONL;\n if (override && existsSync(override)) {\n return resolve(override);\n }\n\n const fromHook = options.transcriptPath;\n if (fromHook && existsSync(fromHook)) {\n return resolve(fromHook);\n }\n\n const sessionId =\n process.env.CLAUDE_SESSION_ID ??\n process.env.CLAUDE_CODE_SESSION_ID ??\n process.env.SESSION_ID;\n\n const claudeHome = process.env.CLAUDE_CONFIG_DIR\n ? resolve(process.env.CLAUDE_CONFIG_DIR)\n : join(homedir(), \".claude\");\n const projectsRoot = join(claudeHome, \"projects\");\n if (!existsSync(projectsRoot)) {\n return null;\n }\n\n const cwd = resolve(options.cwd ?? repoRoot);\n const preferredProjectDir = encodeClaudeProjectDir(cwd);\n const preferredPath = join(projectsRoot, preferredProjectDir);\n if (existsSync(preferredPath)) {\n const hit = pickNewestJsonl(preferredPath, sessionId);\n if (hit) {\n return hit;\n }\n const legacySessions = join(preferredPath, \"sessions\");\n if (existsSync(legacySessions)) {\n const legacyHit = pickNewestJsonl(legacySessions, sessionId);\n if (legacyHit) {\n return legacyHit;\n }\n }\n }\n\n const candidates: Array<{ path: string; mtime: number }> = [];\n\n for (const projectDir of readdirSync(projectsRoot, { withFileTypes: true })) {\n if (!projectDir.isDirectory()) continue;\n const projectPath = join(projectsRoot, projectDir.name);\n collectJsonlCandidates(projectPath, sessionId, candidates);\n const legacySessions = join(projectPath, \"sessions\");\n if (existsSync(legacySessions)) {\n collectJsonlCandidates(legacySessions, sessionId, candidates);\n }\n }\n\n if (candidates.length === 0) {\n return null;\n }\n\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\n/** @deprecated 使用 readHookInputSync;保留兼容测试与旧调用 */\nexport function readHookTranscriptPathSync(): string | null {\n if (process.stdin.isTTY) {\n return null;\n }\n try {\n const raw = readFileSync(0, \"utf8\").trim();\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw) as { transcript_path?: unknown };\n const p = parsed.transcript_path;\n if (typeof p === \"string\" && existsSync(p)) {\n return resolve(p);\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction pickNewestJsonl(\n dir: string,\n sessionId: string | undefined,\n): string | null {\n const candidates: Array<{ path: string; mtime: number }> = [];\n collectJsonlCandidates(dir, sessionId, candidates);\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction collectJsonlCandidates(\n dir: string,\n sessionId: string | undefined,\n out: Array<{ path: string; mtime: number }>,\n): void {\n if (!existsSync(dir)) {\n return;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n continue;\n }\n const fullPath = join(dir, entry.name);\n if (\n sessionId &&\n !entry.name.includes(sessionId) &&\n basename(entry.name, \".jsonl\") !== sessionId\n ) {\n continue;\n }\n try {\n const st = statSync(fullPath);\n out.push({ path: fullPath, mtime: st.mtimeMs });\n } catch {\n // skip\n }\n }\n}\n","import { commitCapture } from \"../commitCapture.js\";\nimport { shouldCapture } from \"../shouldCapture.js\";\nimport type { CaptureResult } from \"../types.js\";\nimport { parseJsonlFile } from \"./parseJsonl.js\";\nimport { resolveSessionJsonlPath } from \"./resolveSession.js\";\n\nexport async function runClaudeCodeCapture(\n repoRoot: string,\n cwd?: string,\n dryRun?: boolean,\n options?: { transcriptPath?: string; debug?: boolean },\n): Promise<CaptureResult> {\n const jsonlPath = resolveSessionJsonlPath(repoRoot, {\n cwd,\n transcriptPath: options?.transcriptPath,\n });\n if (!jsonlPath) {\n return { written: false, reason: \"no session jsonl found\" };\n }\n\n const session = parseJsonlFile(jsonlPath);\n if (!shouldCapture(session)) {\n return {\n written: false,\n reason: `heuristic rejected (messages=${session.messages.length}, toolCalls=${session.toolCalls})`,\n jsonlPath,\n };\n }\n\n return commitCapture({\n repoRoot,\n session,\n jsonlPath,\n assistant: \"claude-code\",\n dryRun,\n debug: options?.debug,\n });\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join, resolve } from \"node:path\";\n\n/**\n * CodeBuddy 项目目录名:绝对路径去掉 leading `/`,再将 `/` 换为 `-`。\n * 例:`/Users/you/proj` → `Users-you-proj`(与 Cursor 一致,非 Claude leading `-`)\n */\nexport function encodeCodebuddyProjectDir(absPath: string): string {\n return resolve(absPath).replace(/^\\//, \"\").replace(/\\//g, \"-\");\n}\n\nexport interface ResolveCodebuddySessionOptions {\n repoRoot: string;\n cwd?: string;\n transcriptPath?: string;\n}\n\n/**\n * 解析 CodeBuddy 会话 JSONL。\n *\n * 优先级:\n * 1. HERMES_CODEBUDDY_SESSION\n * 2. transcriptPath(hook stdin)\n * 3. ~/.codebuddy/projects/<encoded-cwd> 下最新 .jsonl(含子目录)\n */\nexport function resolveCodebuddySessionJsonl(\n options: ResolveCodebuddySessionOptions,\n): string | null {\n const override = process.env.HERMES_CODEBUDDY_SESSION;\n if (override && existsSync(override)) {\n return resolve(override);\n }\n\n const fromHook = options.transcriptPath;\n if (fromHook && existsSync(fromHook)) {\n return resolve(fromHook);\n }\n\n const sessionId =\n process.env.CODEBUDDY_SESSION_ID ?? process.env.SESSION_ID;\n\n const codebuddyHome = process.env.CODEBUDDY_CONFIG_DIR\n ? resolve(process.env.CODEBUDDY_CONFIG_DIR)\n : join(homedir(), \".codebuddy\");\n const projectsRoot = join(codebuddyHome, \"projects\");\n if (!existsSync(projectsRoot)) {\n return null;\n }\n\n const cwd = resolve(options.cwd ?? options.repoRoot);\n const preferredProjectDir = encodeCodebuddyProjectDir(cwd);\n const preferredPath = join(projectsRoot, preferredProjectDir);\n if (existsSync(preferredPath)) {\n const hit = pickNewestJsonlRecursive(preferredPath, sessionId);\n if (hit) {\n return hit;\n }\n }\n\n const candidates: Array<{ path: string; mtime: number }> = [];\n for (const projectDir of readdirSync(projectsRoot, { withFileTypes: true })) {\n if (!projectDir.isDirectory()) {\n continue;\n }\n collectJsonlRecursive(join(projectsRoot, projectDir.name), sessionId, candidates);\n }\n\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction pickNewestJsonlRecursive(\n dir: string,\n sessionId: string | undefined,\n): string | null {\n const candidates: Array<{ path: string; mtime: number }> = [];\n collectJsonlRecursive(dir, sessionId, candidates);\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction collectJsonlRecursive(\n dir: string,\n sessionId: string | undefined,\n out: Array<{ path: string; mtime: number }>,\n): void {\n if (!existsSync(dir)) {\n return;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n collectJsonlRecursive(full, sessionId, out);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n continue;\n }\n if (\n sessionId &&\n !entry.name.includes(sessionId) &&\n basename(entry.name, \".jsonl\") !== sessionId\n ) {\n continue;\n }\n try {\n const st = statSync(full);\n out.push({ path: full, mtime: st.mtimeMs });\n } catch {\n // skip\n }\n }\n}\n","import { commitCapture } from \"../commitCapture.js\";\nimport { shouldCapture } from \"../shouldCapture.js\";\nimport type { CaptureResult } from \"../types.js\";\nimport { parseJsonlFile } from \"../claude-code/parseJsonl.js\";\nimport { resolveCodebuddySessionJsonl } from \"./resolveSession.js\";\n\nexport async function runCodebuddyCapture(\n repoRoot: string,\n cwd?: string,\n dryRun?: boolean,\n options?: { transcriptPath?: string; debug?: boolean },\n): Promise<CaptureResult> {\n const jsonlPath = resolveCodebuddySessionJsonl({\n repoRoot,\n cwd,\n transcriptPath: options?.transcriptPath,\n });\n if (!jsonlPath) {\n return { written: false, reason: \"no codebuddy session found\" };\n }\n\n const session = parseJsonlFile(jsonlPath);\n if (!shouldCapture(session)) {\n return {\n written: false,\n reason: `heuristic rejected (messages=${session.messages.length}, toolCalls=${session.toolCalls})`,\n jsonlPath,\n };\n }\n\n return commitCapture({\n repoRoot,\n session,\n jsonlPath,\n assistant: \"codebuddy\",\n dryRun,\n debug: options?.debug,\n });\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { HookInput } from \"../hookInput.js\";\n\n/**\n * Cursor 项目目录名:绝对路径去掉 leading `/`,再将 `/` 换为 `-`。\n * 例:`/Users/you/proj` → `Users-you-proj`\n * (与 Claude `encodeClaudeProjectDir` 的 leading `-` 不同)\n */\nexport function encodeCursorProjectDir(absPath: string): string {\n return resolve(absPath).replace(/^\\//, \"\").replace(/\\//g, \"-\");\n}\n\nexport interface ResolveCursorSessionOptions {\n repoRoot: string;\n cwd?: string;\n hookInput?: HookInput | null;\n}\n\n/**\n * 解析 Cursor Agent 会话 JSONL。\n *\n * 优先级:\n * 1. HERMES_CURSOR_SESSION(测试 / 手动)\n * 2. hook session_id → ~/.cursor/projects/<encoded>/agent-transcripts/<id>/<id>.jsonl\n * 3. workspace_roots[0] 或 repoRoot 对应项目下最新 transcript\n */\nexport function resolveCursorSessionJsonl(\n options: ResolveCursorSessionOptions,\n): string | null {\n const override = process.env.HERMES_CURSOR_SESSION;\n if (override && existsSync(override)) {\n return resolve(override);\n }\n\n const cursorHome = process.env.CURSOR_CONFIG_DIR\n ? resolve(process.env.CURSOR_CONFIG_DIR)\n : join(homedir(), \".cursor\");\n const projectsRoot = join(cursorHome, \"projects\");\n if (!existsSync(projectsRoot)) {\n return null;\n }\n\n const sessionId =\n options.hookInput?.sessionId ??\n options.hookInput?.conversationId ??\n process.env.CURSOR_SESSION_ID ??\n process.env.CURSOR_AGENT_SESSION_ID;\n\n const workspace =\n options.hookInput?.workspaceRoots?.[0] ??\n (options.cwd ? resolve(options.cwd) : resolve(options.repoRoot));\n\n const encoded = encodeCursorProjectDir(workspace);\n const projectDir = join(projectsRoot, encoded);\n const transcriptsRoot = join(projectDir, \"agent-transcripts\");\n\n if (!existsSync(transcriptsRoot)) {\n return pickNewestCursorJsonl(projectsRoot);\n }\n\n if (sessionId) {\n const direct = join(transcriptsRoot, sessionId, `${sessionId}.jsonl`);\n if (existsSync(direct)) {\n return direct;\n }\n const nested = findJsonlUnderDir(join(transcriptsRoot, sessionId), sessionId);\n if (nested) {\n return nested;\n }\n }\n\n return pickNewestCursorJsonl(transcriptsRoot);\n}\n\nfunction findJsonlUnderDir(dir: string, sessionId: string): string | null {\n if (!existsSync(dir)) {\n return null;\n }\n const direct = join(dir, `${sessionId}.jsonl`);\n if (existsSync(direct)) {\n return direct;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isFile() && entry.name.endsWith(\".jsonl\")) {\n return join(dir, entry.name);\n }\n if (entry.isDirectory()) {\n const found = findJsonlUnderDir(join(dir, entry.name), sessionId);\n if (found) {\n return found;\n }\n }\n }\n return null;\n}\n\nfunction pickNewestCursorJsonl(root: string): string | null {\n const candidates: Array<{ path: string; mtime: number }> = [];\n collectJsonlRecursive(root, candidates);\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction collectJsonlRecursive(\n dir: string,\n out: Array<{ path: string; mtime: number }>,\n): void {\n if (!existsSync(dir)) {\n return;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n collectJsonlRecursive(full, out);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n continue;\n }\n try {\n const st = statSync(full);\n out.push({ path: full, mtime: st.mtimeMs });\n } catch {\n // skip\n }\n }\n}\n","import { commitCapture } from \"../commitCapture.js\";\nimport { shouldCapture } from \"../shouldCapture.js\";\nimport type { HookInput } from \"../hookInput.js\";\nimport type { CaptureResult } from \"../types.js\";\nimport { parseJsonlFile } from \"../claude-code/parseJsonl.js\";\nimport { resolveCursorSessionJsonl } from \"./resolveSession.js\";\n\nexport async function runCursorCapture(\n repoRoot: string,\n cwd?: string,\n dryRun?: boolean,\n options?: { hookInput?: HookInput | null; debug?: boolean },\n): Promise<CaptureResult> {\n if (\n options?.hookInput?.status === \"aborted\" &&\n !options.hookInput.sessionId\n ) {\n return { written: false, reason: \"cursor stop aborted\" };\n }\n\n const jsonlPath = resolveCursorSessionJsonl({\n repoRoot,\n cwd,\n hookInput: options?.hookInput,\n });\n if (!jsonlPath) {\n return { written: false, reason: \"no cursor session found\" };\n }\n\n const session = parseJsonlFile(jsonlPath);\n if (!shouldCapture(session)) {\n return {\n written: false,\n reason: `heuristic rejected (messages=${session.messages.length}, toolCalls=${session.toolCalls})`,\n jsonlPath,\n };\n }\n\n return commitCapture({\n repoRoot,\n session,\n jsonlPath,\n assistant: \"cursor\",\n dryRun,\n debug: options?.debug,\n });\n}\n","import type { RepoContext } from \"../config/types.js\";\nimport { runClaudeCodeCapture } from \"./claude-code/run.js\";\nimport { runCodebuddyCapture } from \"./codebuddy/run.js\";\nimport { runCursorCapture } from \"./cursor/run.js\";\nimport {\n isClaudeCaptureHook,\n isCodebuddyCaptureHook,\n isCursorCaptureHook,\n type HookInput,\n} from \"./hookInput.js\";\nimport type { CaptureResult } from \"./types.js\";\n\nexport async function routeCapture(\n ctx: RepoContext,\n options: {\n cwd?: string;\n dryRun?: boolean;\n transcriptPath?: string;\n hookInput?: HookInput | null;\n },\n): Promise<CaptureResult> {\n const assistants = ctx.config.assistants;\n const hasClaude = assistants.includes(\"claude-code\");\n const hasCursor = assistants.includes(\"cursor\");\n const hasCodebuddy = assistants.includes(\"codebuddy\");\n\n if (!hasClaude && !hasCursor && !hasCodebuddy) {\n return { written: false, reason: \"no capture assistant in config\" };\n }\n\n const hook = options.hookInput;\n const debug = ctx.config.debug === true;\n const codebuddyFromHook = isCodebuddyCaptureHook(hook);\n const claudeFromHook = isClaudeCaptureHook(hook);\n const cursorFromHook = isCursorCaptureHook(hook);\n\n if (codebuddyFromHook && hasCodebuddy) {\n return runCodebuddyCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n transcriptPath: hook?.transcriptPath ?? options.transcriptPath,\n debug,\n });\n }\n\n if (claudeFromHook && hasClaude) {\n return runClaudeCodeCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n transcriptPath: hook?.transcriptPath ?? options.transcriptPath,\n debug,\n });\n }\n\n if (cursorFromHook && hasCursor) {\n return runCursorCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n hookInput: hook,\n debug,\n });\n }\n\n if (hasClaude) {\n const claudeResult = await runClaudeCodeCapture(\n ctx.repoRoot,\n options.cwd,\n options.dryRun,\n {\n transcriptPath: options.transcriptPath,\n debug,\n },\n );\n if (claudeResult.written) {\n return claudeResult;\n }\n if (!hasCursor && !hasCodebuddy) {\n return claudeResult;\n }\n }\n\n if (hasCursor) {\n const cursorResult = await runCursorCapture(\n ctx.repoRoot,\n options.cwd,\n options.dryRun,\n {\n hookInput: hook,\n debug,\n },\n );\n if (cursorResult.written) {\n return cursorResult;\n }\n if (!hasCodebuddy) {\n return cursorResult;\n }\n }\n\n if (hasCodebuddy) {\n return runCodebuddyCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n transcriptPath: options.transcriptPath,\n debug,\n });\n }\n\n return { written: false, reason: \"no capture assistant in config\" };\n}\n","import { debugLog } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport type { HookInput } from \"./hookInput.js\";\nimport { routeCapture } from \"./router.js\";\nimport type { CaptureResult } from \"./types.js\";\n\nexport interface CaptureOptions {\n cwd?: string;\n dryRun?: boolean;\n strict?: boolean;\n /** Claude Stop hook stdin 中的 transcript_path(兼容旧调用) */\n transcriptPath?: string;\n hookInput?: HookInput | null;\n}\n\nfunction logCaptureResult(debug: boolean, result: CaptureResult): void {\n if (!debug) {\n return;\n }\n if (result.written && result.capturePath) {\n debugLog(true, \"capture\", `ok: ${result.capturePath}`);\n return;\n }\n const parts = [result.reason ?? \"unknown\"];\n if (result.jsonlPath) {\n parts.push(`jsonl=${result.jsonlPath}`);\n }\n debugLog(true, \"capture\", `skip: ${parts.join(\", \")}`);\n}\n\nexport async function runCapture(\n options: CaptureOptions = {},\n): Promise<CaptureResult> {\n const ctx = loadRepoContext(options.cwd);\n if (!ctx) {\n return { written: false, reason: \"not initialized\" };\n }\n\n const result = await routeCapture(ctx, {\n cwd: options.cwd,\n dryRun: options.dryRun,\n transcriptPath: options.transcriptPath,\n hookInput: options.hookInput,\n });\n logCaptureResult(ctx.config.debug, result);\n return result;\n}\n","import { readHookInputSync, isCodebuddyCaptureHook } from \"../capture/hookInput.js\";\nimport { runCapture } from \"../capture/runCapture.js\";\nimport { configureDebugLogging, debugLog } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { finalizeHookCommand } from \"../hookExit.js\";\n\nexport interface CaptureCommandOptions {\n cwd?: string;\n dryRun?: boolean;\n strict?: boolean;\n}\n\nexport function runCaptureCommand(opts: CaptureCommandOptions): void {\n const ctx = loadRepoContext(opts.cwd);\n const debug = ctx?.config.debug === true;\n configureDebugLogging(ctx?.repoRoot ?? null, debug);\n const hookInput = readHookInputSync();\n\n if (hookInput && isCodebuddyCaptureHook(hookInput)) {\n const stdinPath =\n hookInput.transcriptPathRaw ??\n hookInput.transcriptPath ??\n \"(missing)\";\n debugLog(\n debug,\n \"capture\",\n `codebuddy stop stdin transcript_path=${stdinPath}`,\n );\n }\n\n finalizeHookCommand(async () => {\n await runCapture({\n cwd: opts.cwd,\n dryRun: opts.dryRun,\n strict: opts.strict,\n hookInput,\n transcriptPath: hookInput?.transcriptPath,\n });\n }, opts.strict, debug);\n}\n","import { hookExit } from \"../hookExit.js\";\nimport { runFlushCommand } from \"../consolidate/scheduleConsolidate.js\";\n\nexport async function runFlushCommandCli(opts: {\n cwd?: string;\n force?: boolean;\n dryRun?: boolean;\n strict?: boolean;\n}): Promise<void> {\n try {\n const result = await runFlushCommand({\n cwd: opts.cwd,\n force: opts.force,\n dryRun: opts.dryRun,\n });\n\n if (result.ran && result.memoryUpdated) {\n const extra: string[] = [];\n if (result.refsAggregated > 0) {\n extra.push(`${result.refsAggregated} ref(s) aggregated`);\n }\n if (result.archived > 0) {\n extra.push(`${result.archived} archived`);\n }\n const suffix = extra.length > 0 ? `, ${extra.join(\", \")}` : \"\";\n console.error(\n `hermes-repo: consolidated ${result.newProcessed} capture(s), ${result.topicsWritten} topic(s), ${result.skillsWritten} skill(s)${suffix}`,\n );\n } else if (result.ran && result.reason === \"dry-run\") {\n console.error(\n `hermes-repo: dry-run would process ${result.newProcessed} capture(s)`,\n );\n }\n\n hookExit(0, opts.strict);\n } catch (err) {\n console.error(\n `hermes-repo flush: ${err instanceof Error ? err.message : String(err)}`,\n );\n hookExit(1, opts.strict);\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { debugFromContext } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { INJECT_MAX_CHARS } from \"./constants.js\";\n\nexport function runInject(\n cwd?: string,\n options?: { cursorHookOutput?: boolean },\n): { injected: boolean; chars: number } {\n const ctx = loadRepoContext(cwd);\n if (!ctx) {\n return { injected: false, chars: 0 };\n }\n\n const memoryFile = memoryPathOnDisk(ctx.repoRoot);\n if (!existsSync(memoryFile)) {\n debugFromContext(ctx, \"inject\", \"skip: MEMORY.md missing\");\n return { injected: false, chars: 0 };\n }\n\n const contentRaw = readFileSync(memoryFile, \"utf8\");\n if (!contentRaw.trim()) {\n debugFromContext(ctx, \"inject\", \"skip: MEMORY.md empty\");\n return { injected: false, chars: 0 };\n }\n\n let content = contentRaw;\n if (content.length > INJECT_MAX_CHARS) {\n content = `${content.slice(0, INJECT_MAX_CHARS)}\\n\\n...(truncated)`;\n }\n\n if (options?.cursorHookOutput) {\n process.stdout.write(\n `${JSON.stringify({ additional_context: content })}\\n`,\n );\n } else {\n process.stdout.write(content);\n if (!content.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n }\n\n debugFromContext(ctx, \"inject\", `ok: injected ${content.length} chars`);\n\n return { injected: true, chars: content.length };\n}\n\nfunction memoryPathOnDisk(repoRoot: string): string {\n return memoryPath(repoRoot, \"MEMORY.md\");\n}\n","import { isCursorInjectHook, readHookInputSync } from \"../capture/hookInput.js\";\nimport { configureDebugLogging } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { finalizeHookCommand } from \"../hookExit.js\";\nimport { runInject } from \"../inject/runInject.js\";\n\nexport interface InjectCommandOptions {\n cwd?: string;\n strict?: boolean;\n}\n\nexport function runInjectCommand(opts: InjectCommandOptions): void {\n const ctx = loadRepoContext(opts.cwd);\n const debug = ctx?.config.debug === true;\n configureDebugLogging(ctx?.repoRoot ?? null, debug);\n\n const hookInput = readHookInputSync();\n const cursorHookOutput = isCursorInjectHook(hookInput);\n\n finalizeHookCommand(() => {\n runInject(opts.cwd, { cursorHookOutput });\n }, opts.strict, debug);\n}\n","import { spawnSync } from \"node:child_process\";\nimport { resolve } from \"node:path\";\nimport {\n DEFAULT_ASSISTANT_IDS,\n parseToolsArg,\n validateAssistantSelection,\n} from \"./assistants/registry.js\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport { ensureMemoryTree } from \"./ensureDirs.js\";\nimport { mergeAssistants } from \"./mergeAssistants.js\";\nimport { mergeHermesGitignore } from \"./mergeGitignore.js\";\nimport { withSpinnerProgress } from \"../cli/spinner.js\";\nimport { runConsolidate } from \"../consolidate/runConsolidate.js\";\nimport { runProjectScan } from \"../coldstart/runProjectScan.js\";\nimport { gatherInitOptions } from \"./prompts.js\";\nimport type { InitCliOptions, InitReport, InitResolvedOptions } from \"./types.js\";\nimport { writeScaffoldFiles } from \"./writeScaffoldFile.js\";\n\nexport function resolveTargetDir(cwd?: string): string {\n const targetDir = resolve(cwd ?? process.cwd());\n const gitCheck = spawnSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd: targetDir,\n encoding: \"utf8\",\n });\n if (gitCheck.status !== 0) {\n console.warn(\n \"warn: 当前目录可能不是 Git 仓库,init 仍会继续(建议在有 git 的项目根目录执行)\",\n );\n }\n return targetDir;\n}\n\nfunction resolveSelectedAssistants(opts: InitCliOptions): AssistantId[] {\n if (opts.assistants) {\n validateAssistantSelection(opts.assistants);\n return opts.assistants;\n }\n if (opts.tools) {\n if (!opts.yes) {\n console.error(\"init --tools requires -y in non-interactive mode\");\n process.exit(1);\n }\n return parseToolsArg(opts.tools);\n }\n if (opts.yes) {\n return [...DEFAULT_ASSISTANT_IDS];\n }\n return [];\n}\n\nexport type PrintInitReportOptions = {\n /** 是否打印冷启动摘要(默认 true;脚手架报告应传 false) */\n includeBootstrap?: boolean;\n /** 仅打印从该下标起的 warnings(用于冷启动后的增量 warn) */\n warningsFromIndex?: number;\n};\n\nexport function printInitReport(\n report: InitReport,\n opts: PrintInitReportOptions = {},\n): void {\n const includeBootstrap = opts.includeBootstrap !== false;\n const warnStart = opts.warningsFromIndex ?? 0;\n const created = report.files.filter((f) => f.action === \"created\");\n const skipped = report.files.filter((f) => f.action === \"skipped\");\n const overwritten = report.files.filter((f) => f.action === \"overwritten\");\n const appended = report.files.filter((f) => f.action === \"appended\");\n const replaced = report.files.filter((f) => f.action === \"replaced\");\n\n if (warnStart === 0) {\n console.log(`\\nhermes-repo init 完成 → ${report.targetDir}\\n`);\n console.log(`已启用助手: ${report.assistants.join(\", \")}\\n`);\n\n if (created.length > 0) {\n console.log(`已创建 (${created.length}):`);\n for (const f of created) {\n console.log(` + ${f.path}`);\n }\n }\n\n if (overwritten.length > 0) {\n console.log(`已覆盖 (${overwritten.length}):`);\n for (const f of overwritten) {\n console.log(` ~ ${f.path}`);\n }\n }\n\n if (appended.length > 0) {\n console.log(`已追加 (${appended.length}):`);\n for (const f of appended) {\n console.log(` + ${f.path}`);\n }\n }\n\n if (replaced.length > 0) {\n console.log(`已刷新 hermes 块 (${replaced.length}):`);\n for (const f of replaced) {\n console.log(` ↻ ${f.path}`);\n }\n }\n\n if (skipped.length > 0) {\n console.log(`已跳过 (${skipped.length}):`);\n for (const f of skipped) {\n console.log(` - ${f.path}`);\n }\n }\n\n if (report.gitignoreAction) {\n console.log(`\\n.gitignore: ${report.gitignoreAction} hermes-repo 标记块`);\n }\n\n const llmFile = report.files.find((f) => f.path === \".memory/llm.json\");\n if (llmFile && llmFile.action !== \"skipped\") {\n console.warn(\n \"warn: .memory/llm.json 含 API 密钥,已被 .gitignore 忽略,请勿取消忽略或提交到 Git\",\n );\n }\n }\n\n if (\n includeBootstrap &&\n report.bootstrapCapturesWritten !== undefined &&\n report.bootstrapCapturesWritten > 0\n ) {\n console.log(\n `\\n冷启动: 已生成 ${report.bootstrapCapturesWritten} 条 bootstrap 语义记忆`,\n );\n if (report.memoryBootstrapped) {\n console.log(\"冷启动: 已更新 .memory/MEMORY.md(consolidate)\");\n }\n }\n\n for (const warning of report.warnings.slice(warnStart)) {\n console.warn(`warn: ${warning}`);\n }\n\n if (warnStart === 0) {\n console.log(\"\");\n }\n}\n\nasync function runBootstrapFromScan(\n targetDir: string,\n report: InitReport,\n): Promise<void> {\n try {\n const scanResult = await withSpinnerProgress(\n \"正在扫描项目并生成首批语义记忆(package.json、Git、约定文件)…\",\n () => runProjectScan(targetDir),\n (r) =>\n r.skipped\n ? {\n message: \"扫描完成,未发现可写入的语义捕获\",\n status: \"warn\",\n }\n : {\n message: `已写入 ${r.capturesWritten} 条语义捕获`,\n status: \"success\",\n },\n );\n for (const w of scanResult.warnings) {\n report.warnings.push(w);\n }\n if (scanResult.skipped) {\n report.warnings.push(\"项目扫描未生成记忆(无可用信号)\");\n } else {\n report.bootstrapCapturesWritten = scanResult.capturesWritten;\n try {\n const flushResult = await withSpinnerProgress(\n \"正在整理 MEMORY.md(consolidate)…\",\n () =>\n runConsolidate({\n repoRoot: targetDir,\n manual: true,\n }),\n (r) =>\n r.memoryUpdated\n ? { message: \"冷启动完成\", status: \"success\" }\n : {\n message: `consolidate 未更新 MEMORY: ${r.reason ?? \"unknown\"}`,\n status: \"warn\",\n },\n );\n report.memoryBootstrapped = flushResult.memoryUpdated;\n if (!flushResult.memoryUpdated) {\n report.warnings.push(\n `consolidate 未更新 MEMORY: ${flushResult.reason ?? \"unknown\"}`,\n );\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n report.warnings.push(`consolidate 失败: ${msg}`);\n }\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n report.warnings.push(`项目扫描失败: ${msg}`);\n }\n}\n\nexport async function runInit(opts: InitCliOptions): Promise<InitReport> {\n if (!process.stdin.isTTY && !opts.yes) {\n console.error(\"init requires -y in non-interactive environments\");\n process.exit(1);\n }\n\n if (opts.tools && !opts.yes) {\n console.error(\"init --tools requires -y\");\n process.exit(1);\n }\n\n let resolved: InitResolvedOptions;\n\n if (opts.yes) {\n const targetDir = resolveTargetDir(opts.cwd);\n const selected = resolveSelectedAssistants(opts);\n resolved = {\n targetDir,\n force: Boolean(opts.force),\n includeExampleTemplates: opts.includeExampleTemplates ?? true,\n assistants: mergeAssistants(targetDir, selected),\n cancelled: false,\n llm: { enabled: false },\n writeLlmJson: true,\n bootstrapFromScan: opts.scan === true,\n };\n } else {\n const gathered = await gatherInitOptions(opts);\n if (gathered.cancelled) {\n console.log(\"init 已取消\");\n process.exit(0);\n }\n resolved = {\n ...gathered,\n assistants: mergeAssistants(gathered.targetDir, gathered.assistants),\n };\n }\n\n const report: InitReport = {\n targetDir: resolved.targetDir,\n assistants: resolved.assistants,\n files: [],\n warnings: [],\n };\n\n ensureMemoryTree(resolved.targetDir);\n writeScaffoldFiles(resolved.targetDir, resolved, report);\n\n const gitignore = mergeHermesGitignore(resolved.targetDir);\n report.gitignoreAction = gitignore.action;\n if (gitignore.warnBroadMemoryIgnore) {\n report.warnings.push(\n \".gitignore 中存在对整个 .memory/ 的忽略规则,可能与团队层放行冲突,请手动检查\",\n );\n }\n\n printInitReport(report, { includeBootstrap: false });\n\n if (resolved.bootstrapFromScan) {\n const warningsBeforeBootstrap = report.warnings.length;\n await runBootstrapFromScan(resolved.targetDir, report);\n printInitReport(report, {\n includeBootstrap: true,\n warningsFromIndex: warningsBeforeBootstrap,\n });\n console.log(\"\");\n }\n\n return report;\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CLAUDE_SETTINGS_LOCAL_REL,\n claudeSettingsLocalPath,\n mergeClaudeLocalSettings,\n} from \"../mergeClaudeSettings.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const claudeCodeAdapter: AssistantAdapter = {\n id: \"claude-code\",\n label: \"Claude Code(Stop / SessionStart hooks)\",\n available: true,\n scaffoldPaths: [CLAUDE_SETTINGS_LOCAL_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".claude\"), { recursive: true });\n const { content, action } = mergeClaudeLocalSettings(ctx.repoRoot);\n writeFileSync(claudeSettingsLocalPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CLAUDE_SETTINGS_LOCAL_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { renderTemplate } from \"./templateDir.js\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CLAUDE_SETTINGS_LOCAL_REL = \".claude/settings.local.json\";\n\nexport function claudeSettingsLocalPath(repoRoot: string): string {\n return join(repoRoot, \".claude\", \"settings.local.json\");\n}\n\ntype HookHandlers = { hooks: { type: string; command: string }[] }[];\n\n/** 每次 init 合并 hermes 管理的 Stop / SessionStart 到 Claude local settings */\nexport function mergeClaudeLocalSettings(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const settingsPath = claudeSettingsLocalPath(repoRoot);\n const existed = existsSync(settingsPath);\n\n const templateParsed = JSON.parse(renderTemplate(\"hooks.json.tpl\")) as {\n hooks: {\n Stop: HookHandlers;\n SessionStart: HookHandlers;\n };\n };\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevHooks =\n existing.hooks &&\n typeof existing.hooks === \"object\" &&\n !Array.isArray(existing.hooks)\n ? (existing.hooks as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n hooks: {\n ...prevHooks,\n Stop: templateParsed.hooks.Stop,\n SessionStart: templateParsed.hooks.SessionStart,\n },\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { PACKAGE_NAME } from \"../index.js\";\n\nfunction resolveTemplateDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, \"templates\"),\n join(here, \"..\", \"..\", \"templates\"),\n ];\n for (const dir of candidates) {\n if (existsSync(dir)) {\n return dir;\n }\n }\n return join(here, \"templates\");\n}\n\nconst templateDir = resolveTemplateDir();\n\nexport function resolveTemplatePath(name: string): string {\n return join(templateDir, name);\n}\n\nexport function readTemplate(name: string): string {\n return readFileSync(resolveTemplatePath(name), \"utf8\");\n}\n\nexport function renderTemplate(name: string): string {\n const raw = readTemplate(name);\n return raw.replaceAll(\"__PACKAGE_NAME__\", PACKAGE_NAME);\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport const PACKAGE_NAME = \"@riconext/hermes-repo\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport function readPkgVersion(): string {\n const pkgPath = join(__dirname, \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { version: string };\n return pkg.version;\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CODEX_CONFIG_REL,\n codexConfigPath,\n mergeCodexConfig,\n} from \"../mergeCodexConfig.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const codexAdapter: AssistantAdapter = {\n id: \"codex\",\n label: \"OpenAI Codex(AGENTS.md + .codex/config.toml)\",\n available: true,\n scaffoldPaths: [CODEX_CONFIG_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".codex\"), { recursive: true });\n const { content, action } = mergeCodexConfig(ctx.repoRoot);\n writeFileSync(codexConfigPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CODEX_CONFIG_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CODEX_CONFIG_REL = \".codex/config.toml\";\n\nconst CODEX_HERMES_START_MARKER =\n \"# >>> hermes-repo codex (do not edit this block manually)\";\nconst CODEX_HERMES_END_MARKER = \"# <<< hermes-repo codex\";\n\nfunction buildCodexHermesBlock(): string {\n return [\n CODEX_HERMES_START_MARKER,\n \"# Hermes uses AGENTS.md as the shared Codex project guidance entry.\",\n \"# Run `npx @riconext/hermes-repo search <keyword>` to inspect project memory.\",\n \"# Run `npx @riconext/hermes-repo ref --capture <path> --reason \\\"...\\\"` after using memory.\",\n CODEX_HERMES_END_MARKER,\n ].join(\"\\n\");\n}\n\nexport function codexConfigPath(repoRoot: string): string {\n return join(repoRoot, \".codex\", \"config.toml\");\n}\n\nfunction spliceHermesBlock(existing: string, block: string): string {\n const startIdx = existing.indexOf(CODEX_HERMES_START_MARKER);\n const endIdx = existing.indexOf(CODEX_HERMES_END_MARKER);\n\n if (startIdx >= 0 && endIdx >= startIdx) {\n const before = existing.slice(0, startIdx).trimEnd();\n const after = existing.slice(endIdx + CODEX_HERMES_END_MARKER.length).trimStart();\n return `${before ? `${before}\\n\\n` : \"\"}${block}${after ? `\\n\\n${after}` : \"\"}\\n`;\n }\n\n const trimmed = existing.trimEnd();\n return `${trimmed ? `${trimmed}\\n\\n` : \"\"}${block}\\n`;\n}\n\n/** Codex project config is preserved; init only manages a commented Hermes marker block. */\nexport function mergeCodexConfig(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const configPath = codexConfigPath(repoRoot);\n const existed = existsSync(configPath);\n const block = buildCodexHermesBlock();\n\n if (!existed) {\n return {\n content: `${block}\\n`,\n action: \"created\",\n };\n }\n\n const existing = readFileSync(configPath, \"utf8\");\n const hasBlock =\n existing.includes(CODEX_HERMES_START_MARKER) &&\n existing.includes(CODEX_HERMES_END_MARKER);\n\n return {\n content: spliceHermesBlock(existing, block),\n action: hasBlock ? \"replaced\" : \"appended\",\n };\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CODEBUDDY_SETTINGS_LOCAL_REL,\n codebuddySettingsLocalPath,\n mergeCodebuddyLocalSettings,\n} from \"../mergeCodebuddySettings.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const codebuddyAdapter: AssistantAdapter = {\n id: \"codebuddy\",\n label: \"CodeBuddy(CLI)\",\n available: true,\n scaffoldPaths: [CODEBUDDY_SETTINGS_LOCAL_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".codebuddy\"), { recursive: true });\n const { content, action } = mergeCodebuddyLocalSettings(ctx.repoRoot);\n writeFileSync(codebuddySettingsLocalPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CODEBUDDY_SETTINGS_LOCAL_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { renderTemplate } from \"./templateDir.js\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CODEBUDDY_SETTINGS_LOCAL_REL = \".codebuddy/settings.local.json\";\n\nexport function codebuddySettingsLocalPath(repoRoot: string): string {\n return join(repoRoot, \".codebuddy\", \"settings.local.json\");\n}\n\ntype HookHandlers = { hooks: { type: string; command: string }[] }[];\n\n/** 每次 init 合并 hermes 管理的 Stop / SessionStart 到 CodeBuddy local settings */\nexport function mergeCodebuddyLocalSettings(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const settingsPath = codebuddySettingsLocalPath(repoRoot);\n const existed = existsSync(settingsPath);\n\n const templateParsed = JSON.parse(\n renderTemplate(\"hooks.codebuddy.json.tpl\"),\n ) as {\n hooks: {\n Stop: HookHandlers;\n SessionStart: HookHandlers;\n };\n };\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevHooks =\n existing.hooks &&\n typeof existing.hooks === \"object\" &&\n !Array.isArray(existing.hooks)\n ? (existing.hooks as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n hooks: {\n ...prevHooks,\n Stop: templateParsed.hooks.Stop,\n SessionStart: templateParsed.hooks.SessionStart,\n },\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CURSOR_HOOKS_REL,\n cursorHooksPath,\n mergeCursorHooks,\n} from \"../mergeCursorHooks.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const cursorAdapter: AssistantAdapter = {\n id: \"cursor\",\n label: \"Cursor(sessionStart / stop hooks)\",\n available: true,\n scaffoldPaths: [CURSOR_HOOKS_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".cursor\"), { recursive: true });\n const { content, action } = mergeCursorHooks(ctx.repoRoot);\n writeFileSync(cursorHooksPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CURSOR_HOOKS_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { renderTemplate } from \"./templateDir.js\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CURSOR_HOOKS_REL = \".cursor/hooks.json\";\n\nexport function cursorHooksPath(repoRoot: string): string {\n return join(repoRoot, \".cursor\", \"hooks.json\");\n}\n\ntype CursorHookEntry = { command: string };\n\n/** 每次 init 合并 hermes 管理的 sessionStart / stop 到 .cursor/hooks.json */\nexport function mergeCursorHooks(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const hooksPath = cursorHooksPath(repoRoot);\n const existed = existsSync(hooksPath);\n\n const templateParsed = JSON.parse(renderTemplate(\"hooks.cursor.json.tpl\")) as {\n version: number;\n hooks: {\n sessionStart: CursorHookEntry[];\n stop: CursorHookEntry[];\n };\n };\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(hooksPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevHooks =\n existing.hooks &&\n typeof existing.hooks === \"object\" &&\n !Array.isArray(existing.hooks)\n ? (existing.hooks as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n version: templateParsed.version,\n hooks: {\n ...prevHooks,\n sessionStart: templateParsed.hooks.sessionStart,\n stop: templateParsed.hooks.stop,\n },\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import type { AssistantAdapter, AssistantId } from \"./types.js\";\nimport { claudeCodeAdapter } from \"./claude-code.js\";\nimport { codexAdapter } from \"./codex.js\";\nimport { codebuddyAdapter } from \"./codebuddy.js\";\nimport { cursorAdapter } from \"./cursor.js\";\n\nexport const DEFAULT_ASSISTANT_IDS: AssistantId[] = [\"claude-code\"];\n\nconst ALL_ADAPTERS: AssistantAdapter[] = [\n claudeCodeAdapter,\n cursorAdapter,\n codebuddyAdapter,\n codexAdapter,\n];\n\nconst ADAPTER_BY_ID = new Map<AssistantId, AssistantAdapter>(\n ALL_ADAPTERS.map((a) => [a.id, a]),\n);\n\nexport function getAdapter(id: AssistantId): AssistantAdapter {\n const adapter = ADAPTER_BY_ID.get(id);\n if (!adapter) {\n throw new Error(`Unknown assistant id: ${id}`);\n }\n return adapter;\n}\n\nexport function listAvailable(): AssistantAdapter[] {\n return ALL_ADAPTERS.filter((a) => a.available);\n}\n\nexport function isKnownAssistantId(id: string): id is AssistantId {\n return ADAPTER_BY_ID.has(id as AssistantId);\n}\n\nexport function parseToolsArg(tools: string): AssistantId[] {\n const ids = tools\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n if (ids.length === 0) {\n throw new Error(\"init --tools requires at least one assistant id\");\n }\n\n const result: AssistantId[] = [];\n for (const id of ids) {\n if (!isKnownAssistantId(id)) {\n throw new Error(`Unknown assistant id: ${id}`);\n }\n const adapter = getAdapter(id);\n if (!adapter.available) {\n throw new Error(`Assistant not available yet: ${id}`);\n }\n result.push(id);\n }\n return result;\n}\n\nexport function validateAssistantSelection(ids: AssistantId[]): void {\n if (ids.length === 0) {\n throw new Error(\"At least one assistant must be selected\");\n }\n for (const id of ids) {\n const adapter = getAdapter(id);\n if (!adapter.available) {\n throw new Error(`Assistant not available yet: ${id}`);\n }\n }\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { GITKEEP_DIRS, MEMORY_DIR, MEMORY_SUBDIRS } from \"./paths.js\";\n\nexport function ensureMemoryTree(repoRoot: string): void {\n const memoryRoot = join(repoRoot, MEMORY_DIR);\n mkdirSync(memoryRoot, { recursive: true });\n\n for (const sub of MEMORY_SUBDIRS) {\n mkdirSync(join(memoryRoot, sub), { recursive: true });\n }\n\n mkdirSync(join(repoRoot, \".claude\"), { recursive: true });\n\n for (const sub of GITKEEP_DIRS) {\n const keepPath = join(memoryRoot, sub, \".gitkeep\");\n writeFileSync(keepPath, \"\", { flag: \"a\" });\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport { memoryPath } from \"./paths.js\";\n\nfunction readExistingAssistants(repoRoot: string): AssistantId[] {\n const configPath = memoryPath(repoRoot, \"config.json\");\n if (!existsSync(configPath)) {\n return [];\n }\n try {\n const config = JSON.parse(readFileSync(configPath, \"utf8\")) as {\n assistants?: unknown;\n };\n if (!Array.isArray(config.assistants)) {\n return [];\n }\n return config.assistants.filter((id): id is AssistantId => typeof id === \"string\");\n } catch {\n return [];\n }\n}\n\n/** 与已有 config.assistants 做并集(保留已有 id + 追加本次选择) */\nexport function mergeAssistants(\n repoRoot: string,\n selected: AssistantId[],\n): AssistantId[] {\n const existing = readExistingAssistants(repoRoot);\n return [...new Set([...existing, ...selected])];\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readTemplate } from \"./templateDir.js\";\n\nconst START_MARKER = \"# >>> hermes-repo memory (do not edit this block manually)\";\nconst END_MARKER = \"# <<< hermes-repo memory\";\n\nexport type GitignoreMergeAction = \"created\" | \"updated\" | \"replaced\" | \"appended\";\n\nexport function mergeHermesGitignore(repoRoot: string): {\n action: GitignoreMergeAction;\n warnBroadMemoryIgnore: boolean;\n} {\n const block = readTemplate(\"gitignore-block.txt\").trimEnd() + \"\\n\";\n const gitignorePath = join(repoRoot, \".gitignore\");\n const contentBefore = existsSync(gitignorePath)\n ? readFileSync(gitignorePath, \"utf8\")\n : \"\";\n\n const warnBroadMemoryIgnore =\n contentBefore.length > 0 &&\n !contentBefore.includes(START_MARKER) &&\n /(^|\\n)\\.memory\\/\\s*$/m.test(contentBefore);\n\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, `${block}\\n`, \"utf8\");\n return { action: \"created\", warnBroadMemoryIgnore: false };\n }\n\n const startIdx = contentBefore.indexOf(START_MARKER);\n const endIdx = contentBefore.indexOf(END_MARKER);\n\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = contentBefore.slice(0, startIdx);\n const after = contentBefore.slice(endIdx + END_MARKER.length);\n const next = `${before}${block}${after}`.replace(/\\n{3,}/g, \"\\n\\n\");\n writeFileSync(gitignorePath, next.endsWith(\"\\n\") ? next : `${next}\\n`, \"utf8\");\n return { action: \"replaced\", warnBroadMemoryIgnore };\n }\n\n if (startIdx !== -1) {\n const before = contentBefore.slice(0, startIdx);\n const next = `${before}${block}\\n`;\n writeFileSync(gitignorePath, next, \"utf8\");\n return { action: \"updated\", warnBroadMemoryIgnore };\n }\n\n const separator = contentBefore.endsWith(\"\\n\") || contentBefore.length === 0 ? \"\\n\" : \"\\n\\n\";\n writeFileSync(gitignorePath, `${contentBefore}${separator}${block}\\n`, \"utf8\");\n return { action: \"appended\", warnBroadMemoryIgnore };\n}\n","import type { Writable } from \"node:stream\";\n\nconst PREFIX = \"hermes-repo: \";\nconst FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"] as const;\nconst TICK_MS = 80;\n\nexport type SpinnerStatus = \"success\" | \"warn\" | \"fail\";\n\nconst STATUS_MARK: Record<SpinnerStatus, string> = {\n success: \"✓\",\n warn: \"!\",\n fail: \"✗\",\n};\n\nfunction isInteractive(stream: Writable): boolean {\n return \"isTTY\" in stream && stream.isTTY === true;\n}\n\nexport class CliSpinner {\n private frame = 0;\n private timer: ReturnType<typeof setInterval> | undefined;\n private readonly interactive: boolean;\n\n constructor(\n private label: string,\n private readonly stream: Writable = process.stderr,\n ) {\n this.interactive = isInteractive(stream);\n }\n\n start(): void {\n if (!this.interactive) {\n console.error(`${PREFIX}${this.label}`);\n return;\n }\n this.renderFrame();\n this.timer = setInterval(() => this.renderFrame(), TICK_MS);\n }\n\n stop(message: string, status: SpinnerStatus = \"success\"): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n const mark = STATUS_MARK[status];\n if (this.interactive) {\n const line = `${PREFIX}${mark} ${message}`;\n this.stream.write(`\\r\\x1b[K${line}\\n`);\n } else if (message !== this.label) {\n console.error(`${PREFIX}${message}`);\n }\n }\n\n private renderFrame(): void {\n const frame = FRAMES[this.frame++ % FRAMES.length];\n this.stream.write(`\\r\\x1b[K${PREFIX}${frame} ${this.label}`);\n }\n}\n\nexport async function withSpinnerProgress<T>(\n label: string,\n fn: () => T | Promise<T>,\n formatDone: (result: T) => { message: string; status?: SpinnerStatus },\n stream: Writable = process.stderr,\n): Promise<T> {\n const spinner = new CliSpinner(label, stream);\n spinner.start();\n try {\n const result = await fn();\n const { message, status = \"success\" } = formatDone(result);\n spinner.stop(message, status);\n return result;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n spinner.stop(msg, \"fail\");\n throw err;\n }\n}\n","import { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExistingRulesScan } from \"./types.js\";\n\nconst MAX_EXCERPT = 3500;\n\nconst RULE_CANDIDATES = [\n \"AGENTS.md\",\n \"CLAUDE.md\",\n \".cursorrules\",\n] as const;\n\nfunction readExcerpt(repoRoot: string, rel: string): string | null {\n const full = join(repoRoot, rel);\n if (!existsSync(full)) {\n return null;\n }\n try {\n const raw = readFileSync(full, \"utf8\");\n return raw.length > MAX_EXCERPT ? `${raw.slice(0, MAX_EXCERPT)}\\n...(truncated)` : raw;\n } catch {\n return null;\n }\n}\n\nfunction collectCursorRules(repoRoot: string): Array<{ path: string; excerpt: string }> {\n const dir = join(repoRoot, \".cursor\", \"rules\");\n if (!existsSync(dir)) {\n return [];\n }\n const out: Array<{ path: string; excerpt: string }> = [];\n try {\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".md\") && !name.endsWith(\".mdc\")) {\n continue;\n }\n const rel = `.cursor/rules/${name}`;\n const excerpt = readExcerpt(repoRoot, rel);\n if (excerpt) {\n out.push({ path: rel, excerpt });\n }\n if (out.length >= 3) {\n break;\n }\n }\n } catch {\n // ignore\n }\n return out;\n}\n\nexport function collectExistingRules(repoRoot: string): ExistingRulesScan {\n const sources: Array<{ path: string; excerpt: string }> = [];\n for (const rel of RULE_CANDIDATES) {\n const excerpt = readExcerpt(repoRoot, rel);\n if (excerpt) {\n sources.push({ path: rel, excerpt });\n }\n }\n sources.push(...collectCursorRules(repoRoot));\n return { sources };\n}\n","import { spawnSync } from \"node:child_process\";\nimport type { GitLogScan } from \"./types.js\";\n\nexport function collectGitLog(repoRoot: string, limit = 50): GitLogScan {\n const result = spawnSync(\n \"git\",\n [\"log\", `--oneline`, `-${limit}`],\n { cwd: repoRoot, encoding: \"utf8\" },\n );\n if (result.status !== 0 || !result.stdout?.trim()) {\n return { lines: [] };\n }\n return {\n lines: result.stdout\n .trim()\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean),\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { PackageJsonScan } from \"./types.js\";\n\nconst STACK_HINTS: Record<string, string> = {\n react: \"react\",\n vue: \"vue\",\n next: \"nextjs\",\n express: \"express\",\n prisma: \"prisma\",\n typescript: \"typescript\",\n vitest: \"vitest\",\n jest: \"jest\",\n bun: \"bun\",\n vite: \"vite\",\n tailwindcss: \"tailwind\",\n};\n\nfunction depKeys(record: Record<string, string> | undefined): string[] {\n if (!record) {\n return [];\n }\n return Object.keys(record);\n}\n\nexport function inferStackTags(deps: string[]): string[] {\n const tags = new Set<string>();\n for (const dep of deps) {\n const lower = dep.toLowerCase();\n for (const [key, tag] of Object.entries(STACK_HINTS)) {\n if (lower.includes(key)) {\n tags.add(tag);\n }\n }\n }\n return [...tags];\n}\n\nexport function collectPackageJson(repoRoot: string): PackageJsonScan | null {\n const path = join(repoRoot, \"package.json\");\n if (!existsSync(path)) {\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(path, \"utf8\")) as {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n return {\n name: raw.name,\n dependencies: depKeys(raw.dependencies),\n devDependencies: depKeys(raw.devDependencies),\n };\n } catch {\n return null;\n }\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { RepoSignalsScan } from \"./types.js\";\n\nconst SIGNAL_FILES = [\n \"Dockerfile\",\n \"Makefile\",\n \"docker-compose.yml\",\n \"docker-compose.yaml\",\n \"prisma/schema.prisma\",\n \".github/workflows\",\n] as const;\n\nexport function collectRepoSignals(repoRoot: string): RepoSignalsScan {\n const signals: string[] = [];\n for (const rel of SIGNAL_FILES) {\n const full = join(repoRoot, rel);\n if (existsSync(full)) {\n signals.push(rel);\n }\n }\n if (existsSync(join(repoRoot, \".gitignore\"))) {\n signals.push(\".gitignore\");\n }\n try {\n const root = readdirSync(repoRoot);\n if (root.some((n) => n.startsWith(\"docker-compose\"))) {\n signals.push(\"docker-compose (root)\");\n }\n } catch {\n // ignore\n }\n return { signals: [...new Set(signals)] };\n}\n","import { collectExistingRules } from \"./collectors/existingRules.js\";\nimport { collectGitLog } from \"./collectors/gitLog.js\";\nimport { collectPackageJson } from \"./collectors/packageJson.js\";\nimport { collectRepoSignals } from \"./collectors/repoSignals.js\";\nimport type { ProjectScanData } from \"./collectors/types.js\";\n\nexport function collectProjectScan(repoRoot: string): ProjectScanData {\n const warnings: string[] = [];\n const packageJson = collectPackageJson(repoRoot);\n const repoSignals = collectRepoSignals(repoRoot);\n const gitLog = collectGitLog(repoRoot);\n const existingRules = collectExistingRules(repoRoot);\n\n if (!packageJson) {\n warnings.push(\"未找到 package.json,技术栈扫描信息有限\");\n }\n if (gitLog.lines.length === 0) {\n warnings.push(\"无法读取 git log(非 Git 仓库或无提交)\");\n }\n if (\n !packageJson &&\n repoSignals.signals.length === 0 &&\n gitLog.lines.length === 0 &&\n existingRules.sources.length === 0\n ) {\n warnings.push(\"项目扫描未发现可用信号,将跳过生成记忆\");\n }\n\n return {\n packageJson,\n repoSignals,\n gitLog,\n existingRules,\n warnings,\n };\n}\n","export const COLDSTART_SESSION_ID = \"coldstart-scan\";\n\nexport const COLDSTART_BASE_TAGS = [\"coldstart\", \"convention\"] as const;\n","import type { FormattedCapture } from \"../capture/formatCapture.js\";\nimport { COLDSTART_BASE_TAGS, COLDSTART_SESSION_ID } from \"./constants.js\";\nimport { inferStackTags } from \"./collectors/packageJson.js\";\nimport type { ProjectScanData } from \"./collectors/types.js\";\n\nfunction semanticCapture(\n tags: string[],\n context: string,\n findings: string,\n impact = \"供 AI 在后续任务中参考;细节以仓库现状为准。\",\n): FormattedCapture {\n const tagSet = new Set([...COLDSTART_BASE_TAGS, ...tags]);\n return {\n type: \"semantic\",\n sessionId: COLDSTART_SESSION_ID,\n tags: [...tagSet],\n scope: \"all\",\n bodyMarkdown: `## 上下文\n\n${context}\n\n## 发现\n\n${findings}\n\n## 影响\n\n${impact}`,\n };\n}\n\nexport function buildScanCaptures(data: ProjectScanData): FormattedCapture[] {\n const captures: FormattedCapture[] = [];\n\n if (data.packageJson) {\n const allDeps = [\n ...data.packageJson.dependencies,\n ...data.packageJson.devDependencies,\n ];\n const stackTags = inferStackTags(allDeps);\n const nameLine = data.packageJson.name\n ? `项目名称: **${data.packageJson.name}**`\n : \"(未命名 package)\";\n const depList =\n allDeps.length > 0\n ? allDeps.slice(0, 40).join(\", \") +\n (allDeps.length > 40 ? ` …共 ${allDeps.length} 项` : \"\")\n : \"(无 dependencies)\";\n captures.push(\n semanticCapture(\n [\"stack\", ...stackTags],\n \"init 项目扫描:从 package.json 提取技术栈。\",\n `${nameLine}\\n\\n主要依赖: ${depList}`,\n ),\n );\n }\n\n if (data.repoSignals.signals.length > 0) {\n captures.push(\n semanticCapture(\n [\"infra\"],\n \"init 项目扫描:仓库基础设施与工程化文件。\",\n data.repoSignals.signals.map((s) => `- ${s}`).join(\"\\n\"),\n ),\n );\n }\n\n if (data.gitLog.lines.length > 0) {\n const sample = data.gitLog.lines.slice(0, 15).map((l) => `- ${l}`).join(\"\\n\");\n captures.push(\n semanticCapture(\n [\"git\", \"activity\"],\n \"init 项目扫描:最近 Git 提交(oneline)。\",\n `最近 ${data.gitLog.lines.length} 条提交摘要(展示前 15 条):\\n\\n${sample}`,\n \"可据此判断近期活跃模块与变更主题。\",\n ),\n );\n }\n\n for (const src of data.existingRules.sources) {\n captures.push(\n semanticCapture(\n [\"migrated-rules\"],\n `init 项目扫描:迁移自 \\`${src.path}\\` 的既有约定。`,\n `来源文件: \\`${src.path}\\`\\n\\n摘录:\\n\\n${src.excerpt}`,\n \"团队真相源仍以原文件为准;本捕获仅供 MEMORY 注入摘要。\",\n ),\n );\n }\n\n return captures;\n}\n","import { writeCaptureFile } from \"../capture/writeCapture.js\";\nimport { collectProjectScan } from \"./collectProjectScan.js\";\nimport { buildScanCaptures } from \"./buildScanCaptures.js\";\n\nexport interface RunProjectScanResult {\n capturesWritten: number;\n warnings: string[];\n skipped: boolean;\n}\n\nexport function runProjectScan(repoRoot: string): RunProjectScanResult {\n const data = collectProjectScan(repoRoot);\n const formatted = buildScanCaptures(data);\n\n if (formatted.length === 0) {\n return {\n capturesWritten: 0,\n warnings: data.warnings,\n skipped: true,\n };\n }\n\n for (const cap of formatted) {\n writeCaptureFile(repoRoot, cap);\n }\n\n return {\n capturesWritten: formatted.length,\n warnings: data.warnings,\n skipped: false,\n };\n}\n","import { checkbox, confirm, input, password } from \"@inquirer/prompts\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport { listAvailable } from \"./assistants/registry.js\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport {\n DEFAULT_LLM_BASE_URL,\n DEFAULT_LLM_MODEL,\n} from \"../config/llmConfig.js\";\nimport type { InitCliOptions, InitResolvedOptions } from \"./types.js\";\nimport type { LlmInitInput } from \"./mergeLlmConfig.js\";\nimport { countExistingCaptures } from \"../coldstart/countCaptures.js\";\nimport { memoryPath } from \"./paths.js\";\n\nfunction isInitialized(targetDir: string): boolean {\n const configPath = memoryPath(targetDir, \"config.json\");\n if (!existsSync(configPath)) {\n return false;\n }\n try {\n const config = JSON.parse(readFileSync(configPath, \"utf8\")) as {\n version?: number;\n };\n return config.version === 1;\n } catch {\n return false;\n }\n}\n\nexport async function gatherInitOptions(\n opts: InitCliOptions,\n): Promise<InitResolvedOptions> {\n const defaultDir = resolve(opts.cwd ?? process.cwd());\n\n const targetInput = await input({\n message: \"目标目录(Git 仓库根)\",\n default: defaultDir,\n });\n const targetDir = resolve(targetInput);\n\n const assistants = (await checkbox({\n message: \"选择要接入的编程助手(可多选)\",\n choices: listAvailable().map((a) => ({\n name: a.label,\n value: a.id,\n checked: a.id === \"claude-code\",\n })),\n validate: (value) => value.length > 0 || \"请至少选择一项\",\n })) as AssistantId[];\n\n const includeExampleTemplates = await confirm({\n message: \"是否写入 capture 示例模板到 .memory/templates/?\",\n default: true,\n });\n\n const { llm, writeLlmJson } = await gatherLlmInitInput(targetDir);\n\n if (isInitialized(targetDir)) {\n const continueInit = await confirm({\n message: \"检测到已有 .memory/config.json,是否仅补全缺失项?\",\n default: true,\n });\n if (!continueInit) {\n return {\n targetDir,\n force: false,\n includeExampleTemplates,\n assistants,\n cancelled: true,\n llm,\n writeLlmJson,\n bootstrapFromScan: false,\n };\n }\n }\n\n const bootstrapFromScan = await promptBootstrapFromScan(targetDir);\n\n return {\n targetDir,\n force: Boolean(opts.force),\n includeExampleTemplates,\n assistants,\n cancelled: false,\n llm,\n writeLlmJson,\n bootstrapFromScan,\n };\n}\n\nasync function promptBootstrapFromScan(targetDir: string): Promise<boolean> {\n const existing = countExistingCaptures(targetDir);\n\n if (existing > 0) {\n return confirm({\n message: `检测到已有 ${existing} 条捕获,仍要根据项目扫描追加首批记忆吗?`,\n default: false,\n });\n }\n\n return confirm({\n message:\n \"是否根据当前项目扫描结果,生成首批语义记忆?\\n(分析 package.json、Git 提交、Dockerfile/Makefile、已有 AGENTS/CLAUDE 约定等)\",\n default: false,\n });\n}\n\ninterface LlmPromptDefaults {\n enabledDefault?: boolean;\n baseUrlDefault?: string;\n modelDefault?: string;\n}\n\nasync function promptLlmFields(\n defaults: LlmPromptDefaults = {},\n options: { preserveEmptyApiKey?: boolean } = {},\n): Promise<LlmInitInput> {\n const llmEnabled = await confirm({\n message: \"是否启用 LLM 捕获提炼(需 API Key,写入 .memory/llm.json,不提交 Git)?\",\n default: defaults.enabledDefault ?? true,\n });\n\n if (!llmEnabled) {\n return { enabled: false };\n }\n\n const baseUrl = await input({\n message: \"LLM API baseUrl\",\n default: defaults.baseUrlDefault ?? DEFAULT_LLM_BASE_URL,\n });\n const model = await input({\n message: \"LLM model\",\n default: defaults.modelDefault ?? DEFAULT_LLM_MODEL,\n });\n const apiKey = await password({\n message: options.preserveEmptyApiKey\n ? \"LLM API Key(留空则保留已有密钥)\"\n : \"LLM API Key\",\n mask: \"*\",\n });\n\n return {\n enabled: true,\n baseUrl,\n model,\n apiKey: apiKey ?? \"\",\n };\n}\n\nasync function gatherLlmInitInput(\n targetDir: string,\n): Promise<{ llm: LlmInitInput; writeLlmJson: boolean }> {\n const llmPath = memoryPath(targetDir, \"llm.json\");\n\n if (existsSync(llmPath)) {\n const overwrite = await confirm({\n message: \"检测到已有 .memory/llm.json,是否覆盖并重新配置?\",\n default: false,\n });\n if (!overwrite) {\n return {\n llm: { enabled: false },\n writeLlmJson: false,\n };\n }\n\n const existing = readLlmConfigAtRepo(targetDir);\n return {\n llm: await promptLlmFields(\n {\n enabledDefault: existing?.enabled ?? true,\n baseUrlDefault: existing?.baseUrl,\n modelDefault: existing?.model,\n },\n { preserveEmptyApiKey: true },\n ),\n writeLlmJson: true,\n };\n }\n\n return {\n llm: await promptLlmFields(),\n writeLlmJson: true,\n };\n}\n","import { filterActiveCaptures, listAllCaptures } from \"../consolidate/listCaptures.js\";\n\nexport function countExistingCaptures(repoRoot: string): number {\n return filterActiveCaptures(listAllCaptures(repoRoot)).length;\n}\n","import { copyFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getAdapter } from \"./assistants/registry.js\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport type { InitReport, InitResolvedOptions } from \"./types.js\";\nimport { EXAMPLE_TEMPLATE_FILES, memoryPath } from \"./paths.js\";\nimport { renderTemplate, resolveTemplatePath } from \"./templateDir.js\";\nimport { mergeConfigForInit } from \"./mergeConfig.js\";\nimport { mergeAgentsMd } from \"./mergeAgentsMd.js\";\nimport { writeLlmJson } from \"./mergeLlmConfig.js\";\nimport { shouldWriteFile, writeIfAllowed } from \"./scaffoldWrite.js\";\n\nexport { shouldWriteFile } from \"./scaffoldWrite.js\";\n\nexport function buildConfigJson(assistants: AssistantId[]): string {\n return `${JSON.stringify(\n {\n version: 1,\n storage: { backend: \"file\" },\n assistants,\n debug: false,\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction writeConfigJson(\n report: InitReport,\n repoRoot: string,\n assistants: AssistantId[],\n): void {\n const { content, action } = mergeConfigForInit(repoRoot, assistants);\n const absolutePath = memoryPath(repoRoot, \"config.json\");\n writeFileSync(absolutePath, content, \"utf8\");\n report.files.push({ path: \".memory/config.json\", action });\n}\n\nfunction copyTemplateIfAllowed(\n report: InitReport,\n templateName: string,\n destAbsolute: string,\n relativePath: string,\n force: boolean,\n): void {\n const { write, action } = shouldWriteFile(destAbsolute, force);\n if (!write) {\n report.files.push({ path: relativePath, action });\n return;\n }\n copyFileSync(resolveTemplatePath(templateName), destAbsolute);\n report.files.push({ path: relativePath, action });\n}\n\nexport function writeScaffoldFiles(\n repoRoot: string,\n opts: InitResolvedOptions,\n report: InitReport,\n): void {\n const { force, includeExampleTemplates, assistants } = opts;\n\n writeConfigJson(report, repoRoot, assistants);\n\n if (opts.writeLlmJson) {\n const llmAction = writeLlmJson(repoRoot, opts.llm);\n report.files.push({ path: \".memory/llm.json\", action: llmAction });\n } else {\n report.files.push({ path: \".memory/llm.json\", action: \"skipped\" });\n }\n\n writeIfAllowed(\n report,\n memoryPath(repoRoot, \"MEMORY.md\"),\n \".memory/MEMORY.md\",\n renderTemplate(\"MEMORY.md.tpl\"),\n force,\n );\n\n writeIfAllowed(\n report,\n memoryPath(repoRoot, \"sessions\", \"index.json\"),\n \".memory/sessions/index.json\",\n `${JSON.stringify({ version: 1, sessions: [] }, null, 2)}\\n`,\n force,\n );\n\n writeIfAllowed(\n report,\n memoryPath(repoRoot, \"team\", \"steward-log.md\"),\n \".memory/team/steward-log.md\",\n renderTemplate(\"steward-log.md.tpl\"),\n force,\n );\n\n report.files.push({\n path: \"AGENTS.md\",\n action: mergeAgentsMd(repoRoot, force),\n });\n\n for (const id of assistants) {\n getAdapter(id).write({ repoRoot, force, report });\n }\n\n if (includeExampleTemplates) {\n for (const name of EXAMPLE_TEMPLATE_FILES) {\n const dest = memoryPath(repoRoot, \"templates\", name);\n copyTemplateIfAllowed(\n report,\n name,\n dest,\n `.memory/templates/${name}`,\n force,\n );\n }\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport type { InitFileAction } from \"./types.js\";\nimport { memoryPath } from \"./paths.js\";\n\n/** init 每次都会写入的 config 字段(其余顶层 / storage 子字段保留) */\nexport function mergeConfigForInit(\n repoRoot: string,\n assistants: AssistantId[],\n): { content: string; action: InitFileAction } {\n const configPath = memoryPath(repoRoot, \"config.json\");\n const existed = existsSync(configPath);\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(configPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevStorage =\n existing.storage &&\n typeof existing.storage === \"object\" &&\n !Array.isArray(existing.storage)\n ? (existing.storage as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n version: 1,\n storage: {\n ...prevStorage,\n backend: \"file\",\n },\n assistants,\n debug: existing.debug === true,\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { InitFileAction } from \"./types.js\";\nimport { readTemplate, renderTemplate } from \"./templateDir.js\";\n\nexport const HERMES_AGENTS_START_MARKER =\n \"<!-- >>> hermes-repo agents (do not edit this block manually) -->\";\nexport const HERMES_AGENTS_END_MARKER = \"<!-- <<< hermes-repo agents -->\";\n\nexport function buildHermesAgentsBlockBody(): string {\n return renderTemplate(\"AGENTS.hermes-block.tpl\").trimEnd();\n}\n\nexport function buildHermesAgentsMarkedBlock(): string {\n const body = buildHermesAgentsBlockBody();\n return `${HERMES_AGENTS_START_MARKER}\\n${body}\\n${HERMES_AGENTS_END_MARKER}`;\n}\n\nexport function buildNewAgentsMd(): string {\n return renderTemplate(\"AGENTS.md.tpl\").replace(\n \"__HERMES_AGENTS_BLOCK__\",\n buildHermesAgentsBlockBody(),\n );\n}\n\nexport function agentsMdHasHermesBlock(content: string): boolean {\n const startIdx = content.indexOf(HERMES_AGENTS_START_MARKER);\n const endIdx = content.indexOf(HERMES_AGENTS_END_MARKER);\n return startIdx !== -1 && endIdx !== -1 && endIdx > startIdx;\n}\n\n/** 无标记块但已手写 hermes 指引时视为已接入(避免重复追加) */\nexport function agentsMdHasLegacyHermesContent(content: string): boolean {\n if (agentsMdHasHermesBlock(content)) {\n return false;\n }\n return (\n content.includes(\"@riconext/hermes-repo\") &&\n content.includes(\"## 记忆系统\") &&\n content.includes(\".memory/MEMORY.md\")\n );\n}\n\nexport function agentsMdHasHermesContent(content: string): boolean {\n return agentsMdHasHermesBlock(content) || agentsMdHasLegacyHermesContent(content);\n}\n\n/** 已有正文与 hermes 标记块之间约两行空行 */\nconst GAP_BEFORE_HERMES_BLOCK = \"\\n\\n\\n\";\n\nfunction withGapBeforeHermesBlock(prefix: string): string {\n const trimmed = prefix.trimEnd();\n if (trimmed.length === 0) {\n return \"\";\n }\n return `${trimmed}${GAP_BEFORE_HERMES_BLOCK}`;\n}\n\nfunction spliceHermesBlock(existing: string, block: string): string {\n const startIdx = existing.indexOf(HERMES_AGENTS_START_MARKER);\n const endIdx = existing.indexOf(HERMES_AGENTS_END_MARKER);\n\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + HERMES_AGENTS_END_MARKER.length);\n const next = `${withGapBeforeHermesBlock(before)}${block}${after}`;\n return next.endsWith(\"\\n\") ? next : `${next}\\n`;\n }\n\n if (startIdx !== -1) {\n const before = existing.slice(0, startIdx);\n return `${withGapBeforeHermesBlock(before)}${block}\\n`;\n }\n\n return `${withGapBeforeHermesBlock(existing)}${block}\\n`;\n}\n\nexport function mergeAgentsMd(\n repoRoot: string,\n force: boolean,\n): InitFileAction {\n const agentsPath = join(repoRoot, \"AGENTS.md\");\n const block = buildHermesAgentsMarkedBlock();\n\n if (!existsSync(agentsPath)) {\n writeFileSync(agentsPath, buildNewAgentsMd(), \"utf8\");\n return \"created\";\n }\n\n const content = readFileSync(agentsPath, \"utf8\");\n\n if (agentsMdHasHermesBlock(content)) {\n if (!force) {\n return \"skipped\";\n }\n writeFileSync(agentsPath, spliceHermesBlock(content, block), \"utf8\");\n return \"replaced\";\n }\n\n if (agentsMdHasLegacyHermesContent(content)) {\n return \"skipped\";\n }\n\n writeFileSync(agentsPath, spliceHermesBlock(content, block), \"utf8\");\n return \"appended\";\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport {\n DEFAULT_LLM_BASE_URL,\n DEFAULT_LLM_MAX_INPUT_CHARS,\n DEFAULT_LLM_MODEL,\n DEFAULT_LLM_TIMEOUT_MS,\n type LlmConfig,\n} from \"../config/llmConfig.js\";\nimport { readLlmConfigAtRepo, serializeLlmConfig } from \"../config/readLlmConfig.js\";\nimport type { InitFileAction } from \"./types.js\";\nimport { memoryPath } from \"./paths.js\";\n\nexport interface LlmInitInput {\n enabled: boolean;\n baseUrl?: string;\n model?: string;\n apiKey?: string;\n provider?: string;\n}\n\nexport function mergeLlmConfigForInit(\n repoRoot: string,\n input: LlmInitInput,\n): { content: string; action: InitFileAction } {\n const llmPath = memoryPath(repoRoot, \"llm.json\");\n const existed = existsSync(llmPath);\n\n let existing: Partial<LlmConfig> = {};\n if (existed) {\n try {\n const parsed = readLlmConfigAtRepo(repoRoot);\n if (parsed) {\n existing = parsed;\n }\n } catch {\n existing = {};\n }\n }\n\n const merged: LlmConfig = {\n enabled: input.enabled,\n provider:\n input.provider ??\n (typeof existing.provider === \"string\" ? existing.provider : \"openai\"),\n baseUrl:\n input.baseUrl ??\n (typeof existing.baseUrl === \"string\" && existing.baseUrl\n ? existing.baseUrl\n : DEFAULT_LLM_BASE_URL),\n model:\n input.model ??\n (typeof existing.model === \"string\" && existing.model\n ? existing.model\n : DEFAULT_LLM_MODEL),\n apiKey:\n input.apiKey !== undefined && input.apiKey !== \"\"\n ? input.apiKey\n : typeof existing.apiKey === \"string\"\n ? existing.apiKey\n : \"\",\n timeoutMs:\n typeof existing.timeoutMs === \"number\"\n ? existing.timeoutMs\n : DEFAULT_LLM_TIMEOUT_MS,\n maxInputChars:\n typeof existing.maxInputChars === \"number\"\n ? existing.maxInputChars\n : DEFAULT_LLM_MAX_INPUT_CHARS,\n mode: existing.mode === \"sync\" ? \"sync\" : \"async\",\n };\n\n return {\n content: serializeLlmConfig(merged),\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n\nexport function writeLlmJson(\n repoRoot: string,\n input: LlmInitInput,\n): InitFileAction {\n const { content, action } = mergeLlmConfigForInit(repoRoot, input);\n writeFileSync(memoryPath(repoRoot, \"llm.json\"), content, \"utf8\");\n return action;\n}\n","import { existsSync, writeFileSync } from \"node:fs\";\nimport type { InitFileAction, InitReport } from \"./types.js\";\n\nexport function shouldWriteFile(\n absolutePath: string,\n force: boolean,\n): { write: boolean; action: InitFileAction } {\n if (!existsSync(absolutePath)) {\n return { write: true, action: \"created\" };\n }\n if (force) {\n return { write: true, action: \"overwritten\" };\n }\n return { write: false, action: \"skipped\" };\n}\n\nexport function writeIfAllowed(\n report: InitReport,\n absolutePath: string,\n relativePath: string,\n content: string,\n force: boolean,\n): void {\n const { write, action } = shouldWriteFile(absolutePath, force);\n if (!write) {\n report.files.push({ path: relativePath, action });\n return;\n }\n writeFileSync(absolutePath, content, \"utf8\");\n report.files.push({ path: relativePath, action });\n}\n","import type { InitCliOptions } from \"../init/types.js\";\nimport { runInit } from \"../init/runInit.js\";\n\nexport async function runInitCommand(opts: InitCliOptions): Promise<void> {\n try {\n await runInit(opts);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { RefRecord } from \"./types.js\";\nimport {\n normalizeCaptureTarget,\n normalizeSkillTarget,\n refFilePath,\n refsDir,\n} from \"./paths.js\";\n\nexport interface WriteRefOptions {\n repoRoot: string;\n capture?: string;\n skill?: string;\n reason: string;\n session?: string;\n date?: string;\n}\n\nfunction targetExists(repoRoot: string, target: string): boolean {\n return existsSync(join(repoRoot, \".memory\", target));\n}\n\nexport function writeRef(opts: WriteRefOptions): { target: string; file: string } {\n const { repoRoot, reason, session } = opts;\n const date = opts.date ?? new Date().toISOString().slice(0, 10);\n\n let target: string;\n if (opts.capture) {\n target = normalizeCaptureTarget(opts.capture);\n } else if (opts.skill) {\n target = normalizeSkillTarget(opts.skill);\n } else {\n throw new Error(\"specify --capture or --skill\");\n }\n\n if (!targetExists(repoRoot, target)) {\n throw new Error(`target not found: .memory/${target}`);\n }\n\n const record: RefRecord = {\n target,\n reason,\n date,\n ...(session ? { session } : {}),\n };\n\n mkdirSync(refsDir(repoRoot), { recursive: true });\n const filePath = refFilePath(repoRoot, target, date);\n const base = filePath.replace(/\\.json$/, \"\");\n let finalPath = `${filePath}`;\n let n = 0;\n while (existsSync(finalPath)) {\n n++;\n finalPath = `${base}-${n}.json`;\n }\n writeFileSync(finalPath, `${JSON.stringify(record, null, 2)}\\n`, \"utf8\");\n\n const file = finalPath.split(\"/refs/\").pop() ?? finalPath;\n return { target, file: `refs/${file}` };\n}\n","import { loadRepoContext } from \"../config/readConfig.js\";\nimport { writeRef } from \"../feedback/writeRef.js\";\nimport { hookExit } from \"../hookExit.js\";\n\nexport function runRefCommand(opts: {\n cwd?: string;\n capture?: string;\n skill?: string;\n reason?: string;\n session?: string;\n strict?: boolean;\n}): void {\n try {\n const ctx = loadRepoContext(opts.cwd);\n if (!ctx) {\n throw new Error(\"not a hermes-repo project (run init first)\");\n }\n if (!opts.reason?.trim()) {\n throw new Error(\"--reason is required\");\n }\n if (!opts.capture && !opts.skill) {\n throw new Error(\"specify --capture or --skill\");\n }\n if (opts.capture && opts.skill) {\n throw new Error(\"use only one of --capture or --skill\");\n }\n\n const { target, file } = writeRef({\n repoRoot: ctx.repoRoot,\n capture: opts.capture,\n skill: opts.skill,\n reason: opts.reason.trim(),\n session: opts.session,\n });\n\n console.error(`hermes-repo: ref recorded ${target} (${file})`);\n hookExit(0, opts.strict);\n } catch (err) {\n console.error(\n `hermes-repo ref: ${err instanceof Error ? err.message : String(err)}`,\n );\n hookExit(1, opts.strict);\n }\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { CaptureMemoryType } from \"../capture/types.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { parseCaptureMarkdown } from \"../consolidate/parseCapture.js\";\n\nexport interface SearchHit {\n path: string;\n summary: string;\n}\n\nexport interface RunSearchOptions {\n repoRoot: string;\n keyword: string;\n type?: CaptureMemoryType;\n limit?: number;\n}\n\nfunction walkMdFiles(dir: string): string[] {\n if (!existsSync(dir)) {\n return [];\n }\n const out: string[] = [];\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (name.endsWith(\".md\")) {\n out.push(full);\n } else if (!name.startsWith(\".\")) {\n try {\n const st = readdirSync(full);\n if (Array.isArray(st)) {\n for (const child of readdirSync(full)) {\n if (child.endsWith(\".md\")) {\n out.push(join(full, child));\n }\n }\n }\n } catch {\n // not a directory\n }\n }\n }\n return out;\n}\n\nfunction listSkillMd(repoRoot: string): string[] {\n const skillsDir = memoryPath(repoRoot, \"skills\");\n if (!existsSync(skillsDir)) {\n return [];\n }\n const out: string[] = [];\n for (const slug of readdirSync(skillsDir)) {\n const f = join(skillsDir, slug, \"SKILL.md\");\n if (existsSync(f)) {\n out.push(f);\n }\n }\n return out;\n}\n\nfunction summaryFromFile(absPath: string, relFromMemory: string): string {\n try {\n const content = readFileSync(absPath, \"utf8\");\n if (relFromMemory.startsWith(\"captures/\")) {\n const parsed = parseCaptureMarkdown(content, relFromMemory, absPath);\n if (parsed) {\n return parsed.summary.slice(0, 80);\n }\n }\n const line = content\n .split(\"\\n\")\n .find((l) => l.trim() && !l.startsWith(\"---\") && !l.startsWith(\"#\"));\n return (line ?? content).slice(0, 80).trim();\n } catch {\n return \"\";\n }\n}\n\nexport function runSearch(opts: RunSearchOptions): SearchHit[] {\n const kw = opts.keyword.trim().toLowerCase();\n if (!kw) {\n return [];\n }\n const limit = opts.limit ?? 20;\n const hits: SearchHit[] = [];\n const memRoot = memoryPath(opts.repoRoot);\n\n const captureTypes: CaptureMemoryType[] = opts.type\n ? [opts.type]\n : [\"semantic\", \"episodic\", \"procedural\"];\n\n for (const t of captureTypes) {\n const dir = join(memRoot, \"captures\", t);\n for (const abs of walkMdFiles(dir)) {\n const rel = abs.replace(memRoot + \"/\", \"\").replace(/\\\\/g, \"/\");\n const content = readFileSync(abs, \"utf8\").toLowerCase();\n if (content.includes(kw)) {\n hits.push({\n path: rel,\n summary: summaryFromFile(abs, rel),\n });\n }\n if (hits.length >= limit) {\n return hits;\n }\n }\n }\n\n const topicsDir = join(memRoot, \"topics\");\n for (const abs of walkMdFiles(topicsDir)) {\n const rel = abs.replace(memRoot + \"/\", \"\").replace(/\\\\/g, \"/\");\n if (readFileSync(abs, \"utf8\").toLowerCase().includes(kw)) {\n hits.push({ path: rel, summary: summaryFromFile(abs, rel) });\n }\n if (hits.length >= limit) {\n return hits;\n }\n }\n\n for (const abs of listSkillMd(opts.repoRoot)) {\n const rel = abs.replace(memRoot + \"/\", \"\").replace(/\\\\/g, \"/\");\n if (readFileSync(abs, \"utf8\").toLowerCase().includes(kw)) {\n hits.push({ path: rel, summary: summaryFromFile(abs, rel) });\n }\n if (hits.length >= limit) {\n return hits;\n }\n }\n\n return hits;\n}\n","import { loadRepoContext } from \"../config/readConfig.js\";\nimport { hookExit } from \"../hookExit.js\";\nimport { runSearch } from \"../search/runSearch.js\";\nimport type { CaptureMemoryType } from \"../capture/types.js\";\n\nexport function runSearchCommand(opts: {\n cwd?: string;\n keyword: string;\n type?: string;\n limit?: number;\n strict?: boolean;\n}): void {\n try {\n const ctx = loadRepoContext(opts.cwd);\n if (!ctx) {\n throw new Error(\"not a hermes-repo project (run init first)\");\n }\n const kw = opts.keyword?.trim();\n if (!kw) {\n throw new Error(\"keyword is required\");\n }\n\n let type: CaptureMemoryType | undefined;\n if (opts.type) {\n const t = opts.type as CaptureMemoryType;\n if (![\"semantic\", \"episodic\", \"procedural\"].includes(t)) {\n throw new Error(\"--type must be semantic, episodic, or procedural\");\n }\n type = t;\n }\n\n const hits = runSearch({\n repoRoot: ctx.repoRoot,\n keyword: kw,\n type,\n limit: opts.limit,\n });\n\n for (const h of hits) {\n console.log(`${h.path}\\t${h.summary}`);\n }\n\n if (hits.length === 0) {\n console.error(`hermes-repo: no matches for \"${kw}\"`);\n } else {\n console.error(`hermes-repo: ${hits.length} match(es)`);\n }\n\n hookExit(0, opts.strict);\n } catch (err) {\n console.error(\n `hermes-repo search: ${err instanceof Error ? err.message : String(err)}`,\n );\n hookExit(1, opts.strict);\n }\n}\n","import { existsSync, statSync } from \"node:fs\";\nimport { INJECT_MAX_CHARS } from \"../inject/constants.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { listRefFiles } from \"../feedback/listRefs.js\";\nimport { readSkillUsage } from \"../feedback/skillUsage.js\";\nimport {\n filterActiveCaptures,\n listAllCaptures,\n} from \"../consolidate/listCaptures.js\";\nimport { readConsolidateState } from \"../consolidate/state.js\";\nimport {\n isMemoryEligible,\n shouldArchiveCapture,\n} from \"../lifecycle/memoryEligibility.js\";\nimport { listSkillIndex, filterSkillIndexForMemory } from \"../skills/skillIndex.js\";\n\nexport interface MemoryStats {\n capturesTotal: number;\n semantic: number;\n episodic: number;\n procedural: number;\n superseded: number;\n zeroUseCount: number;\n demotedCandidates: number;\n archiveCandidates: number;\n memoryBytes: number;\n memoryMaxBytes: number;\n skillsTotal: number;\n skillsInMemory: number;\n pendingRefs: number;\n lastConsolidatedAt: string;\n}\n\nexport function collectStats(repoRoot: string, nowMs: number = Date.now()): MemoryStats {\n const all = listAllCaptures(repoRoot);\n const active = filterActiveCaptures(all);\n const superseded = all.length - active.length;\n\n let semantic = 0;\n let episodic = 0;\n let procedural = 0;\n let zeroUseCount = 0;\n let demotedCandidates = 0;\n let archiveCandidates = 0;\n\n for (const c of active) {\n if (c.type === \"semantic\") {\n semantic++;\n } else if (c.type === \"episodic\") {\n episodic++;\n } else if (c.type === \"procedural\") {\n procedural++;\n }\n if ((c.useCount ?? 0) === 0) {\n zeroUseCount++;\n }\n if (!isMemoryEligible(c, nowMs)) {\n demotedCandidates++;\n }\n if (shouldArchiveCapture(c, repoRoot, nowMs)) {\n archiveCandidates++;\n }\n }\n\n const memoryFile = memoryPath(repoRoot, \"MEMORY.md\");\n const memoryBytes = existsSync(memoryFile) ? statSync(memoryFile).size : 0;\n\n const allSkills = listSkillIndex(repoRoot);\n const skillUsage = readSkillUsage(repoRoot);\n const inMemory = filterSkillIndexForMemory(allSkills, skillUsage, repoRoot, nowMs);\n\n let lastConsolidatedAt = \"\";\n try {\n lastConsolidatedAt = readConsolidateState(repoRoot).lastConsolidatedAt;\n } catch {\n lastConsolidatedAt = \"\";\n }\n\n return {\n capturesTotal: active.length,\n semantic,\n episodic,\n procedural,\n superseded,\n zeroUseCount,\n demotedCandidates,\n archiveCandidates,\n memoryBytes,\n memoryMaxBytes: INJECT_MAX_CHARS,\n skillsTotal: allSkills.length,\n skillsInMemory: inMemory.length,\n pendingRefs: listRefFiles(repoRoot).length,\n lastConsolidatedAt,\n };\n}\n\nexport function formatStatsHuman(s: MemoryStats): string {\n const lines = [\n \"hermes-repo memory health\",\n ` captures (active): ${s.capturesTotal} (${s.semantic}s / ${s.episodic}e / ${s.procedural}p)`,\n ` superseded: ${s.superseded}`,\n ` zero use_count: ${s.zeroUseCount}`,\n ` demoted (not in MEMORY): ${s.demotedCandidates}`,\n ` archive candidates: ${s.archiveCandidates}`,\n ` MEMORY.md: ${s.memoryBytes} / ${s.memoryMaxBytes} chars`,\n ` skills: ${s.skillsInMemory} in MEMORY / ${s.skillsTotal} on disk`,\n ` pending refs: ${s.pendingRefs}`,\n ` last consolidate: ${s.lastConsolidatedAt || \"(never)\"}`,\n ];\n return lines.join(\"\\n\");\n}\n\nexport function formatStatsJson(s: MemoryStats): string {\n return `${JSON.stringify(s, null, 2)}\\n`;\n}\n","import { loadRepoContext } from \"../config/readConfig.js\";\nimport {\n collectStats,\n formatStatsHuman,\n formatStatsJson,\n} from \"../stats/runStats.js\";\nimport { hookExit } from \"../hookExit.js\";\n\nexport function runStatsCommand(opts: {\n cwd?: string;\n json?: boolean;\n strict?: boolean;\n}): void {\n try {\n const ctx = loadRepoContext(opts.cwd);\n if (!ctx) {\n throw new Error(\"not a hermes-repo project (run init first)\");\n }\n\n const stats = collectStats(ctx.repoRoot);\n const out = opts.json ? formatStatsJson(stats) : formatStatsHuman(stats);\n console.log(out.endsWith(\"\\n\") ? out.slice(0, -1) : out);\n hookExit(0, opts.strict);\n } catch (err) {\n console.error(\n `hermes-repo stats: ${err instanceof Error ? err.message : String(err)}`,\n );\n hookExit(1, opts.strict);\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport {\n analyzeCandidates,\n buildMergedStagingDrafts,\n} from \"./analyzeCandidate.js\";\nimport { applyDecisions, readManifestFile, writeManifestTemplate } from \"./applyDecisions.js\";\nimport { buildPrBody } from \"./buildPrBody.js\";\nimport {\n listPromoteCandidates,\n normalizeCapturePath,\n} from \"./listPromoteCandidates.js\";\nimport {\n defaultPrBodyPath,\n promoteDir,\n promoteStagingTopicsDir,\n stagingTopicPath,\n} from \"./paths.js\";\nimport type { PromoteApplyResult, PromoteCandidateAnalysis } from \"./types.js\";\n\nexport interface RunPromoteOptions {\n cwd?: string;\n mode: \"preview\" | \"pr\" | \"apply\";\n manifestPath?: string;\n outPath?: string;\n dryRun?: boolean;\n captureFilters?: string[];\n}\n\nexport interface RunPromotePreviewResult {\n analyses: PromoteCandidateAnalysis[];\n}\n\nexport interface RunPromotePrResult {\n analyses: PromoteCandidateAnalysis[];\n prBodyPath: string;\n stagingTopicPaths: string[];\n manifestTemplatePath: string;\n}\n\nfunction ensurePromoteDirs(repoRoot: string): void {\n mkdirSync(promoteDir(repoRoot), { recursive: true });\n mkdirSync(promoteStagingTopicsDir(repoRoot), { recursive: true });\n}\n\nfunction formatPreviewTable(analyses: PromoteCandidateAnalysis[]): string {\n const lines = [\n \"path | type | tag | suggest | conflict\",\n \"-----|------|-----|---------|----------\",\n ];\n for (const a of analyses) {\n const conflict = a.conflict.hasConflict ? \"yes\" : \"no\";\n lines.push(\n `${a.capture.path} | ${a.capture.type} | ${a.primaryTag} | ${a.suggestedAction} | ${conflict}`,\n );\n }\n return lines.join(\"\\n\");\n}\n\nexport async function runPromote(\n opts: RunPromoteOptions,\n): Promise<\n | RunPromotePreviewResult\n | RunPromotePrResult\n | PromoteApplyResult\n | { empty: true }\n> {\n const ctx = loadRepoContext(opts.cwd);\n if (!ctx) {\n throw new Error(\"not a hermes-repo project (run init first)\");\n }\n const repoRoot = ctx.repoRoot;\n\n if (opts.mode === \"apply\") {\n if (!opts.manifestPath) {\n throw new Error(\"--apply requires --manifest <path>\");\n }\n const manifest = readManifestFile(resolve(opts.manifestPath));\n return applyDecisions(repoRoot, manifest, { dryRun: opts.dryRun });\n }\n\n const filters = opts.captureFilters?.map(normalizeCapturePath);\n const candidates = listPromoteCandidates(repoRoot, filters);\n\n if (candidates.length === 0) {\n return { empty: true };\n }\n\n const llm = readLlmConfigAtRepo(repoRoot);\n const analyses = await analyzeCandidates(repoRoot, candidates, llm);\n\n if (opts.mode === \"preview\") {\n return { analyses };\n }\n\n ensurePromoteDirs(repoRoot);\n const dateIso = new Date().toISOString().slice(0, 10);\n const mergedDrafts = await buildMergedStagingDrafts(repoRoot, analyses, llm);\n const stagingTopicPaths: string[] = [];\n\n for (const [slug, body] of mergedDrafts) {\n const path = stagingTopicPath(repoRoot, slug);\n writeFileSync(path, body, \"utf8\");\n stagingTopicPaths.push(\n `.memory/promote/staging/topics/${slug}.md`,\n );\n }\n\n const prBody = buildPrBody(repoRoot, analyses);\n const prBodyPath = opts.outPath\n ? resolve(opts.outPath)\n : defaultPrBodyPath(repoRoot, dateIso);\n mkdirSync(memoryPath(repoRoot, \"promote\"), { recursive: true });\n writeFileSync(prBodyPath, prBody, \"utf8\");\n\n const manifestTemplatePath = writeManifestTemplate(\n repoRoot,\n candidates.map((c) => c.path),\n );\n\n return {\n analyses,\n prBodyPath,\n stagingTopicPaths,\n manifestTemplatePath,\n };\n}\n\nexport function printPreviewReport(analyses: PromoteCandidateAnalysis[]): void {\n console.error(formatPreviewTable(analyses));\n for (const a of analyses) {\n console.error(`\\n# ${a.capture.path}\\n${a.note}`);\n }\n}\n\nexport function printPrReport(result: RunPromotePrResult): void {\n const approve = result.analyses.filter((a) => a.suggestedAction === \"approve\")\n .length;\n const conflicts = result.analyses.filter((a) => a.conflict.hasConflict).length;\n console.error(\n `hermes-repo promote: ${result.analyses.length} candidate(s), ${approve} suggested approve, ${conflicts} conflict(s)`,\n );\n console.error(`PR body: ${result.prBodyPath}`);\n console.error(`Manifest template: ${result.manifestTemplatePath}`);\n for (const p of result.stagingTopicPaths) {\n console.error(`Staging: ${p}`);\n }\n console.error(\n \"Next: review PR body → copy decisions.template.json to decisions.json → git commit topics/ → promote --apply --manifest decisions.json → flush\",\n );\n}\n\nexport function printApplyReport(result: PromoteApplyResult): void {\n console.error(\n `hermes-repo promote apply: approved ${result.approved.length}, rejected ${result.rejected.length}, deferred ${result.deferred.length}`,\n );\n if (result.topicsWritten.length > 0) {\n console.error(`Topics written: ${result.topicsWritten.join(\", \")}`);\n }\n console.error(\"Run `hermes-repo flush` to refresh MEMORY.md\");\n}\n\nexport function memoryExists(repoRoot: string): boolean {\n return existsSync(memoryPath(repoRoot, \"config.json\"));\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { LlmConfig } from \"../config/llmConfig.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport { updateTopicViaLlm } from \"../consolidate/llmConsolidate.js\";\nimport { primaryTag, tagToSlug, type ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport function ruleTopicDraftBody(\n tag: string,\n captures: ParsedCapture[],\n existing: string,\n): string {\n const lines = captures.map(\n (c) =>\n `- [${c.date}] [${c.type}] ${c.summary.slice(0, 120)} (${c.path}) [晋升候选]`,\n );\n const header = `# ${tag}\\n\\n`;\n const stamp = new Date().toISOString().slice(0, 10);\n if (existing.trim()) {\n return `${existing.trimEnd()}\\n\\n## 晋升草案 ${stamp}\\n\\n${lines.join(\"\\n\")}\\n`;\n }\n return `${header}由 promote 生成的团队层草案(待审查)。\\n\\n${lines.join(\"\\n\")}\\n`;\n}\n\nexport async function buildTopicDraftBody(\n repoRoot: string,\n captures: ParsedCapture[],\n llm: LlmConfig | null,\n): Promise<{ tag: string; slug: string; body: string }> {\n const tag = primaryTag(captures[0]!);\n const slug = tagToSlug(tag);\n const abs = memoryPath(repoRoot, \"topics\", `${slug}.md`);\n let existing = \"\";\n if (existsSync(abs)) {\n try {\n existing = readFileSync(abs, \"utf8\");\n } catch {\n existing = \"\";\n }\n }\n\n const summaries = captures.map(\n (c) => `[${c.type}] ${c.summary}\\n${c.findings.slice(0, 300)}`,\n );\n\n let body: string | null = null;\n if (isLlmAvailable(llm)) {\n body = await updateTopicViaLlm(llm!, tag, existing, summaries);\n }\n if (!body) {\n body = ruleTopicDraftBody(tag, captures, existing);\n }\n\n return {\n tag,\n slug,\n body: body.endsWith(\"\\n\") ? body : `${body}\\n`,\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport { primaryTag, tagToSlug } from \"../consolidate/parseCapture.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { TopicConflictInfo } from \"./types.js\";\n\n/** 与 consolidate/detectConflict 对齐的互斥词对 */\nconst MUTEX_PAIRS: [string, string][] = [\n [\"localstorage\", \"httponly\"],\n [\"local storage\", \"httponly\"],\n [\"mysql\", \"postgresql\"],\n [\"mysql\", \"postgres\"],\n [\"javascript\", \"typescript-only\"],\n [\"npm\", \"pnpm-only\"],\n];\n\nfunction hasTerm(blob: string, term: string): boolean {\n return blob.includes(term.toLowerCase());\n}\n\nfunction pairConflicts(a: string, b: string): boolean {\n for (const [x, y] of MUTEX_PAIRS) {\n const hasX = hasTerm(a, x) && hasTerm(b, y);\n const hasY = hasTerm(a, y) && hasTerm(b, x);\n if (hasX || hasY) {\n return true;\n }\n }\n return false;\n}\n\nfunction captureBlob(c: ParsedCapture): string {\n return `${c.summary} ${c.findings}`.toLowerCase();\n}\n\nexport function detectTopicConflict(\n repoRoot: string,\n capture: ParsedCapture,\n): TopicConflictInfo {\n const tag = primaryTag(capture);\n const slug = tagToSlug(tag);\n const topicPath = memoryPath(repoRoot, \"topics\", `${slug}.md`);\n const relTopic = `topics/${slug}.md`;\n\n if (!existsSync(topicPath)) {\n return { hasConflict: false, reason: \"none\" };\n }\n\n let existing = \"\";\n try {\n existing = readFileSync(topicPath, \"utf8\");\n } catch {\n return { hasConflict: false, reason: \"none\" };\n }\n\n const blobCap = captureBlob(capture);\n const blobTopic = existing.toLowerCase();\n\n if (pairConflicts(blobCap, blobTopic)) {\n return {\n hasConflict: true,\n reason: \"与现有团队 topic 存在互斥断言(规则检测)\",\n topicPath: relTopic,\n };\n }\n\n return { hasConflict: false, reason: \"none\", topicPath: relTopic };\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport { primaryTag } from \"../consolidate/parseCapture.js\";\n\nasync function chatJson(\n llm: LlmConfig,\n system: string,\n user: string,\n): Promise<unknown | null> {\n const url = `${llm.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), llm.timeoutMs);\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${llm.apiKey}`,\n },\n body: JSON.stringify({\n model: llm.model,\n response_format: { type: \"json_object\" },\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n temperature: 0.2,\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n return null;\n }\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n return null;\n }\n return JSON.parse(content) as unknown;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nconst ANALYZE_SYSTEM = `You help review whether a personal memory capture should be promoted to team-shared topics.\nRespond with JSON only: { \"note\": \"<1-2 sentences in Chinese>\", \"suggestedAction\": \"approve\" | \"defer\" | \"reject\" }\nUse defer when uncertain or one-off episodic events; reject when clearly personal noise.`;\n\nexport async function analyzeNoteViaLlm(\n llm: LlmConfig,\n capture: ParsedCapture,\n conflictSummary: string,\n): Promise<{ note: string; suggestedAction?: string } | null> {\n const user = `Tag: ${primaryTag(capture)}\nType: ${capture.type}\nScope: ${capture.scope}\nSummary: ${capture.summary}\nFindings excerpt: ${capture.findings.slice(0, 800)}\nConflict check: ${conflictSummary}`;\n\n const parsed = (await chatJson(llm, ANALYZE_SYSTEM, user)) as {\n note?: string;\n suggestedAction?: string;\n } | null;\n\n if (!parsed?.note?.trim()) {\n return null;\n }\n return {\n note: parsed.note.trim(),\n suggestedAction: parsed.suggestedAction,\n };\n}\n","import type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport type { PromoteTarget } from \"./types.js\";\n\nexport function suggestTarget(capture: ParsedCapture): PromoteTarget {\n if (capture.type === \"procedural\") {\n return \"skills\";\n }\n return \"topics\";\n}\n\nexport function targetHintForPr(target: PromoteTarget): string {\n if (target === \"skills\") {\n return \"建议通过 `flush` 晋升到 `.memory/skills/`(本 CLI 不自动写 Skill)\";\n }\n return \"建议晋升到 `.memory/topics/`\";\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport { primaryTag, tagToSlug, type ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport { buildTopicDraftBody } from \"./buildTopicDraft.js\";\nimport { detectTopicConflict } from \"./detectTopicConflict.js\";\nimport { analyzeNoteViaLlm } from \"./promoteLlm.js\";\nimport { suggestTarget, targetHintForPr } from \"./suggestTarget.js\";\nimport type {\n PromoteCandidateAnalysis,\n PromoteSuggestedAction,\n} from \"./types.js\";\n\nfunction ruleNote(\n capture: ParsedCapture,\n conflict: ReturnType<typeof detectTopicConflict>,\n target: ReturnType<typeof suggestTarget>,\n): string {\n const hint = targetHintForPr(target);\n if (conflict.hasConflict) {\n return `与 ${conflict.topicPath ?? \"topics\"} 可能存在冲突,建议延后讨论。${hint}`;\n }\n if (capture.type === \"episodic\") {\n return `情景记忆,请确认是否值得固化为团队约定。${hint}`;\n }\n return `无规则冲突,可进入团队层审查。${hint}`;\n}\n\nfunction resolveSuggestedAction(\n conflict: ReturnType<typeof detectTopicConflict>,\n capture: ParsedCapture,\n llmAction?: string,\n): PromoteSuggestedAction {\n if (llmAction === \"approve\" || llmAction === \"defer\" || llmAction === \"reject\") {\n return llmAction;\n }\n if (conflict.hasConflict) {\n return \"defer\";\n }\n if (capture.type === \"episodic\") {\n return \"defer\";\n }\n return \"approve\";\n}\n\nexport async function analyzeCandidate(\n repoRoot: string,\n capture: ParsedCapture,\n llm: LlmConfig | null,\n): Promise<PromoteCandidateAnalysis> {\n const tag = primaryTag(capture);\n const topicSlug = tagToSlug(tag);\n const suggestedTarget = suggestTarget(capture);\n const conflict = detectTopicConflict(repoRoot, capture);\n\n let note = ruleNote(capture, conflict, suggestedTarget);\n let suggestedAction = resolveSuggestedAction(conflict, capture);\n\n if (isLlmAvailable(llm)) {\n const conflictSummary = conflict.hasConflict\n ? conflict.reason\n : \"no conflict detected\";\n const llmResult = await analyzeNoteViaLlm(llm!, capture, conflictSummary);\n if (llmResult?.note) {\n note = llmResult.note;\n suggestedAction = resolveSuggestedAction(\n conflict,\n capture,\n llmResult.suggestedAction,\n );\n }\n }\n\n const { body: topicDraftBody } = await buildTopicDraftBody(repoRoot, [capture], llm);\n\n return {\n capture,\n primaryTag: tag,\n topicSlug,\n suggestedTarget,\n suggestedAction,\n conflict,\n note,\n topicDraftBody,\n };\n}\n\nexport async function analyzeCandidates(\n repoRoot: string,\n captures: ParsedCapture[],\n llm: LlmConfig | null,\n): Promise<PromoteCandidateAnalysis[]> {\n const analyses: PromoteCandidateAnalysis[] = [];\n for (const c of captures) {\n analyses.push(await analyzeCandidate(repoRoot, c, llm));\n }\n return analyses;\n}\n\n/** 按 topic slug 合并 staging 草案(同 tag 多条捕获) */\nexport async function buildMergedStagingDrafts(\n repoRoot: string,\n analyses: PromoteCandidateAnalysis[],\n llm: LlmConfig | null,\n): Promise<Map<string, string>> {\n const bySlug = new Map<string, ParsedCapture[]>();\n for (const a of analyses) {\n const list = bySlug.get(a.topicSlug) ?? [];\n list.push(a.capture);\n bySlug.set(a.topicSlug, list);\n }\n\n const drafts = new Map<string, string>();\n for (const [, group] of bySlug) {\n const { slug, body } = await buildTopicDraftBody(repoRoot, group, llm);\n drafts.set(slug, body);\n }\n return drafts;\n}\n","import {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readCaptureFile, primaryTag, tagToSlug } from \"../consolidate/parseCapture.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { setFrontmatterScalars } from \"../markdown/frontmatter.js\";\nimport { promoteMarkerPath } from \"../skills/promoteMarker.js\";\nimport {\n decisionsTemplatePath,\n promoteStagingTopicsDir,\n stagingTopicPath,\n} from \"./paths.js\";\nimport type {\n PromoteApplyResult,\n PromoteManifest,\n} from \"./types.js\";\n\nexport function parseManifestJson(raw: string): PromoteManifest {\n const data = JSON.parse(raw) as PromoteManifest;\n if (!data || !Array.isArray(data.decisions)) {\n throw new Error(\"manifest must contain decisions array\");\n }\n for (const d of data.decisions) {\n if (!d.capturePath || !d.action) {\n throw new Error(\"each decision needs capturePath and action\");\n }\n if (\n d.action !== \"approve\" &&\n d.action !== \"reject\" &&\n d.action !== \"defer\"\n ) {\n throw new Error(`invalid action: ${d.action}`);\n }\n if (d.action === \"approve\" && d.target && d.target !== \"topics\") {\n throw new Error(\n \"approve with target=skills is not supported in v0.13; use flush for skills\",\n );\n }\n }\n return data;\n}\n\nexport function buildManifestTemplate(\n capturePaths: string[],\n dateIso: string,\n): PromoteManifest {\n return {\n generatedAt: dateIso,\n decisions: capturePaths.map((capturePath) => ({\n capturePath,\n action: \"defer\" as const,\n target: \"topics\" as const,\n })),\n };\n}\n\nfunction removePromoteMarker(repoRoot: string, capturePath: string): void {\n const marker = promoteMarkerPath(repoRoot, capturePath);\n if (existsSync(marker)) {\n unlinkSync(marker);\n }\n}\n\nfunction annotateReject(\n repoRoot: string,\n capturePath: string,\n note?: string,\n): void {\n const abs = join(repoRoot, \".memory\", capturePath);\n if (!existsSync(abs)) {\n return;\n }\n try {\n let content = readFileSync(abs, \"utf8\");\n const fields: Record<string, string> = {\n promote_rejected_at: new Date().toISOString().slice(0, 10),\n };\n if (note?.trim()) {\n fields.promote_note = note.trim().slice(0, 200);\n }\n content = setFrontmatterScalars(content, fields);\n writeFileSync(abs, content, \"utf8\");\n } catch {\n // skip\n }\n}\n\nfunction mergeTopicFromStaging(\n repoRoot: string,\n slug: string,\n dryRun: boolean,\n): string | null {\n const staging = stagingTopicPath(repoRoot, slug);\n if (!existsSync(staging)) {\n return null;\n }\n const draft = readFileSync(staging, \"utf8\");\n const dest = memoryPath(repoRoot, \"topics\", `${slug}.md`);\n if (dryRun) {\n return `topics/${slug}.md`;\n }\n mkdirSync(memoryPath(repoRoot, \"topics\"), { recursive: true });\n writeFileSync(dest, draft.endsWith(\"\\n\") ? draft : `${draft}\\n`, \"utf8\");\n return `topics/${slug}.md`;\n}\n\nexport function applyDecisions(\n repoRoot: string,\n manifest: PromoteManifest,\n opts?: { dryRun?: boolean },\n): PromoteApplyResult {\n const dryRun = opts?.dryRun === true;\n const result: PromoteApplyResult = {\n approved: [],\n rejected: [],\n deferred: [],\n topicsWritten: [],\n };\n\n const slugsToMerge = new Set<string>();\n\n for (const d of manifest.decisions) {\n const capturePath = d.capturePath.replace(/\\\\/g, \"/\");\n\n if (d.action === \"approve\") {\n result.approved.push(capturePath);\n if (!dryRun) {\n removePromoteMarker(repoRoot, capturePath);\n }\n const parsed = readCaptureFile(repoRoot, capturePath);\n if (parsed) {\n slugsToMerge.add(tagToSlug(primaryTag(parsed)));\n }\n } else if (d.action === \"reject\") {\n result.rejected.push(capturePath);\n if (!dryRun) {\n removePromoteMarker(repoRoot, capturePath);\n annotateReject(repoRoot, capturePath, d.note);\n }\n } else {\n result.deferred.push(capturePath);\n }\n }\n\n if (slugsToMerge.size === 0 && result.approved.length > 0) {\n const stagingDir = promoteStagingTopicsDir(repoRoot);\n if (existsSync(stagingDir)) {\n for (const name of readdirSync(stagingDir)) {\n if (name.endsWith(\".md\")) {\n slugsToMerge.add(name.replace(/\\.md$/, \"\"));\n }\n }\n }\n }\n\n for (const slug of slugsToMerge) {\n const rel = mergeTopicFromStaging(repoRoot, slug, dryRun);\n if (rel && !result.topicsWritten.includes(rel)) {\n result.topicsWritten.push(rel);\n }\n }\n\n return result;\n}\n\nexport function readManifestFile(manifestPath: string): PromoteManifest {\n const raw = readFileSync(manifestPath, \"utf8\");\n return parseManifestJson(raw);\n}\n\nexport function writeManifestTemplate(\n repoRoot: string,\n capturePaths: string[],\n): string {\n const dateIso = new Date().toISOString().slice(0, 10);\n const manifest = buildManifestTemplate(capturePaths, dateIso);\n const path = decisionsTemplatePath(repoRoot);\n mkdirSync(memoryPath(repoRoot, \"promote\"), { recursive: true });\n writeFileSync(path, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n return path;\n}\n","import { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport function promoteDir(repoRoot: string): string {\n return memoryPath(repoRoot, \"promote\");\n}\n\nexport function promoteStagingTopicsDir(repoRoot: string): string {\n return memoryPath(repoRoot, \"promote\", \"staging\", \"topics\");\n}\n\nexport function defaultPrBodyPath(repoRoot: string, dateIso: string): string {\n return memoryPath(repoRoot, \"promote\", `pr-${dateIso}.md`);\n}\n\nexport function decisionsTemplatePath(repoRoot: string): string {\n return memoryPath(repoRoot, \"promote\", \"decisions.template.json\");\n}\n\nexport function resolvePromoteTemplatePath(repoRoot: string): string {\n const inMemory = memoryPath(repoRoot, \"templates\", \"PROMOTE_PR.md\");\n return inMemory;\n}\n\nexport function stagingTopicPath(\n repoRoot: string,\n slug: string,\n): string {\n return join(promoteStagingTopicsDir(repoRoot), `${slug}.md`);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { PromoteCandidateAnalysis } from \"./types.js\";\nimport { targetHintForPr } from \"./suggestTarget.js\";\nimport { resolvePromoteTemplatePath } from \"./paths.js\";\n\nfunction actionLabel(action: string): string {\n if (action === \"approve\") {\n return \"批准晋升\";\n }\n if (action === \"reject\") {\n return \"拒绝\";\n }\n return \"延后讨论\";\n}\n\nfunction buildOverviewTable(analyses: PromoteCandidateAnalysis[]): string {\n const rows = analyses.map((a, i) => {\n const summary = a.capture.summary.slice(0, 60).replace(/\\|/g, \"\\\\|\");\n return `| ${i + 1} | ${summary} | ${actionLabel(a.suggestedAction)} | ${a.capture.scope} |`;\n });\n return [\n \"| 序号 | 摘要 | AI 建议 | scope |\",\n \"|------|------|---------|-------|\",\n ...rows,\n ].join(\"\\n\");\n}\n\nfunction buildItemSection(a: PromoteCandidateAnalysis, index: number): string {\n const targetLine =\n a.suggestedTarget === \"skills\"\n ? `- **建议目标**: \\`.memory/skills/\\`(${targetHintForPr(a.suggestedTarget)})`\n : `- **建议目标**: \\`.memory/topics/${a.topicSlug}.md\\``;\n\n const conflictLine = a.conflict.hasConflict\n ? `- **冲突**: ${a.conflict.reason}(${a.conflict.topicPath ?? \"—\"})`\n : \"- **冲突**: 无\";\n\n return `### ${index + 1}: ${a.capture.summary.slice(0, 80)}\n\n- **来源**: ${a.capture.path}(${a.capture.type},@${a.capture.session || \"—\"})\n- **标签**: ${a.capture.tags.join(\", \")}\n- **scope**: ${a.capture.scope}\n${targetLine}\n${conflictLine}\n- **AI 判断**: ${a.note}\n\n- [ ] 批准晋升\n- [ ] 拒绝\n- [ ] **延后讨论**\n`;\n}\n\nfunction loadTemplate(repoRoot: string): string {\n const path = resolvePromoteTemplatePath(repoRoot);\n if (existsSync(path)) {\n try {\n return readFileSync(path, \"utf8\");\n } catch {\n // fall through\n }\n }\n return `## 记忆晋升申请\n\n### 自动扫描结果\n\n本次检测到 {total_count} 条 promoted capture,建议晋升 {ai_approve_count} 条到团队层。\n\n---\n\n### 本次晋升总览\n\n| 序号 | 摘要 | AI 建议 | scope |\n|------|------|---------|-------|\n| — | — | — | — |\n`;\n}\n\nexport function buildPrBody(\n repoRoot: string,\n analyses: PromoteCandidateAnalysis[],\n): string {\n const template = loadTemplate(repoRoot);\n const approveCount = analyses.filter((a) => a.suggestedAction === \"approve\")\n .length;\n\n let body = template\n .replace(/\\{total_count\\}/g, String(analyses.length))\n .replace(/\\{ai_approve_count\\}/g, String(approveCount));\n\n const overview = buildOverviewTable(analyses);\n body = body.replace(\n /\\| — \\| — \\| — \\| — \\|\\n/,\n `${overview.split(\"\\n\").slice(2).join(\"\\n\")}\\n`,\n );\n\n const marker = \"<!-- 由 `npx @riconext/hermes-repo promote --pr` 自动填充每条捕获 -->\";\n const items = analyses\n .map((a, i) => buildItemSection(a, i))\n .join(\"\\n---\\n\\n\");\n\n if (body.includes(marker)) {\n body = body.replace(marker, `${marker}\\n\\n${items}`);\n } else {\n body = `${body.trimEnd()}\\n\\n---\\n\\n${items}\\n`;\n }\n\n return body.endsWith(\"\\n\") ? body : `${body}\\n`;\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { CaptureMemoryType } from \"../capture/types.js\";\nimport { readCaptureFile } from \"../consolidate/parseCapture.js\";\nimport type { ParsedCapture } from \"../consolidate/parseCapture.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { hasPromoteMarker } from \"../skills/promoteMarker.js\";\n\nconst TYPES: CaptureMemoryType[] = [\"semantic\", \"episodic\", \"procedural\"];\n\nexport function normalizeCapturePath(input: string): string {\n let p = input.replace(/\\\\/g, \"/\").trim();\n if (p.startsWith(\".memory/\")) {\n p = p.slice(\".memory/\".length);\n }\n if (p.startsWith(\"/\")) {\n p = p.slice(1);\n }\n return p;\n}\n\nexport function listPromoteCandidates(\n repoRoot: string,\n filterPaths?: string[],\n): ParsedCapture[] {\n const filterSet =\n filterPaths && filterPaths.length > 0\n ? new Set(filterPaths.map(normalizeCapturePath))\n : null;\n\n const results: ParsedCapture[] = [];\n\n for (const type of TYPES) {\n const dir = memoryPath(repoRoot, \"captures\", type);\n if (!existsSync(dir)) {\n continue;\n }\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".md\")) {\n continue;\n }\n const relativePath = `captures/${type}/${name}`;\n if (filterSet && !filterSet.has(relativePath)) {\n continue;\n }\n if (!hasPromoteMarker(repoRoot, relativePath)) {\n continue;\n }\n const parsed = readCaptureFile(repoRoot, relativePath);\n if (parsed) {\n parsed.hasPromoteMarker = true;\n results.push(parsed);\n }\n }\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return results;\n}\n\nexport function listPromoteSidecarPaths(repoRoot: string): string[] {\n const paths: string[] = [];\n for (const type of TYPES) {\n const dir = memoryPath(repoRoot, \"captures\", type);\n if (!existsSync(dir)) {\n continue;\n }\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".md\")) {\n continue;\n }\n const relativePath = `captures/${type}/${name}`;\n if (hasPromoteMarker(repoRoot, relativePath)) {\n paths.push(relativePath);\n }\n }\n }\n return paths;\n}\n","import { hookExit } from \"../hookExit.js\";\nimport {\n printApplyReport,\n printPreviewReport,\n printPrReport,\n runPromote,\n} from \"../promote/runPromote.js\";\n\nexport async function runPromoteCommand(opts: {\n cwd?: string;\n preview?: boolean;\n pr?: boolean;\n apply?: boolean;\n manifest?: string;\n out?: string;\n dryRun?: boolean;\n strict?: boolean;\n captures?: string[];\n}): Promise<void> {\n try {\n const modes = [opts.preview, opts.pr, opts.apply].filter(Boolean).length;\n if (modes !== 1) {\n throw new Error(\"specify exactly one of --preview, --pr, or --apply\");\n }\n\n if (opts.preview) {\n const result = await runPromote({\n cwd: opts.cwd,\n mode: \"preview\",\n captureFilters: opts.captures,\n });\n if (\"empty\" in result && result.empty) {\n console.error(\"hermes-repo promote: no .promote markers found\");\n hookExit(0, opts.strict);\n return;\n }\n if (\"analyses\" in result) {\n printPreviewReport(result.analyses);\n }\n hookExit(0, opts.strict);\n return;\n }\n\n if (opts.pr) {\n const result = await runPromote({\n cwd: opts.cwd,\n mode: \"pr\",\n outPath: opts.out,\n captureFilters: opts.captures,\n });\n if (\"empty\" in result && result.empty) {\n console.error(\"hermes-repo promote: no .promote markers found\");\n hookExit(0, opts.strict);\n return;\n }\n if (\"prBodyPath\" in result) {\n printPrReport(result);\n }\n hookExit(0, opts.strict);\n return;\n }\n\n const result = await runPromote({\n cwd: opts.cwd,\n mode: \"apply\",\n manifestPath: opts.manifest,\n dryRun: opts.dryRun,\n });\n if (\"approved\" in result) {\n printApplyReport(result);\n }\n hookExit(0, opts.strict);\n } catch (err) {\n console.error(\n `hermes-repo promote: ${err instanceof Error ? err.message : String(err)}`,\n );\n hookExit(1, opts.strict);\n }\n}\n"],"mappings":"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","names":["join","dirname","join","join","existsSync","readFileSync","writeFileSync","join","existsSync","readFileSync","existsSync","readFileSync","readFileSync","text","existsSync","mkdirSync","readFileSync","dirname","join","join","dirname","existsSync","readFileSync","mkdirSync","existsSync","mkdirSync","readdirSync","writeFileSync","join","mkdirSync","existsSync","readdirSync","join","writeFileSync","join","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","resolve","readFileSync","writeFileSync","join","readFileSync","writeFileSync","join","spawn","dirname","join","fileURLToPath","existsSync","readdirSync","readFileSync","join","readFileSync","join","join","readFileSync","existsSync","readdirSync","join","readFileSync","appendFileSync","existsSync","writeFileSync","readFileSync","writeFileSync","join","existsSync","readdirSync","readFileSync","join","join","join","input","existsSync","readdirSync","readFileSync","join","join","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","writeFileSync","join","readFileSync","writeFileSync","existsSync","join","existsSync","mkdirSync","renameSync","unlinkSync","dirname","join","join","existsSync","mkdirSync","dirname","renameSync","unlinkSync","existsSync","readdirSync","readFileSync","statSync","join","existsSync","readdirSync","join","readFileSync","statSync","existsSync","mkdirSync","readFileSync","writeFileSync","mkdirSync","existsSync","readFileSync","writeFileSync","readFileSync","writeFileSync","mkdirSync","writeFileSync","join","chatJson","existsSync","join","join","existsSync","readFileSync","writeFileSync","readFileSync","writeFileSync","readFileSync","input","readFileSync","join","mkdirSync","writeFileSync","existsSync","mkdirSync","readFileSync","rmSync","writeFileSync","existsSync","readFileSync","mkdirSync","writeFileSync","rmSync","feedback","lifecycle","writeFileSync","existsSync","appendFileSync","input","all","cliPath","join","dirname","fileURLToPath","spawn","existsSync","readdirSync","readFileSync","statSync","basename","join","resolve","existsSync","readdirSync","join","basename","statSync","existsSync","readdirSync","statSync","homedir","basename","join","resolve","existsSync","readdirSync","statSync","homedir","join","resolve","collectJsonlRecursive","existsSync","readFileSync","existsSync","readFileSync","spawnSync","resolve","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","existsSync","readFileSync","dirname","join","fileURLToPath","readFileSync","dirname","join","fileURLToPath","dirname","fileURLToPath","join","existsSync","readFileSync","join","existsSync","readFileSync","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","join","existsSync","readFileSync","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","join","existsSync","readFileSync","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","join","mkdirSync","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","existsSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","readdirSync","join","existsSync","readFileSync","join","existsSync","readdirSync","join","existsSync","readFileSync","resolve","existsSync","readFileSync","resolve","writeLlmJson","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","existsSync","readFileSync","writeFileSync","join","spliceHermesBlock","join","existsSync","writeFileSync","readFileSync","existsSync","writeFileSync","input","existsSync","writeFileSync","existsSync","writeFileSync","writeFileSync","resolve","spawnSync","existsSync","mkdirSync","writeFileSync","join","existsSync","join","mkdirSync","writeFileSync","existsSync","readdirSync","readFileSync","join","existsSync","readdirSync","join","readFileSync","existsSync","statSync","existsSync","statSync","existsSync","mkdirSync","writeFileSync","resolve","existsSync","readFileSync","existsSync","readFileSync","existsSync","readFileSync","MUTEX_PAIRS","hasTerm","pairConflicts","existsSync","readFileSync","chatJson","existsSync","mkdirSync","readdirSync","readFileSync","unlinkSync","writeFileSync","join","join","join","existsSync","unlinkSync","join","readFileSync","writeFileSync","mkdirSync","readdirSync","existsSync","readFileSync","existsSync","readFileSync","existsSync","readdirSync","TYPES","input","existsSync","readdirSync","mkdirSync","resolve","writeFileSync","result"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/config/debugLog.ts","../src/init/paths.ts","../src/config/readConfig.ts","../src/config/findRepoRoot.ts","../src/capture/runLlmJob.ts","../src/config/llmConfig.ts","../src/config/readLlmConfig.ts","../src/capture/claude-code/parseJsonl.ts","../src/capture/enqueueLlmJob.ts","../src/llm/buildSessionDigest.ts","../src/llm/renderCaptureFromJson.ts","../src/llm/chatCompletions.ts","../src/capture/formatCapture.ts","../src/capture/writeCapture.ts","../src/hookExit.ts","../src/commands/captureLlm.ts","../src/capture/hookInput.ts","../src/capture/signalStrength.ts","../src/capture/needsLlm.ts","../src/consolidate/state.ts","../src/consolidate/sessionScanner.ts","../src/consolidate/llmConsolidateV2.ts","../src/consolidate/writeKnowledge.ts","../src/consolidate/archive.ts","../src/consolidate/runConsolidate.ts","../src/consolidate/constants.ts","../src/consolidate/scheduleConsolidate.ts","../src/capture/commitCapture.ts","../src/capture/claude-code/resolveSession.ts","../src/capture/claude-code/run.ts","../src/capture/codebuddy/resolveSession.ts","../src/capture/codebuddy/run.ts","../src/capture/cursor/resolveSession.ts","../src/capture/cursor/run.ts","../src/capture/router.ts","../src/capture/runCapture.ts","../src/commands/capture.ts","../src/commands/flush.ts","../src/inject/runInject.ts","../src/inject/constants.ts","../src/commands/inject.ts","../src/init/runInit.ts","../src/init/assistants/claude-code.ts","../src/init/mergeClaudeSettings.ts","../src/init/templateDir.ts","../src/index.ts","../src/init/assistants/codex.ts","../src/init/mergeCodexConfig.ts","../src/init/assistants/codebuddy.ts","../src/init/mergeCodebuddySettings.ts","../src/init/assistants/cursor.ts","../src/init/mergeCursorHooks.ts","../src/init/assistants/registry.ts","../src/init/ensureDirs.ts","../src/init/mergeAssistants.ts","../src/init/mergeGitignore.ts","../src/init/writeScaffoldFile.ts","../src/init/mergeConfig.ts","../src/init/mergeAgentsMd.ts","../src/init/scaffoldWrite.ts","../src/init/prompts.ts","../src/commands/init.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { runCaptureLlmCommand } from \"./commands/captureLlm.js\";\nimport { runCaptureCommand } from \"./commands/capture.js\";\nimport { runFlushCommandCli } from \"./commands/flush.js\";\nimport { runInjectCommand } from \"./commands/inject.js\";\nimport { runInitCommand } from \"./commands/init.js\";\nimport { readPkgVersion } from \"./index.js\";\n\nconst MIN_NODE_MAJOR = 20;\n\nfunction assertNodeVersion(): void {\n const major = Number.parseInt(process.versions.node.split(\".\")[0] ?? \"0\", 10);\n if (major < MIN_NODE_MAJOR) {\n console.error(\n `hermes-repo requires Node.js >= ${MIN_NODE_MAJOR}. Current: ${process.version}`,\n );\n process.exit(1);\n }\n}\n\nfunction main(): void {\n assertNodeVersion();\n\n const program = new Command();\n\n program\n .name(\"hermes-repo\")\n .description(\n \"跨编程助手的项目级记忆系统:在 Git 仓库中沉淀约定、踩坑与可复用流程\",\n )\n .version(readPkgVersion(), \"-V, --version\", \"显示版本号\");\n\n program\n .command(\"init\")\n .description(\"在当前 Git 仓库初始化 .memory/ 记忆脚手架\")\n .option(\"-y, --yes\", \"非交互模式,使用默认选项\")\n .option(\"-f, --force\", \"覆盖已存在的脚手架文件(不删除 captures 等内容)\")\n .option(\"-C, --cwd <dir>\", \"目标目录,默认 process.cwd()\")\n .option(\n \"--tools <ids>\",\n \"逗号分隔的助手 id,如 claude-code(须与 -y 合用)\",\n )\n .action(\n (options: {\n yes?: boolean;\n force?: boolean;\n cwd?: string;\n tools?: string;\n }) => {\n void runInitCommand({\n yes: options.yes,\n force: options.force,\n cwd: options.cwd,\n tools: options.tools,\n });\n },\n );\n\n program\n .command(\"capture\")\n .description(\"Stop hook:捕获当前会话到 .memory/captures/raw/\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--dry-run\", \"仅预览,不写入文件\")\n .option(\"--strict\", \"失败时 exit 1(hook 默认 exit 0)\")\n .action((options: { cwd?: string; dryRun?: boolean; strict?: boolean }) => {\n runCaptureCommand({\n cwd: options.cwd,\n dryRun: options.dryRun,\n strict: options.strict,\n });\n });\n\n program\n .command(\"capture-llm\")\n .description(\"异步 LLM 升级 capture(由 capture hook 入队,亦可 --flush)\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--job <id>\", \"处理指定 pending job\")\n .option(\"--flush\", \"处理所有 pending job\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action(\n (options: {\n cwd?: string;\n job?: string;\n flush?: boolean;\n strict?: boolean;\n }) => {\n runCaptureLlmCommand({\n cwd: options.cwd,\n job: options.job,\n flush: options.flush,\n strict: options.strict,\n });\n },\n );\n\n program\n .command(\"flush\")\n .description(\n \"手动触发 consolidate:LLM 提炼 captures → 知识库 + MEMORY.md\",\n )\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--force\", \"重处理全部 session 文件\")\n .option(\"--dry-run\", \"仅预览,不写入\")\n .option(\"--strict\", \"失败时 exit 1\")\n .action(\n (options: {\n cwd?: string;\n force?: boolean;\n dryRun?: boolean;\n strict?: boolean;\n }) => {\n void runFlushCommandCli({\n cwd: options.cwd,\n force: options.force,\n dryRun: options.dryRun,\n strict: options.strict,\n });\n },\n );\n\n program\n .command(\"inject\")\n .description(\"SessionStart hook:将 MEMORY.md 导航 + rules 注入到 stdout\")\n .option(\"-C, --cwd <dir>\", \"目标仓库根目录\")\n .option(\"--strict\", \"失败时 exit 1(hook 默认 exit 0)\")\n .action((options: { cwd?: string; strict?: boolean }) => {\n runInjectCommand({\n cwd: options.cwd,\n strict: options.strict,\n });\n });\n\n if (process.argv.length <= 2) {\n program.outputHelp();\n process.exit(0);\n }\n\n program.parse(process.argv);\n}\n\nmain();\n","import { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { RepoContext } from \"./types.js\";\nimport { memoryPath } from \"../init/paths.js\";\n\nexport const DEBUG_LOG_FILE = \"hermes-debug.log\";\n\nlet logFilePath: string | null = null;\n\nexport function configureDebugLogging(\n repoRoot: string | null,\n enabled: boolean,\n): void {\n if (!enabled || !repoRoot) {\n logFilePath = null;\n return;\n }\n logFilePath = memoryPath(repoRoot, DEBUG_LOG_FILE);\n}\n\nfunction formatLine(phase: string, message: string): string {\n return `${new Date().toISOString()} hermes-repo [${phase}] ${message}`;\n}\n\nfunction writeToLogFile(line: string): void {\n if (!logFilePath) {\n return;\n }\n mkdirSync(dirname(logFilePath), { recursive: true });\n appendFileSync(logFilePath, `${line}\\n`, \"utf8\");\n}\n\nexport function debugLog(\n enabled: boolean,\n phase: string,\n message: string,\n): void {\n if (!enabled) {\n return;\n }\n const line = formatLine(phase, message);\n console.error(line);\n writeToLogFile(line);\n}\n\nexport function debugFromContext(\n ctx: RepoContext | null | undefined,\n phase: string,\n message: string,\n): void {\n debugLog(ctx?.config.debug === true, phase, message);\n}\n","import { join } from \"node:path\";\n\nexport const MEMORY_DIR = \".memory\";\n\n/** v2 目录结构 */\nexport const MEMORY_SUBDIRS = [\n \"rules\",\n \"domains/general\",\n \"workflows\",\n \"decisions\",\n \"incidents\",\n \"captures/raw\",\n \"captures/archived\",\n] as const;\n\n/** 需要创建 .gitkeep 的目录(确保空目录能被 git 追踪) */\nexport const GITKEEP_DIRS = [\n \"rules\",\n \"domains/general\",\n \"workflows\",\n \"decisions\",\n \"incidents\",\n] as const;\n\n/** init 时复制的示例模板文件 */\nexport const EXAMPLE_TEMPLATE_FILES = [\n \"capture-session.example.md\",\n] as const;\n\n/** init 时生成的脚手架文件路径列表 */\nexport const SCAFFOLD_RELATIVE_PATHS = [\n \".memory/config.json\",\n \".memory/MEMORY.md\",\n \".memory/consolidate-state.json\",\n \"AGENTS.md\",\n \".claude/settings.local.json\",\n] as const;\n\nexport function memoryPath(root: string, ...segments: string[]): string {\n return join(root, MEMORY_DIR, ...segments);\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\nimport { findRepoRoot } from \"./findRepoRoot.js\";\nimport type {\n ConsolidateConfig,\n HermesConfig,\n LlmConfigV2,\n RepoContext,\n} from \"./types.js\";\n\nfunction isAssistantId(value: unknown): value is AssistantId {\n return typeof value === \"string\";\n}\n\nfunction parseLlmConfig(raw: Record<string, unknown>): LlmConfigV2 {\n const llm = raw.llm as Record<string, unknown> | undefined;\n return {\n enabled: typeof llm?.enabled === \"boolean\" ? llm.enabled : false,\n baseUrl: typeof llm?.baseUrl === \"string\" ? llm.baseUrl : \"https://api.openai.com/v1\",\n model: typeof llm?.model === \"string\" ? llm.model : \"gpt-4o\",\n };\n}\n\nfunction parseConsolidateConfig(raw: Record<string, unknown>): ConsolidateConfig {\n const c = raw.consolidate as Record<string, unknown> | undefined;\n return {\n autoArchiveDays: typeof c?.autoArchiveDays === \"number\" ? c.autoArchiveDays : 30,\n };\n}\n\nexport function readConfigAtRepo(repoRoot: string): HermesConfig | null {\n const configPath = join(repoRoot, \".memory\", \"config.json\");\n try {\n const raw = JSON.parse(readFileSync(configPath, \"utf8\")) as Record<string, unknown>;\n const version = raw.version;\n\n // v2 配置\n if (version === 2) {\n const assistants = Array.isArray(raw.assistants)\n ? raw.assistants.filter(isAssistantId)\n : [];\n return {\n version: 2,\n storage: { backend: (raw.storage as Record<string, unknown>)?.backend === \"file\" ? \"file\" : \"file\" },\n assistants,\n debug: raw.debug === true,\n llm: parseLlmConfig(raw),\n consolidate: parseConsolidateConfig(raw),\n };\n }\n\n // v1 兼容(自动升级字段)\n if (version === 1 || version === undefined) {\n const assistants = Array.isArray(raw.assistants)\n ? raw.assistants.filter(isAssistantId)\n : [];\n return {\n version: 2, // 自动升级为 v2\n storage: { backend: \"file\" },\n assistants,\n debug: raw.debug === true,\n llm: { enabled: false, baseUrl: \"https://api.openai.com/v1\", model: \"gpt-4o\" },\n consolidate: { autoArchiveDays: 30 },\n };\n }\n\n return null; // 不支持的版本\n } catch {\n return null;\n }\n}\n\nexport function loadRepoContext(cwd?: string): RepoContext | null {\n const repoRoot = findRepoRoot(cwd);\n if (!repoRoot) {\n return null;\n }\n const config = readConfigAtRepo(repoRoot);\n if (!config) {\n return null;\n }\n return { repoRoot, config };\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nconst CONFIG_REL = join(\".memory\", \"config.json\");\n\nexport function findRepoRoot(startDir?: string): string | null {\n let dir = resolve(startDir ?? process.cwd());\n\n while (true) {\n if (existsSync(join(dir, CONFIG_REL))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return null;\n }\n dir = parent;\n }\n}\n","import { existsSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport { isLlmAvailable } from \"../config/llmConfig.js\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport { parseJsonlFile } from \"./claude-code/parseJsonl.js\";\nimport {\n deleteLlmJob,\n listPendingJobs,\n readLlmJob,\n type LlmJobPayload,\n} from \"./enqueueLlmJob.js\";\nimport { llmFormat } from \"./formatCapture.js\";\nimport { renderCaptureMarkdown } from \"./writeCapture.js\";\n\nfunction captureAlreadyUpgraded(repoRoot: string, captureFile: string): boolean {\n const path = join(repoRoot, captureFile);\n if (!existsSync(path)) {\n return false;\n }\n const text = readFileSync(path, \"utf8\");\n return /llmUpgradedAt:/.test(text);\n}\n\nexport async function runLlmJob(\n repoRoot: string,\n job: LlmJobPayload,\n debug?: boolean,\n): Promise<{ ok: boolean; reason?: string }> {\n if (captureAlreadyUpgraded(repoRoot, job.captureFile)) {\n deleteLlmJob(repoRoot, job.jobId);\n return { ok: true, reason: \"already-upgraded\" };\n }\n\n const llm = readLlmConfigAtRepo(repoRoot);\n if (!isLlmAvailable(llm)) {\n return { ok: false, reason: \"llm not available\" };\n }\n\n if (!existsSync(job.jsonlPath)) {\n return { ok: false, reason: \"jsonl missing\" };\n }\n\n const session = parseJsonlFile(job.jsonlPath);\n const upgraded = await llmFormat(session, job.assistant, llm!);\n if (!upgraded) {\n debugLog(debug === true, \"capture-llm\", `llm job failed: ${job.jobId}`);\n return { ok: false, reason: \"llm format failed\" };\n }\n\n const target = join(repoRoot, job.captureFile);\n const temp = `${target}.hermes-tmp`;\n const date = new Date().toISOString().slice(0, 10);\n writeFileSync(temp, renderCaptureMarkdown(upgraded, date), \"utf8\");\n renameSync(temp, target);\n\n deleteLlmJob(repoRoot, job.jobId);\n debugLog(debug === true, \"capture-llm\", `ok: upgraded ${job.captureFile}`);\n return { ok: true };\n}\n\nexport async function runLlmJobById(\n repoRoot: string,\n jobId: string,\n debug?: boolean,\n): Promise<{ ok: boolean; reason?: string }> {\n const job = readLlmJob(repoRoot, jobId);\n if (!job) {\n return { ok: false, reason: \"job not found\" };\n }\n return runLlmJob(repoRoot, job, debug);\n}\n\nexport async function flushPendingLlmJobs(\n repoRoot: string,\n debug?: boolean,\n): Promise<number> {\n const jobs = listPendingJobs(repoRoot);\n let done = 0;\n for (const job of jobs) {\n const result = await runLlmJob(repoRoot, job, debug);\n if (result.ok) {\n done += 1;\n }\n }\n return done;\n}\n","export type LlmCaptureMode = \"async\" | \"sync\";\n\nexport interface LlmConfig {\n enabled: boolean;\n provider?: string;\n baseUrl: string;\n model: string;\n apiKey: string;\n timeoutMs: number;\n maxInputChars: number;\n mode: LlmCaptureMode;\n}\n\nexport const DEFAULT_LLM_TIMEOUT_MS = 60_000;\nexport const DEFAULT_LLM_MAX_INPUT_CHARS = 24_000;\nexport const DEFAULT_LLM_BASE_URL = \"https://api.deepseek.com\";\nexport const DEFAULT_LLM_MODEL = \"deepseek-v4-flash\";\n\nexport function defaultDisabledLlmConfig(): LlmConfig {\n return {\n enabled: false,\n provider: \"openai\",\n baseUrl: DEFAULT_LLM_BASE_URL,\n model: DEFAULT_LLM_MODEL,\n apiKey: \"\",\n timeoutMs: DEFAULT_LLM_TIMEOUT_MS,\n maxInputChars: DEFAULT_LLM_MAX_INPUT_CHARS,\n mode: \"async\",\n };\n}\n\nexport function isLlmAvailable(cfg: LlmConfig | null): boolean {\n if (!cfg?.enabled) {\n return false;\n }\n return (\n Boolean(cfg.apiKey?.trim()) &&\n Boolean(cfg.baseUrl?.trim()) &&\n Boolean(cfg.model?.trim())\n );\n}\n\n/** Env forces sync for tests; otherwise uses llm.json mode */\nexport function effectiveLlmMode(cfg: LlmConfig): LlmCaptureMode {\n const forceSync = process.env.HERMES_LLM_SYNC;\n if (forceSync === \"1\" || forceSync === \"true\") {\n return \"sync\";\n }\n return cfg.mode === \"sync\" ? \"sync\" : \"async\";\n}\n\nexport function parseLlmConfigRaw(raw: Record<string, unknown>): LlmConfig | null {\n if (raw.enabled !== true && raw.enabled !== false) {\n return null;\n }\n const baseUrl = typeof raw.baseUrl === \"string\" ? raw.baseUrl : \"\";\n const model = typeof raw.model === \"string\" ? raw.model : \"\";\n const apiKey = typeof raw.apiKey === \"string\" ? raw.apiKey : \"\";\n const timeoutMs =\n typeof raw.timeoutMs === \"number\" && raw.timeoutMs > 0\n ? raw.timeoutMs\n : DEFAULT_LLM_TIMEOUT_MS;\n const maxInputChars =\n typeof raw.maxInputChars === \"number\" && raw.maxInputChars > 0\n ? raw.maxInputChars\n : DEFAULT_LLM_MAX_INPUT_CHARS;\n const mode = raw.mode === \"sync\" ? \"sync\" : \"async\";\n const provider =\n typeof raw.provider === \"string\" ? raw.provider : \"openai\";\n\n return {\n enabled: raw.enabled,\n provider,\n baseUrl,\n model,\n apiKey,\n timeoutMs,\n maxInputChars,\n mode,\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { memoryPath } from \"../init/paths.js\";\nimport {\n defaultDisabledLlmConfig,\n parseLlmConfigRaw,\n type LlmConfig,\n} from \"./llmConfig.js\";\n\nexport function readLlmConfigAtRepo(repoRoot: string): LlmConfig | null {\n const llmPath = memoryPath(repoRoot, \"llm.json\");\n if (!existsSync(llmPath)) {\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(llmPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n return parseLlmConfigRaw(raw);\n } catch {\n return null;\n }\n}\n\n/** Missing file → disabled-shaped config for init defaults */\nexport function readLlmConfigOrDefault(repoRoot: string): LlmConfig {\n return readLlmConfigAtRepo(repoRoot) ?? defaultDisabledLlmConfig();\n}\n\nexport function serializeLlmConfig(cfg: LlmConfig): string {\n return `${JSON.stringify(cfg, null, 2)}\\n`;\n}\n","import { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport type { ParsedSession, SessionMessage } from \"../types.js\";\n\nconst FILE_CHANGE_TOOLS =\n /^(Write|Edit|MultiEdit|NotebookEdit|write|edit)$/i;\n\n/** CodeBuddy:跳过元数据行,避免干扰统计 */\nconst SKIP_LINE_TYPES = new Set([\n \"file-history-snapshot\",\n \"summary\",\n \"function_call_result\",\n]);\n\nfunction textFromContentParts(content: unknown): string {\n if (!Array.isArray(content)) {\n return \"\";\n }\n return content\n .map((part) => {\n if (!part || typeof part !== \"object\") {\n return \"\";\n }\n const p = part as Record<string, unknown>;\n if (typeof p.text === \"string\") {\n return p.text;\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction extractText(record: Record<string, unknown>): string {\n if (typeof record.content === \"string\") {\n return record.content;\n }\n if (Array.isArray(record.content)) {\n const top = textFromContentParts(record.content);\n if (top) {\n return top;\n }\n }\n const message = record.message;\n if (message && typeof message === \"object\") {\n const msg = message as Record<string, unknown>;\n if (typeof msg.content === \"string\") {\n return msg.content;\n }\n if (Array.isArray(msg.content)) {\n return textFromContentParts(msg.content);\n }\n }\n return \"\";\n}\n\nfunction inferRole(record: Record<string, unknown>): string {\n if (typeof record.role === \"string\") {\n return record.role;\n }\n if (typeof record.type === \"string\") {\n const t = record.type.toLowerCase();\n if (t === \"user\" || t === \"human\") return \"user\";\n if (t === \"assistant\") return \"assistant\";\n }\n return \"unknown\";\n}\n\nfunction isSkippedLine(record: Record<string, unknown>): boolean {\n const t = String(record.type ?? \"\").toLowerCase();\n return SKIP_LINE_TYPES.has(t);\n}\n\nfunction isToolUse(record: Record<string, unknown>): boolean {\n const t = String(record.type ?? \"\").toLowerCase();\n return t === \"tool_use\" || t === \"tool\" || t === \"function_call\";\n}\n\nfunction toolName(record: Record<string, unknown>): string {\n if (typeof record.name === \"string\") return record.name;\n const tool = record.tool;\n if (tool && typeof tool === \"object\" && \"name\" in tool) {\n return String((tool as { name: string }).name);\n }\n return \"\";\n}\n\n/** Cursor 等助手:tool_use 嵌在 message.content 数组内 */\nfunction countNestedTools(record: Record<string, unknown>): {\n toolCalls: number;\n fileChanges: number;\n} {\n let toolCalls = 0;\n let fileChanges = 0;\n const message = record.message;\n if (!message || typeof message !== \"object\") {\n return { toolCalls, fileChanges };\n }\n const content = (message as Record<string, unknown>).content;\n if (!Array.isArray(content)) {\n return { toolCalls, fileChanges };\n }\n for (const part of content) {\n if (!part || typeof part !== \"object\") {\n continue;\n }\n const p = part as Record<string, unknown>;\n const t = String(p.type ?? \"\").toLowerCase();\n if (t !== \"tool_use\" && t !== \"tool\") {\n continue;\n }\n toolCalls += 1;\n const name = typeof p.name === \"string\" ? p.name : \"\";\n if (FILE_CHANGE_TOOLS.test(name)) {\n fileChanges += 1;\n }\n }\n return { toolCalls, fileChanges };\n}\n\nexport function parseJsonlFile(jsonlPath: string): ParsedSession {\n const sessionId = basename(jsonlPath, \".jsonl\");\n const raw = readFileSync(jsonlPath, \"utf8\");\n const messages: SessionMessage[] = [];\n let fileChanges = 0;\n let toolCalls = 0;\n\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const record = JSON.parse(trimmed) as Record<string, unknown>;\n if (isSkippedLine(record)) {\n continue;\n }\n if (isToolUse(record)) {\n toolCalls += 1;\n const name = toolName(record);\n if (FILE_CHANGE_TOOLS.test(name)) {\n fileChanges += 1;\n }\n continue;\n }\n const nested = countNestedTools(record);\n toolCalls += nested.toolCalls;\n fileChanges += nested.fileChanges;\n const role = inferRole(record);\n const text = extractText(record);\n if (text) {\n messages.push({ role, text });\n }\n } catch {\n // skip malformed lines\n }\n }\n\n const text = messages.map((m) => m.text).join(\"\\n\");\n\n return {\n sessionId,\n messages,\n text,\n fileChanges,\n toolCalls,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { debugLog } from \"../config/debugLog.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\n\nexport interface LlmJobPayload {\n jobId: string;\n sessionId: string;\n jsonlPath: string;\n captureFile: string;\n assistant: AssistantId;\n enqueuedAt: string;\n}\n\nfunction pendingDir(repoRoot: string): string {\n return memoryPath(repoRoot, \"captures\", \"pending\");\n}\n\nfunction cliPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"..\", \"cli.js\");\n}\n\nfunction makeJobId(sessionId: string): string {\n const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, \"\").slice(0, 32);\n return `${Date.now()}-${safe || \"session\"}`;\n}\n\nfunction removeStaleJobsForSession(\n repoRoot: string,\n sessionId: string,\n): void {\n const dir = pendingDir(repoRoot);\n if (!existsSync(dir)) {\n return;\n }\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".json\")) {\n continue;\n }\n try {\n const raw = JSON.parse(\n readFileSync(join(dir, name), \"utf8\"),\n ) as LlmJobPayload;\n if (raw.sessionId === sessionId) {\n rmSync(join(dir, name), { force: true });\n }\n } catch {\n // skip\n }\n }\n}\n\nexport function enqueueLlmJob(opts: {\n repoRoot: string;\n sessionId: string;\n jsonlPath: string;\n captureFile: string;\n assistant: AssistantId;\n debug?: boolean;\n}): boolean {\n const { repoRoot, sessionId, jsonlPath, captureFile, assistant, debug } =\n opts;\n const dir = pendingDir(repoRoot);\n mkdirSync(dir, { recursive: true });\n removeStaleJobsForSession(repoRoot, sessionId);\n\n const jobId = makeJobId(sessionId);\n const payload: LlmJobPayload = {\n jobId,\n sessionId,\n jsonlPath,\n captureFile,\n assistant,\n enqueuedAt: new Date().toISOString(),\n };\n writeFileSync(\n join(dir, `${jobId}.json`),\n `${JSON.stringify(payload, null, 2)}\\n`,\n \"utf8\",\n );\n\n const child = spawn(\n process.execPath,\n [cliPath(), \"capture-llm\", \"--job\", jobId, \"-C\", repoRoot],\n {\n detached: true,\n stdio: \"ignore\",\n cwd: repoRoot,\n },\n );\n child.unref();\n\n debugLog(debug === true, \"capture\", `llm job enqueued: ${jobId}`);\n return true;\n}\n\nexport function readLlmJob(\n repoRoot: string,\n jobId: string,\n): LlmJobPayload | null {\n const path = join(pendingDir(repoRoot), `${jobId}.json`);\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as LlmJobPayload;\n } catch {\n return null;\n }\n}\n\nexport function deleteLlmJob(repoRoot: string, jobId: string): void {\n const path = join(pendingDir(repoRoot), `${jobId}.json`);\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nexport function listPendingJobs(repoRoot: string): LlmJobPayload[] {\n const dir = pendingDir(repoRoot);\n if (!existsSync(dir)) {\n return [];\n }\n const jobs: LlmJobPayload[] = [];\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(\".json\")) {\n continue;\n }\n try {\n jobs.push(\n JSON.parse(readFileSync(join(dir, name), \"utf8\")) as LlmJobPayload,\n );\n } catch {\n // skip\n }\n }\n return jobs;\n}\n","import type { ParsedSession } from \"../capture/types.js\";\n\nexport function buildSessionDigest(\n session: ParsedSession,\n maxChars: number,\n): string {\n const parts: string[] = [\n `sessionId: ${session.sessionId}`,\n `messages: ${session.messages.length}`,\n `toolCalls: ${session.toolCalls}`,\n `fileChanges: ${session.fileChanges}`,\n \"\",\n \"--- transcript (truncated) ---\",\n ];\n\n let used = parts.join(\"\\n\").length;\n const userFirst = [...session.messages].sort((a, b) => {\n if (a.role === \"user\" && b.role !== \"user\") return -1;\n if (b.role === \"user\" && a.role !== \"user\") return 1;\n return 0;\n });\n\n for (const m of userFirst) {\n const block = `[${m.role}]\\n${m.text.slice(0, 2000)}\\n`;\n if (used + block.length > maxChars) {\n parts.push(\"[... truncated ...]\");\n break;\n }\n parts.push(block);\n used += block.length;\n }\n\n return parts.join(\"\\n\");\n}\n","import type { CaptureMemoryType } from \"../capture/types.js\";\n\nexport interface LlmExtractResult {\n type: CaptureMemoryType;\n tags: string[];\n scope: string;\n title?: string;\n context: string;\n findings?: string;\n impact?: string;\n goal?: string;\n steps?: string[];\n cautions?: string[];\n verification?: string[];\n}\n\nconst VALID_TYPES = new Set<CaptureMemoryType>([\n \"semantic\",\n \"episodic\",\n \"procedural\",\n]);\n\nexport function parseLlmExtractJson(raw: unknown): LlmExtractResult | null {\n if (!raw || typeof raw !== \"object\") {\n return null;\n }\n const o = raw as Record<string, unknown>;\n const type = o.type;\n if (typeof type !== \"string\" || !VALID_TYPES.has(type as CaptureMemoryType)) {\n return null;\n }\n const context = typeof o.context === \"string\" ? o.context.trim() : \"\";\n if (!context) {\n return null;\n }\n const tags = Array.isArray(o.tags)\n ? o.tags.filter((t): t is string => typeof t === \"string\")\n : [];\n const scope =\n typeof o.scope === \"string\" && o.scope.trim()\n ? o.scope.trim()\n : \"all\";\n\n return {\n type: type as CaptureMemoryType,\n tags,\n scope,\n title: typeof o.title === \"string\" ? o.title : undefined,\n context,\n findings: typeof o.findings === \"string\" ? o.findings : undefined,\n impact: typeof o.impact === \"string\" ? o.impact : undefined,\n goal: typeof o.goal === \"string\" ? o.goal : undefined,\n steps: Array.isArray(o.steps)\n ? o.steps.filter((s): s is string => typeof s === \"string\")\n : undefined,\n cautions: Array.isArray(o.cautions)\n ? o.cautions.filter((s): s is string => typeof s === \"string\")\n : undefined,\n verification: Array.isArray(o.verification)\n ? o.verification.filter((s): s is string => typeof s === \"string\")\n : undefined,\n };\n}\n\nfunction listSection(title: string, items: string[] | undefined): string {\n if (!items?.length) {\n return \"\";\n }\n return `\\n\\n## ${title}\\n\\n${items.map((s, i) => `${i + 1}. ${s}`).join(\"\\n\")}`;\n}\n\nexport function renderBodyFromExtract(extract: LlmExtractResult): string {\n if (extract.type === \"procedural\") {\n const steps =\n extract.steps?.map((s, i) => `${i + 1}. ${s}`).join(\"\\n\") ??\n extract.findings ??\n \"(无步骤)\";\n const cautions =\n extract.cautions?.map((s) => `- ${s}`).join(\"\\n\") ?? \"(无)\";\n const verification =\n extract.verification?.map((s) => `- ${s}`).join(\"\\n\") ?? \"(无)\";\n return `## 目标\n\n${extract.goal ?? extract.context}\n\n## 步骤\n\n${steps}\n${extract.cautions?.length ? `\\n\\n## 注意\\n\\n${cautions}` : \"\"}\n${extract.verification?.length ? `\\n\\n## 验证\\n\\n${verification}` : \"\"}`;\n }\n\n return `## 上下文\n\n${extract.context}\n\n## 发现\n\n${extract.findings ?? extract.title ?? \"(见上下文)\"}\n\n## 影响\n\n${extract.impact ?? \"(待 consolidate 或人工补充)\"}`;\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport { buildSessionDigest } from \"./buildSessionDigest.js\";\nimport {\n parseLlmExtractJson,\n type LlmExtractResult,\n} from \"./renderCaptureFromJson.js\";\nimport type { ParsedSession } from \"../capture/types.js\";\n\nconst SYSTEM_PROMPT = `You extract project memory from an AI coding session transcript.\nRespond with a single JSON object only (no markdown fence), matching this shape:\n{\n \"type\": \"semantic\" | \"episodic\" | \"procedural\",\n \"tags\": [\"tag1\"],\n \"scope\": \"all\" | \"frontend\" | \"backend\",\n \"title\": \"short summary\",\n \"context\": \"what was being done\",\n \"findings\": \"facts/decisions/root cause (semantic/episodic)\",\n \"impact\": \"effect on future work\",\n \"goal\": \"for procedural only\",\n \"steps\": [\"step 1\"],\n \"cautions\": [\"pitfall\"],\n \"verification\": [\"how to verify\"]\n}\nUse procedural only for repeatable multi-step workflows. Use Chinese for content when the session is mainly Chinese.`;\n\nexport async function extractCaptureViaLlm(\n session: ParsedSession,\n llm: LlmConfig,\n): Promise<LlmExtractResult | null> {\n const digest = buildSessionDigest(session, llm.maxInputChars);\n const url = `${llm.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), llm.timeoutMs);\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${llm.apiKey}`,\n },\n body: JSON.stringify({\n model: llm.model,\n response_format: { type: \"json_object\" },\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n {\n role: \"user\",\n content: `Extract memory from this session:\\n\\n${digest}`,\n },\n ],\n temperature: 0.2,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n return parseLlmExtractJson(parsed);\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import type { LlmConfig } from \"../config/llmConfig.js\";\nimport { extractCaptureViaLlm } from \"../llm/chatCompletions.js\";\nimport {\n renderBodyFromExtract,\n type LlmExtractResult,\n} from \"../llm/renderCaptureFromJson.js\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\nimport type { CaptureMemoryType, ParsedSession } from \"./types.js\";\n\n/** 内联:推断 capture 类型(原 shouldCapture.ts,v2 保留用于 capture-llm 兼容) */\nfunction inferCaptureType(session: ParsedSession): \"semantic\" | \"episodic\" {\n const SEMANTIC_SIGNAL_RE =\n /约定|必须|架构|决策|规范|convention|pattern|always|never/i;\n if (SEMANTIC_SIGNAL_RE.test(session.text)) {\n return \"semantic\";\n }\n return \"episodic\";\n}\n\nexport interface FormattedCapture {\n type: CaptureMemoryType;\n sessionId: string;\n tags: string[];\n scope: string;\n bodyMarkdown: string;\n llmUpgradedAt?: string;\n}\n\nfunction assistantLabel(assistant: AssistantId): string {\n return assistant;\n}\n\nexport function simpleFormat(\n session: ParsedSession,\n assistant: AssistantId,\n): FormattedCapture {\n const type = inferCaptureType(session);\n const recent = session.messages.slice(-6);\n const context = recent\n .map((m) => `**${m.role}**: ${m.text.slice(0, 500)}`)\n .join(\"\\n\\n\");\n\n const bodyMarkdown = `## 上下文\n\n自动捕获自 ${assistantLabel(assistant)} 会话 \\`${session.sessionId}\\`。\n\n## 发现\n\n${context || \"(无提取内容)\"}\n\n## 影响\n\n(待 consolidate 或人工补充)`;\n\n return {\n type,\n sessionId: session.sessionId,\n tags: [\"auto-capture\", assistant],\n scope: \"all\",\n bodyMarkdown,\n };\n}\n\nexport function formattedFromLlmExtract(\n session: ParsedSession,\n assistant: AssistantId,\n extract: LlmExtractResult,\n): FormattedCapture {\n const tagSet = new Set([\"auto-capture\", assistant, ...extract.tags]);\n return {\n type: extract.type,\n sessionId: session.sessionId,\n tags: [...tagSet],\n scope: extract.scope,\n bodyMarkdown: renderBodyFromExtract(extract),\n llmUpgradedAt: new Date().toISOString(),\n };\n}\n\nexport async function llmFormat(\n session: ParsedSession,\n assistant: AssistantId,\n llm: LlmConfig,\n): Promise<FormattedCapture | null> {\n const extract = await extractCaptureViaLlm(session, llm);\n if (!extract) {\n return null;\n }\n return formattedFromLlmExtract(session, assistant, extract);\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { FormattedCapture } from \"./formatCapture.js\";\n\n// ─── Types ────────────────────────────────────────────\n\nexport type CaptureSource = \"session\" | \"commit\" | \"manual\";\n\nexport type SessionFileStatus = \"pending\" | \"done\" | \"stale\";\n\nexport interface SessionFileFrontmatter {\n sessionId: string;\n source: CaptureSource;\n status: SessionFileStatus;\n domain: string | null; // consolidate 后由 LLM 填写\n createdAt: string; // ISO 8601\n lastModifiedAt: string;\n consolidatedAt: string | null;\n captureCount: number;\n}\n\n// ─── Helpers ──────────────────────────────────────────\n\nfunction isoNow(): string {\n return new Date().toISOString();\n}\n\n/** 从已有文件中解析 frontmatter */\nfunction parseSessionFileFrontmatter(content: string): SessionFileFrontmatter | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n\n const frontmatter: Record<string, unknown> = {};\n for (const line of match[1].split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx === -1) continue;\n const key = line.slice(0, idx).trim();\n const val = line.slice(idx + 1).trim();\n\n // 解析布尔、null 和数字\n if (val === \"null\") frontmatter[key] = null;\n else if (val === \"true\") frontmatter[key] = true;\n else if (val === \"false\") frontmatter[key] = false;\n else if (/^\\d+$/.test(val)) frontmatter[key] = Number.parseInt(val, 10);\n else frontmatter[key] = val.replace(/^[\"']|[\"']$/g, \"\");\n }\n\n return frontmatter as unknown as SessionFileFrontmatter;\n}\n\n/** 序列化 frontmatter 为 YAML 块 */\nfunction serializeSessionFrontmatter(fm: SessionFileFrontmatter): string {\n const lines = [\n \"---\",\n `sessionId: ${fm.sessionId}`,\n `source: ${fm.source}`,\n `status: ${fm.status}`,\n `domain: ${fm.domain ?? null}`,\n `createdAt: ${fm.createdAt}`,\n `lastModifiedAt: ${fm.lastModifiedAt}`,\n `consolidatedAt: ${fm.consolidatedAt ?? null}`,\n `captureCount: ${fm.captureCount}`,\n \"---\",\n ];\n return lines.join(\"\\n\");\n}\n\n/** 格式化单个 capture 段落(追加到文件 body 中) */\nfunction renderCaptureSection(\n formatted: FormattedCapture,\n index: number,\n): string {\n const time = isoNow().slice(11, 19); // HH:mm:ss\n const tagsStr = formatted.tags.map((t) => JSON.stringify(t)).join(\", \");\n\n return [\n \"\",\n `## Capture #${index} — ${time}`,\n `### type: ${formatted.type}`,\n `### tags: [${tagsStr}]`,\n \"\",\n formatted.bodyMarkdown,\n ].join(\"\\n\");\n}\n\n// ─── Core: find or create session file ───────────────\n\n/**\n * 获取或创建 session 文件路径。\n * v2 规则:一个对话对应一个文件 `captures/raw/session-{id}.md`\n */\nexport function resolveSessionFile(\n repoRoot: string,\n sessionId: string,\n): { absolutePath: string; relativePath: string; exists: boolean } {\n const filename = `session-${sessionId}.md`;\n const absolutePath = memoryPath(repoRoot, \"captures\", \"raw\", filename);\n const relativePath = join(\".memory\", \"captures\", \"raw\", filename);\n return { absolutePath, relativePath, exists: existsSync(absolutePath) };\n}\n\n// ─── Legacy: renderCaptureMarkdown (LLM upgrade 用) ────\n\n/**\n * @deprecated v2 保留用于 LLM upgrade 兼容。Phase 2 将移除或重写为 session 文件的增量更新。\n */\nexport function renderCaptureMarkdown(\n formatted: FormattedCapture,\n date: string,\n): string {\n const tagsStr = formatted.tags.map((t) => JSON.stringify(t)).join(\", \");\n const lines = [\n \"---\",\n `type: ${formatted.type}`,\n `date: ${date}`,\n `session: ${formatted.sessionId}`,\n `tags: [${tagsStr}]`,\n `scope: ${formatted.scope}`,\n \"confidence: pending\",\n ];\n if (formatted.llmUpgradedAt) {\n lines.push(`llmUpgradedAt: ${formatted.llmUpgradedAt}`);\n }\n lines.push(\"---\", \"\", formatted.bodyMarkdown);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n// ─── Core: append capture to session file ─────────────\n\ninterface AppendCaptureResult {\n absolutePath: string;\n relativePath: string;\n filename: string;\n isNewFile: boolean;\n captureIndex: number;\n previousStatus: SessionFileStatus | null;\n}\n\n/**\n * 将一条 capture 追加到对应的 session 文件。\n *\n * 行为:\n * - 文件不存在 → 创建,status=pending\n * - 文件存在 → 追加新的 Capture 段落\n * - 若 status=done → 改为 stale(有新内容需重新 consolidate)\n * - 若 status=stale/pending → 保持不变\n */\nexport function appendCaptureToSession(\n repoRoot: string,\n formatted: FormattedCapture,\n): AppendCaptureResult {\n const { absolutePath, relativePath, exists } = resolveSessionFile(repoRoot, formatted.sessionId);\n const filename = `session-${formatted.sessionId}.md`;\n\n mkdirSync(join(absolutePath, \"..\"), { recursive: true });\n const now = isoNow();\n\n if (!exists) {\n // 新建文件\n const fm: SessionFileFrontmatter = {\n sessionId: formatted.sessionId,\n source: \"session\",\n status: \"pending\",\n domain: null,\n createdAt: now,\n lastModifiedAt: now,\n consolidatedAt: null,\n captureCount: 1,\n };\n\n const content =\n serializeSessionFrontmatter(fm) +\n \"\\n\" +\n renderCaptureSection(formatted, 1) +\n \"\\n\";\n\n writeFileSync(absolutePath, content, \"utf8\");\n\n return {\n absolutePath,\n relativePath,\n filename,\n isNewFile: true,\n captureIndex: 1,\n previousStatus: null,\n };\n }\n\n // 已有文件 → 追加\n const existingContent = readFileSync(absolutePath, \"utf8\");\n const existingFm = parseSessionFileFrontmatter(existingContent);\n\n if (!existingFm) {\n // 格式异常,覆盖写入\n const fm: SessionFileFrontmatter = {\n sessionId: formatted.sessionId,\n source: \"session\",\n status: \"pending\",\n domain: null,\n createdAt: now,\n lastModifiedAt: now,\n consolidatedAt: null,\n captureCount: 1,\n };\n\n writeFileSync(\n absolutePath,\n serializeSessionFrontmatter(fm) +\n \"\\n\" +\n renderCaptureSection(formatted, 1) +\n \"\\n\",\n \"utf8\",\n );\n return {\n absolutePath,\n relativePath,\n filename,\n isNewFile: false,\n captureIndex: 1,\n previousStatus: null,\n };\n }\n\n const previousStatus = existingFm.status;\n const nextIndex = existingFm.captureCount + 1;\n\n // 状态机:done → stale(有新内容需要重新处理)\n const newStatus: SessionFileStatus =\n existingFm.status === \"done\" ? \"stale\" : existingFm.status;\n\n const updatedFm: SessionFileFrontmatter = {\n ...existingFm,\n status: newStatus,\n lastModifiedAt: now,\n captureCount: nextIndex,\n };\n\n // 找到第一个 --- (frontmatter 结束位置)\n const fmEndIndex = existingContent.indexOf(\"---\", 4); // 跳过开头的 ---\n const bodyStart = fmEndIndex >= 0 ? fmEndIndex + 3 : existingContent.length;\n\n const updatedContent =\n serializeSessionFrontmatter(updatedFm) +\n \"\\n\" +\n existingContent.slice(bodyStart) + // 保留原有 body\n renderCaptureSection(formatted, nextIndex) + // 追加新的 capture 段落\n \"\\n\";\n\n writeFileSync(absolutePath, updatedContent, \"utf8\");\n\n return {\n absolutePath,\n relativePath,\n filename,\n isNewFile: false,\n captureIndex: nextIndex,\n previousStatus,\n };\n}\n\n// ─── Legacy compat: writeCaptureFile ──────────────────\n/**\n * @deprecated v2 使用 appendCaptureToSession 替代。保留此函数以兼容尚未迁移的调用方。\n */\nexport function writeCaptureFile(\n repoRoot: string,\n formatted: FormattedCapture,\n _filename?: string,\n): { absolutePath: string; filename: string } {\n const result = appendCaptureToSession(repoRoot, formatted);\n return { absolutePath: result.absolutePath, filename: result.filename };\n}\n\n/** 更新 session 文件的 consolidate 状态 */\nexport function markSessionConsolidated(\n repoRoot: string,\n sessionId: string,\n): void {\n const { absolutePath, exists } = resolveSessionFile(repoRoot, sessionId);\n if (!exists) return;\n\n const content = readFileSync(absolutePath, \"utf8\");\n const fm = parseSessionFileFrontmatter(content);\n if (!fm) return;\n\n const updatedFm: SessionFileFrontmatter = {\n ...fm,\n status: \"done\",\n consolidatedAt: isoNow(),\n };\n\n const fmEndIndex = content.indexOf(\"---\", 4);\n const bodyStart = fmEndIndex >= 0 ? fmEndIndex + 3 : content.length;\n\n writeFileSync(\n absolutePath,\n serializeSessionFrontmatter(updatedFm) + \"\\n\" + content.slice(bodyStart),\n \"utf8\",\n );\n}\n","import { debugLog } from \"./config/debugLog.js\";\n\n/** Hook 路径下失败仍 exit 0,避免阻塞 Claude Code */\nexport function hookExit(code: number, strict?: boolean): never {\n process.exit(strict ? code : code === 0 ? 0 : 0);\n}\n\nexport function finalizeHookCommand(\n fn: () => void | Promise<void>,\n strict?: boolean,\n debug?: boolean,\n): void {\n void (async () => {\n try {\n await fn();\n process.exit(0);\n } catch (error) {\n debugLog(debug === true, \"hook\", error instanceof Error ? error.message : String(error));\n process.exit(strict ? 1 : 0);\n }\n })();\n}\n","import { configureDebugLogging } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { flushPendingLlmJobs, runLlmJobById } from \"../capture/runLlmJob.js\";\nimport { finalizeHookCommand } from \"../hookExit.js\";\n\nexport interface CaptureLlmCommandOptions {\n cwd?: string;\n job?: string;\n flush?: boolean;\n strict?: boolean;\n}\n\nexport function runCaptureLlmCommand(opts: CaptureLlmCommandOptions): void {\n const ctx = loadRepoContext(opts.cwd);\n const debug = ctx?.config.debug === true;\n configureDebugLogging(ctx?.repoRoot ?? null, debug);\n\n finalizeHookCommand(async () => {\n if (!ctx) {\n console.error(\"hermes-repo: not initialized\");\n return;\n }\n const repoRoot = ctx.repoRoot;\n\n if (opts.flush) {\n const n = await flushPendingLlmJobs(repoRoot, debug);\n if (debug) {\n console.error(`hermes-repo: flushed ${n} llm job(s)`);\n }\n return;\n }\n\n if (!opts.job) {\n console.error(\"hermes-repo capture-llm: require --job <id> or --flush\");\n return;\n }\n\n const result = await runLlmJobById(repoRoot, opts.job, debug);\n if (!result.ok && opts.strict) {\n throw new Error(result.reason ?? \"capture-llm failed\");\n }\n }, opts.strict, debug);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport type HookInput = {\n /** Claude / CodeBuddy Stop hook(文件存在时已 resolve) */\n transcriptPath?: string;\n /** hook stdin 中的 transcript_path 原值(无论文件是否存在) */\n transcriptPathRaw?: string;\n hookEventName?: string;\n sessionId?: string;\n conversationId?: string;\n workspaceRoots?: string[];\n status?: string;\n};\n\nfunction pickString(obj: Record<string, unknown>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const v = obj[key];\n if (typeof v === \"string\" && v.length > 0) {\n return v;\n }\n }\n return undefined;\n}\n\nfunction pickStringArray(\n obj: Record<string, unknown>,\n ...keys: string[]\n): string[] | undefined {\n for (const key of keys) {\n const v = obj[key];\n if (Array.isArray(v)) {\n const roots = v.filter((x): x is string => typeof x === \"string\");\n if (roots.length > 0) {\n return roots;\n }\n }\n }\n return undefined;\n}\n\n/** 路径是否属于某助手 transcript 根目录 */\nexport function isTranscriptUnderAssistant(\n transcriptPath: string | undefined,\n segment: \".codebuddy\" | \".claude\",\n): boolean {\n if (!transcriptPath) {\n return false;\n }\n const normalized = transcriptPath.replace(/\\\\/g, \"/\");\n return normalized.includes(`${segment}/`);\n}\n\nexport function parseHookInputJson(raw: string): HookInput | null {\n const trimmed = raw.trim();\n if (!trimmed) {\n return null;\n }\n try {\n const parsed = JSON.parse(trimmed) as Record<string, unknown>;\n const transcriptRaw = pickString(parsed, \"transcript_path\", \"transcriptPath\");\n const transcriptPath =\n transcriptRaw && existsSync(transcriptRaw) ? resolve(transcriptRaw) : undefined;\n\n return {\n transcriptPath,\n transcriptPathRaw: transcriptRaw,\n hookEventName: pickString(parsed, \"hook_event_name\", \"hookEventName\"),\n sessionId: pickString(parsed, \"session_id\", \"sessionId\"),\n conversationId: pickString(parsed, \"conversation_id\", \"conversationId\"),\n workspaceRoots: pickStringArray(parsed, \"workspace_roots\", \"workspaceRoots\"),\n status: pickString(parsed, \"status\"),\n };\n } catch {\n return null;\n }\n}\n\n/** 从 hook stdin 读取一次(非 TTY 时) */\nexport function readHookInputSync(): HookInput | null {\n if (process.stdin.isTTY) {\n return null;\n }\n try {\n const raw = readFileSync(0, \"utf8\");\n return parseHookInputJson(raw);\n } catch {\n return null;\n }\n}\n\nexport function isCodebuddyCaptureHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n return (\n isTranscriptUnderAssistant(hook.transcriptPath, \".codebuddy\") ||\n isTranscriptUnderAssistant(hook.transcriptPathRaw, \".codebuddy\")\n );\n}\n\nexport function isClaudeCaptureHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n if (isCodebuddyCaptureHook(hook)) {\n return false;\n }\n if (isTranscriptUnderAssistant(hook.transcriptPath, \".claude\")) {\n return true;\n }\n if (hook.transcriptPath) {\n return true;\n }\n const name = hook.hookEventName?.toLowerCase();\n return name === \"stop\" && !hook.sessionId && !hook.conversationId;\n}\n\nexport function isCursorCaptureHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n if (hook.transcriptPath) {\n if (\n isTranscriptUnderAssistant(hook.transcriptPath, \".codebuddy\") ||\n isTranscriptUnderAssistant(hook.transcriptPath, \".claude\")\n ) {\n return false;\n }\n }\n const name = hook.hookEventName?.toLowerCase();\n if (name === \"stop\") {\n return true;\n }\n return Boolean(hook.sessionId || hook.conversationId);\n}\n\nexport function isCursorInjectHook(hook: HookInput | null | undefined): boolean {\n if (!hook) {\n return false;\n }\n const name = hook.hookEventName?.toLowerCase();\n return name === \"sessionstart\";\n}\n","import type { ParsedSession } from \"./types.js\";\n\n/**\n * 修复 3:信号强度分级\n * 从二元判断(有/无)改进为多级评分(强/中/弱/无)\n * 根据信号强度和对话复杂度加权决策\n */\n\nexport type SignalStrength = \"strong\" | \"medium\" | \"weak\" | \"none\";\n\nconst STRONG_SIGNAL_RE = /改成|不对|错了|应该是|决定用|约定是|必须|架构/i;\nconst MEDIUM_SIGNAL_RE =\n /考虑|也许|可能|试试|我们可以|看起来|似乎|建议|优化/i;\nconst WEAK_SIGNAL_RE = /为什么|怎样|怎么|什么时候|哪里|如何/i;\n\n/**\n * 判断文本的信号强度\n * strong: 明确的决策或纠正\n * medium: 有价值但不确定的建议\n * weak: 可能有价值的探索性问题\n * none: 无信号\n */\nexport function getSignalStrength(text: string): SignalStrength {\n if (STRONG_SIGNAL_RE.test(text)) {\n return \"strong\";\n }\n if (MEDIUM_SIGNAL_RE.test(text)) {\n return \"medium\";\n }\n if (WEAK_SIGNAL_RE.test(text)) {\n return \"weak\";\n }\n return \"none\";\n}\n\n/**\n * 根据信号强度和对话复杂度加权决策\n */\nexport function shouldCaptureBySignalStrength(session: ParsedSession): boolean {\n const strength = getSignalStrength(session.text);\n\n // 强信号:始终保留\n if (strength === \"strong\") {\n return true;\n }\n\n // 中等信号:需要多轮对话或复杂任务\n if (strength === \"medium\") {\n return session.messages.length >= 4 || session.toolCalls > 3;\n }\n\n // 弱信号:只有特别复杂的任务才保留\n if (strength === \"weak\") {\n return session.toolCalls > 8 || session.fileChanges > 5;\n }\n\n // 无信号:返回 false,让其他逻辑决策\n return false;\n}\n\n/**\n * 为捕获计算综合强度分数(0-100)\n * 考虑文本信号、会话复杂度、文件修改等多个因子\n */\nexport function computeSignalScore(session: ParsedSession): number {\n let score = 0;\n\n // 文本信号权重:30 分\n const strength = getSignalStrength(session.text);\n if (strength === \"strong\") {\n score += 30;\n } else if (strength === \"medium\") {\n score += 15;\n } else if (strength === \"weak\") {\n score += 5;\n }\n\n // 会话复杂度权重:30 分\n const messageBonus = Math.min(30, (session.messages.length - 2) * 5);\n score += Math.max(0, messageBonus);\n\n // 工具调用权重:20 分\n const toolBonus = Math.min(20, session.toolCalls * 2);\n score += toolBonus;\n\n // 文件修改权重:20 分\n const fileBonus = Math.min(20, session.fileChanges * 5);\n score += fileBonus;\n\n return Math.min(100, score);\n}\n\n/**\n * 根据综合分数决策是否捕获\n * < 40: 不捕获\n * 40-70: 边界情况(可选 LLM 判断)\n * > 70: 捕获\n */\nexport function shouldCaptureByScore(session: ParsedSession): boolean {\n const score = computeSignalScore(session);\n return score >= 70;\n}\n","import type { ParsedSession } from \"./types.js\";\nimport {\n computeSignalScore,\n getSignalStrength,\n} from \"./signalStrength.js\";\n\nconst ARCHITECTURE_SIGNAL_RE =\n /约定|必须|架构|决策|规范|根因|migration|refactor|convention|root cause/i;\nconst CORRECTION_RE =\n /不对|错了|不是这样|不应该|别用|stop|wrong|incorrect|改成|修正/i;\n\n/** 内联:用户纠正检测(原 shouldCapture.ts) */\nfunction hasUserCorrection(session: ParsedSession): boolean {\n return session.messages.some(\n (m) => m.role === \"user\" && CORRECTION_RE.test(m.text),\n );\n}\n\nexport function hasArchitectureSignal(text: string): boolean {\n return ARCHITECTURE_SIGNAL_RE.test(text);\n}\n\n/**\n * 判断会话是否需要 LLM 升级\n *\n * 触发条件(满足任一即可):\n * 1. 高复杂度:消息数、文件修改、工具调用达到阈值\n * 2. 强信号:明确决策、约定、架构相关\n * 3. 用户纠正:用户有纠正行为\n * 4. 组合条件:中等复杂度 + 中等信号\n * 5. 综合分数:分数 ≥ 55\n */\nexport function needsLlm(session: ParsedSession): boolean {\n // 1. 高复杂度会话\n if (session.messages.length >= 20) return true;\n if (session.fileChanges >= 3) return true;\n if (session.toolCalls >= 8) return true;\n\n // 2. 强信号(重要约定、决策应被 LLM 提炼)\n const strength = getSignalStrength(session.text);\n if (strength === \"strong\") return true;\n\n // 3. 架构信号\n if (hasArchitectureSignal(session.text)) return true;\n\n // 4. 用户纠正(纠正过程有价值,需要 LLM 总结)\n if (hasUserCorrection(session)) return true;\n\n // 5. 组合条件:中等复杂度 + 有实质工作\n if (session.messages.length >= 10 && session.toolCalls >= 5) return true;\n if (strength === \"medium\" && session.fileChanges >= 2) return true;\n if (session.toolCalls >= 5 && session.fileChanges >= 1) return true;\n\n // 6. 基于综合分数\n const score = computeSignalScore(session);\n if (score >= 55) return true;\n\n return false;\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { memoryPath } from \"../init/paths.js\";\n\n// ─── v2 状态模型 ─────────────────────────────\n\nexport interface SessionStatusRecord {\n status: \"pending\" | \"done\" | \"stale\";\n consolidatedAt: string | null;\n lastCaptureAt: string;\n}\n\nexport interface ConsolidateStateV2 {\n version: 2;\n lastConsolidatedAt: string;\n stats: {\n totalCapturesProcessed: number;\n domains: string[];\n knowledgeFilesCreated: number;\n };\n /** sessionId → status record */\n processedSessions: Record<string, SessionStatusRecord>;\n}\n\nconst EMPTY_STATE: ConsolidateStateV2 = {\n version: 2,\n lastConsolidatedAt: new Date(0).toISOString(),\n stats: {\n totalCapturesProcessed: 0,\n domains: [],\n knowledgeFilesCreated: 0,\n },\n processedSessions: {},\n};\n\nexport function consolidateStatePath(repoRoot: string): string {\n return memoryPath(repoRoot, \"consolidate-state.json\");\n}\n\nexport function consolidateLockPath(repoRoot: string): string {\n return memoryPath(repoRoot, \".consolidate.lock\");\n}\n\nexport function readConsolidateState(repoRoot: string): ConsolidateStateV2 {\n const path = consolidateStatePath(repoRoot);\n if (!existsSync(path)) {\n return { ...EMPTY_STATE, processedSessions: {} };\n }\n try {\n const raw = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n // v1 → v2 自动升级\n if (typeof raw === \"object\" && raw !== null) {\n const obj = raw as Record<string, unknown>;\n if (obj.version === 2 && typeof obj.processedSessions === \"object\") {\n return raw as ConsolidateStateV2;\n }\n // v1 升级:processedCapturePaths → 空 processedSessions\n return {\n ...EMPTY_STATE,\n lastConsolidatedAt:\n typeof obj.lastConsolidatedAt === \"string\"\n ? obj.lastConsolidatedAt\n : EMPTY_STATE.lastConsolidatedAt,\n };\n }\n return { ...EMPTY_STATE, processedSessions: {} };\n } catch {\n return { ...EMPTY_STATE, processedSessions: {} };\n }\n}\n\nexport function writeConsolidateState(\n repoRoot: string,\n state: ConsolidateStateV2,\n): void {\n const path = consolidateStatePath(repoRoot);\n mkdirSync(memoryPath(repoRoot), { recursive: true });\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`, \"utf8\");\n}\n\n// ─── Lock(保留不变)─────────────────────────\n\nexport interface ConsolidateLock {\n pid: number;\n startedAt: string;\n}\n\nexport function readConsolidateLock(repoRoot: string): ConsolidateLock | null {\n const path = consolidateLockPath(repoRoot);\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as ConsolidateLock;\n } catch {\n return null;\n }\n}\n\nexport function writeConsolidateLock(repoRoot: string): void {\n const payload: ConsolidateLock = {\n pid: process.pid,\n startedAt: new Date().toISOString(),\n };\n mkdirSync(memoryPath(repoRoot), { recursive: true });\n writeFileSync(\n consolidateLockPath(repoRoot),\n `${JSON.stringify(payload, null, 2)}\\n`,\n \"utf8\",\n );\n}\n\nexport function releaseConsolidateLock(repoRoot: string): void {\n const path = consolidateLockPath(repoRoot);\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nexport function isLockStale(\n lock: ConsolidateLock,\n ttlMs: number,\n): boolean {\n const started = Date.parse(lock.startedAt);\n if (Number.isNaN(started)) {\n return true;\n }\n return Date.now() - started > ttlMs;\n}\n","import { readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { SessionFileFrontmatter } from \"../capture/writeCapture.js\";\n\n// ─── Types ────────────────────────────────────\n\nexport interface ScannedSession {\n sessionId: string;\n filename: string;\n absolutePath: string;\n relativePath: string;\n frontmatter: SessionFileFrontmatter;\n bodyContent: string; // frontmatter 之后的完整 body\n}\n\n// ─── 解析 session 文件 frontmatter ───────────\n\nfunction parseSessionFrontmatter(\n content: string,\n): SessionFileFrontmatter | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n\n const fm: Record<string, unknown> = {};\n for (const line of match[1].split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx === -1) continue;\n const key = line.slice(0, idx).trim();\n const val = line.slice(idx + 1).trim();\n\n if (val === \"null\") fm[key] = null;\n else if (val === \"true\") fm[key] = true;\n else if (val === \"false\") fm[key] = false;\n else if (/^\\d+$/.test(val)) fm[key] = Number.parseInt(val, 10);\n else fm[key] = val.replace(/^[\"']|[\"']$/g, \"\");\n }\n\n return fm as unknown as SessionFileFrontmatter;\n}\n\n// ─── 扫描 captures/raw/ ──────────────────────\n\n/**\n * 扫描 captures/raw/ 下所有 session 文件,返回全部。\n */\nexport function scanAllSessions(repoRoot: string): ScannedSession[] {\n const rawDir = memoryPath(repoRoot, \"captures\", \"raw\");\n let files: string[];\n try {\n files = readdirSync(rawDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n\n const sessions: ScannedSession[] = [];\n for (const file of files) {\n const absolutePath = join(rawDir, file);\n try {\n const content = readFileSync(absolutePath, \"utf8\");\n const fm = parseSessionFrontmatter(content);\n if (!fm || !fm.sessionId) continue;\n\n // 提取 body(frontmatter 之后的内容)\n const fmEndIndex = content.indexOf(\"---\", 4);\n const bodyStart = fmEndIndex >= 0 ? fmEndIndex + 3 : content.length;\n const bodyContent = content.slice(bodyStart);\n\n sessions.push({\n sessionId: fm.sessionId,\n filename: file,\n absolutePath,\n relativePath: join(\".memory\", \"captures\", \"raw\", file),\n frontmatter: fm,\n bodyContent: bodyContent.trim(),\n });\n } catch {\n // 跳过无法解析的文件\n }\n }\n\n // 按最后修改时间倒序(优先处理最近的)\n sessions.sort(\n (a, b) =>\n new Date(b.frontmatter.lastModifiedAt).getTime() -\n new Date(a.frontmatter.lastModifiedAt).getTime(),\n );\n\n return sessions;\n}\n\n/**\n * 过滤出需要 consolidate 的 session 文件(pending + stale)。\n */\nexport function filterPendingSessions(\n sessions: ScannedSession[],\n): ScannedSession[] {\n return sessions.filter(\n (s) =>\n s.frontmatter.status === \"pending\" ||\n s.frontmatter.status === \"stale\",\n );\n}\n","import { readFileSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { LlmConfigV2 } from \"../config/types.js\";\nimport type { ScannedSession } from \"./sessionScanner.js\";\n\n// ─── Types ────────────────────────────────────\n\nexport interface ExistingKnowledge {\n path: string;\n title: string;\n type: \"rule\" | \"domain-knowledge\" | \"workflow\" | \"decision\" | \"incident\";\n domain: string | null;\n status: string;\n summary: string;\n}\n\nexport interface LlmConsolidateInput {\n pendingSessions: PendingSessionInput[];\n existingKnowledge: ExistingKnowledge[];\n currentMemoryMd: string | null;\n}\n\nexport interface PendingSessionInput {\n sessionId: string;\n status: \"pending\" | \"stale\";\n content: string; // 完整的 markdown(含 frontmatter + body)\n captureCount: number;\n createdAt: string;\n}\n\nexport interface KnowledgeFileOutput {\n targetPath: string;\n action: \"create\" | \"update\";\n frontmatter: Record<string, unknown>;\n body: string;\n}\n\nexport interface LlmConsolidateResult {\n knowledgeFiles: KnowledgeFileOutput[];\n memoryMd: string;\n skippedSessions: Array<{ sessionId: string; reason: string }>;\n}\n\n// ─── System Prompt ────────────────────────────\n\nconst CONSOLIDATE_SYSTEM_PROMPT = `你是一个项目知识整理专家。你的任务是从 AI 编程助手的对话记录中提炼出结构化的知识库。\n\n## 工作流程\n\n### 第一步:分析理解\n通读所有待处理的 session 记录,理解:\n- 讨论了哪些业务领域(模块、子系统、功能)\n- 产生了哪类知识(规范、事实、流程、决策、踩坑)\n- 哪些内容有长期保留价值,哪些是临时噪音\n\n### 第二步:域识别与匹配\n为每条有价值的内容确定所属业务域:\n- 查看 existingKnowledge 中已有的域列表\n- 优先复用已有域,只有确实无法匹配时才新建域\n- 无法归类的放入 general 域\n- 域名用 kebab-case,简洁明了(如 quoted, inventory, payment)\n- 不要创建过于细粒度的域(如不要按文件名建域)\n\n### 第三步:分类判定\n\n| 类型 | 判定条件 | 写入目录 |\n|------|---------|---------|\n| rule | 编码规范、约定、禁令 | rules/{name}.md |\n| domain-knowledge | 业务域的事实、概念、数据模型 | domains/{domain}/{name}.md |\n| workflow | 可复用的操作步骤、流程 | workflows/{name}.md |\n| decision | 架构选型、方案选择及原因 | decisions/{date}-{slug}.md |\n| incident | 踩坑记录、问题根因、修复方式 | incidents/{date}-{slug}.md |\n\n分类优先级:\n1. 如果是可执行的步骤流程 → workflow\n2. 如果是\"为什么选了X而不是Y\" → decision\n3. 如果是\"遇到了X问题,原因是Y,修法是Z\" → incident\n4. 如果是编码规范、团队约定 → rule\n5. 其余 → domain-knowledge(默认)\n\n### 第四步:内容提炼\n对归类后的内容进行提炼:\n\n提炼原则:\n1. 去除口语化表达、重复讨论、中间错误结论\n2. 保留最终确定的结论和关键决策过程\n3. 用结构化的 markdown 组织(标题、列表、表格、代码块)\n4. 区分\"事实\"和\"推断\",对不确定的内容标注 confidence: low\n5. 保留足够的上下文让未来阅读者理解背景\n\n如果是更新已有文件(action=update):\n- 对比新旧内容,保留仍有效的部分\n- 更新被修正的部分(标注更新日期)\n- 追加全新内容\n- 移除已被完全替代的旧段落\n\n### 第五步:生成导航 (MEMORY.md)\n重新生成导航页面:\n\n组织原则:\n1. rules 放最前(必读),每项一行:[路径](链接) — 摘要\n2. domains 按域分组表格展示\n3. workflows 简短列出\n4. decisions/incidents 只显示计数和最近几条\n5. 每个摘要控制在 20 字以内\n6. 整体保持紧凑(目标 < 100 行),AI 注入时不会太长\n7. 保留用户的自定义编辑标记 <!-- user-edit-start --> ... <!-- user-edit-end -->\n\n## 输出要求\n- 输出严格 JSON 格式\n- knowledgeFiles 数组包含所有需要创建/更新的文件\n - 每项必须包含完整的 frontmatter 和 body markdown\n- memoryMd 是完整 MEMORY.md 内容\n- 无价值的 session 在 skippedSessions 中说明原因(而非生成空内容)`;\n\n// ─── 扫描已有知识文件 ───────────────────────\n\n/**\n * 扫描 rules/, domains/, workflows/, decisions/, incidents/\n * 返回已有知识文件的摘要列表。\n */\nexport function scanExistingKnowledge(repoRoot: string): ExistingKnowledge[] {\n const results: ExistingKnowledge[] = [];\n\n // 定义各类型目录和对应的 type\n const typeDirs: Array<{ dir: string; type: ExistingKnowledge[\"type\"] }> = [\n { dir: \"rules\", type: \"rule\" },\n { dir: \"workflows\", type: \"workflow\" },\n { dir: \"decisions\", type: \"decision\" },\n { dir: \"incidents\", type: \"incident\" },\n ];\n\n for (const { dir, type } of typeDirs) {\n const absDir = memoryPath(repoRoot, dir);\n scanMarkdownDirectory(absDir, dir, type, null, results);\n }\n\n // domains 下可能有多个子目录\n const domainsDir = memoryPath(repoRoot, \"domains\");\n try {\n const subdirs = readdirSync(domainsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n\n for (const domain of subdirs) {\n const domainAbsDir = join(domainsDir, domain);\n scanMarkdownDirectory(\n domainAbsDir,\n `domains/${domain}`,\n \"domain-knowledge\",\n domain,\n results,\n );\n }\n } catch {\n // domains 目录不存在\n }\n\n return results;\n}\n\nfunction scanMarkdownDirectory(\n absoluteDir: string,\n relativePrefix: string,\n type: ExistingKnowledge[\"type\"],\n domain: string | null,\n results: ExistingKnowledge[],\n): void {\n let files: string[];\n try {\n files = readdirSync(absoluteDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return;\n }\n\n for (const file of files) {\n try {\n const content = readFileSync(join(absoluteDir, file), \"utf8\");\n // 解析 frontmatter 提取 title\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n let title = file.replace(/\\.md$/, \"\");\n if (fmMatch) {\n const titleMatch = fmMatch[1].match(/^title:\\s*(.+)$/m);\n if (titleMatch) title = titleMatch[1].replace(/^[\"']|[\"']$/g, \"\");\n }\n\n // 取前 100 字作为摘要\n const bodyStart = content.indexOf(\"---\", 4);\n const body =\n bodyStart >= 0 ? content.slice(bodyStart + 3).trim() : content;\n const summary = body.slice(0, 150).replace(/\\n/g, \" \").trim();\n\n results.push({\n path: `${relativePrefix}/${file}`,\n title,\n type,\n domain,\n status: \"active\",\n summary,\n });\n } catch {\n // 跳过无法读取的文件\n }\n }\n}\n\n// ─── 构建 LLM Input ──────────────────────────\n\nexport function buildLlmConsolidateInput(\n repoRoot: string,\n sessions: ScannedSession[],\n): LlmConsolidateInput {\n const pendingSessions: PendingSessionInput[] = sessions.map((s) => ({\n sessionId: s.sessionId,\n status: s.frontmatter.status as \"pending\" | \"stale\",\n content: readFileSync(s.absolutePath, \"utf8\"),\n captureCount: s.frontmatter.captureCount,\n createdAt: s.frontmatter.createdAt,\n }));\n\n const existingKnowledge = scanExistingKnowledge(repoRoot);\n\n // 读取当前 MEMORY.md\n const memoryPathAbs = memoryPath(repoRoot, \"MEMORY.md\");\n let currentMemoryMd: string | null = null;\n try {\n currentMemoryMd = readFileSync(memoryPathAbs, \"utf8\");\n } catch {\n // 不存在则传 null\n }\n\n return {\n pendingSessions,\n existingKnowledge,\n currentMemoryMd,\n };\n}\n\n// ─── 调用 LLM ────────────────────────────────\n\n/**\n * 单次 LLM 调用完成完整 consolidate。\n *\n * @throws 当 LLM 未配置或调用失败时抛出错误\n */\nexport async function callLlmConsolidate(\n input: LlmConsolidateInput,\n llmConfig: LlmConfigV2,\n): Promise<LlmConsolidateResult> {\n const apiKey = process.env.HERMES_LLM_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"LLM 未配置:请设置 HERMES_LLM_API_KEY 环境变量\",\n );\n }\n\n if (!llmConfig.enabled) {\n throw new Error(\n \"LLM 未启用:请在 config.json 中设置 llm.enabled = true\",\n );\n }\n\n const url = `${llmConfig.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n\n // 构造 user message — 将 input 序列化为 JSON\n const userContent = formatUserMessage(input);\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 120_000); // 2 分钟超时\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: llmConfig.model,\n response_format: { type: \"json_object\" },\n messages: [\n { role: \"system\", content: CONSOLIDATE_SYSTEM_PROMPT },\n { role: \"user\", content: userContent },\n ],\n temperature: 0.2,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const errBody = await res.text().catch(() => \"\");\n throw new Error(\n `LLM API 错误 (${res.status}): ${errBody.slice(0, 300)}`,\n );\n }\n\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n const rawContent = data.choices?.[0]?.message?.content;\n\n if (!rawContent) {\n throw new Error(\"LLM 返回内容为空\");\n }\n\n // 解析 JSON\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawContent);\n } catch {\n throw new Error(\"LLM 返回内容不是合法 JSON\");\n }\n\n return validateAndNormalizeLlmResult(parsed);\n } finally {\n clearTimeout(timeout);\n }\n}\n\n// ─── 格式化 user message ─────────────────────\n\nfunction formatUserMessage(input: LlmConsolidateInput): string {\n // 截断 session 内容避免过长(保留前 8000 字符)\n const maxSessionChars = 8000;\n const truncatedSessions = input.pendingSessions.map((s) => ({\n ...s,\n content:\n s.content.length > maxSessionChars\n ? s.content.slice(0, maxSessionChars) +\n `\\n\\n... [截断,原始长度: ${s.content.length} 字符]`\n : s.content,\n }));\n\n return JSON.stringify(\n {\n pendingSessions: truncatedSessions,\n existingKnowledge: input.existingKnowledge.map((k) => ({\n path: k.path,\n title: k.title,\n type: k.type,\n domain: k.domain,\n status: k.status,\n summary: k.summary,\n })),\n currentMemoryMd: input.currentMemoryMd ?? \"\",\n },\n null,\n 2,\n );\n}\n\n// ─── 验证 & 标准化 LLM 返回结果 ───────────────\n\nfunction validateAndNormalizeLlmResult(\n raw: unknown,\n): LlmConsolidateResult {\n if (!raw || typeof raw !== \"object\") {\n throw new Error(\"LLM 返回格式错误:期望 JSON 对象\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n const knowledgeFiles: KnowledgeFileOutput[] = Array.isArray(obj.knowledgeFiles)\n ? (obj.knowledgeFiles as unknown[]).map(normalizeKnowledgeFile).filter(Boolean) as KnowledgeFileOutput[]\n : [];\n\n const memoryMd =\n typeof obj.memoryMd === \"string\"\n ? obj.memoryMd\n : \"# 项目知识库\\n\\n> 待 consolidate\";\n\n const skippedSessions: Array<{ sessionId: string; reason: string }> = Array.isArray(\n obj.skippedSessions,\n )\n ? (obj.skippedSessions as unknown[]).filter(isSkippedEntry)\n : [];\n\n return { knowledgeFiles, memoryMd, skippedSessions };\n}\n\nfunction normalizeKnowledgeFile(raw: unknown): KnowledgeFileOutput | null {\n if (!raw || typeof raw !== \"object\") return null;\n const obj = raw as Record<string, unknown>;\n\n if (\n typeof obj.targetPath !== \"string\" ||\n ![\"create\", \"update\"].includes(obj.action as string) ||\n typeof obj.body !== \"string\"\n ) {\n return null;\n }\n\n return {\n targetPath: obj.targetPath,\n action: obj.action as \"create\" | \"update\",\n frontmatter:\n typeof obj.frontmatter === \"object\" && obj.frontmatter !== null\n ? (obj.frontmatter as Record<string, unknown>)\n : {},\n body: obj.body as string,\n };\n}\n\nfunction isSkippedEntry(raw: unknown): raw is { sessionId: string; reason: string } {\n if (!raw || typeof raw !== \"object\") return false;\n const obj = raw as Record<string, unknown>;\n return (\n typeof obj.sessionId === \"string\" && typeof obj.reason === \"string\"\n );\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { KnowledgeFileOutput } from \"./llmConsolidateV2.js\";\n\n// ─── Types ────────────────────────────────────\n\nexport interface WriteKnowledgeResult {\n created: string[];\n updated: string[];\n failed: string[];\n}\n\n// ─── 写入知识文件 ─────────────────────────────\n\n/**\n * 将 LLM 返回的 knowledgeFiles 数组写入磁盘。\n *\n * - targetPath 相对于 .memory/ 根目录\n * - 自动创建所需子目录\n * - action=\"create\" 仅在新文件时写入\n * - action=\"update\" 总是覆盖\n */\nexport function writeKnowledgeFiles(\n repoRoot: string,\n files: KnowledgeFileOutput[],\n): WriteKnowledgeResult {\n const result: WriteKnowledgeResult = {\n created: [],\n updated: [],\n failed: [],\n };\n\n for (const kf of files) {\n try {\n const absolutePath = memoryPath(repoRoot, kf.targetPath);\n const dir = dirname(absolutePath);\n\n mkdirSync(dir, { recursive: true });\n\n // 序列化 frontmatter + body\n const content = serializeKnowledgeFile(kf.frontmatter, kf.body);\n\n const alreadyExists = existsSync(absolutePath);\n\n if (kf.action === \"create\" && alreadyExists) {\n // create 但已存在,降级为 update\n result.updated.push(kf.targetPath);\n } else if (kf.action === \"create\") {\n result.created.push(kf.targetPath);\n } else {\n result.updated.push(kf.targetPath);\n }\n\n writeFileSync(absolutePath, content, \"utf8\");\n } catch (err) {\n result.failed.push(kf.targetPath);\n console.error(\n `[consolidate] 写入知识文件失败: ${kf.targetPath}: ${(err as Error).message}`,\n );\n }\n }\n\n return result;\n}\n\n// ─── 写入 MEMORY.md ──────────────────────────\n\n/**\n * 将 LLM 生成的 MEMORY.md 写入磁盘。\n * 保留用户自定义编辑标记 <!-- user-edit-start --> ... <!-- user-edit-end -->\n */\nexport function writeMemoryMd(\n repoRoot: string,\n memoryMd: string,\n): void {\n const memoryPathAbs = memoryPath(repoRoot, \"MEMORY.md\");\n\n // 如果已有文件且包含用户编辑标记,尝试保留用户自定义区域\n if (existsSync(memoryPathAbs)) {\n const existing = require(\"node:fs\").readFileSync(memoryPathAbs, \"utf8\");\n const preserved = extractUserEditedSections(existing);\n if (preserved.length > 0) {\n memoryMd = injectUserSections(memoryMd, preserved);\n }\n }\n\n mkdirSync(memoryPath(repoRoot), { recursive: true });\n writeFileSync(memoryPathAbs, `${memoryMd}\\n`, \"utf8\");\n}\n\n// ─── 序列化知识文件 ─────────────────────────\n\nfunction serializeKnowledgeFile(\n frontmatter: Record<string, unknown>,\n body: string,\n): string {\n const lines = [\"---\"];\n\n // 固定顺序输出常用字段\n const fieldOrder = [\"title\", \"domain\", \"type\", \"status\", \"confidence\", \"lastReviewed\"];\n const emitted = new Set<string>();\n\n for (const key of fieldOrder) {\n if (key in frontmatter && frontmatter[key] !== undefined && frontmatter[key] !== null) {\n lines.push(`${key}: ${formatYamlValue(frontmatter[key])}`);\n emitted.add(key);\n }\n }\n\n // sourceSessions 数组特殊处理\n if (Array.isArray(frontmatter.sourceSessions)) {\n lines.push(\"sourceSessions:\");\n for (const s of frontmatter.sourceSessions) {\n lines.push(` - ${s}`);\n }\n emitted.add(\"sourceSessions\");\n }\n\n // 其余字段\n for (const [key, val] of Object.entries(frontmatter)) {\n if (!emitted.has(key) && val !== undefined && val !== null) {\n lines.push(`${key}: ${formatYamlValue(val)}`);\n }\n }\n\n lines.push(\"---\", \"\", body);\n\n return lines.join(\"\\n\");\n}\n\nfunction formatYamlValue(val: unknown): string {\n if (Array.isArray(val)) {\n return `[${val.map(String).join(\", \")}]`;\n }\n return String(val);\n}\n\n// ─── 用户编辑区保留 ──────────────────────────\n\ninterface UserSection {\n marker: string;\n content: string;\n}\n\n/** 提取 <!-- user-edit-start --> ... <!-- user-edit-end --> 区块 */\nfunction extractUserEditedSections(content: string): UserSection[] {\n const sections: UserSection[] = [];\n const regex = /<!--\\s*user-edit-start\\s*-->\\n?([\\s\\S]*?)\\n?<!--\\s*user-edit-end\\s*-->/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(content)) !== null) {\n sections.push({\n marker: match[0].split(\"\\n\")[0], // 取开始标记行\n content: match[1],\n });\n }\n return sections;\n}\n\n/** 将用户编辑区注入到新内容中同名的标记位置 */\nfunction injectUserSections(\n newContent: string,\n sections: UserSection[],\n): string {\n let result = newContent;\n for (const section of sections) {\n // 用原有内容替换同名标记区块\n const startMarker = section.marker;\n const endMarker = \"<!-- user-edit-end -->\";\n\n const startIdx = result.indexOf(startMarker);\n if (startIdx === -1) continue;\n\n const endIdx = result.indexOf(endMarker, startIdx);\n if (endIdx === -1) continue;\n\n result =\n result.slice(0, startIdx) +\n `${startMarker}\\n${section.content}\\n${endMarker}` +\n result.slice(endIdx + endMarker.length);\n }\n return result;\n}\n","import { existsSync, mkdirSync, renameSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { memoryPath } from \"../init/paths.js\";\nimport type { SessionFileFrontmatter } from \"../capture/writeCapture.js\";\nimport type { ScannedSession } from \"./sessionScanner.js\";\n\n/**\n * 将符合条件的已处理 capture 文件从 raw/ 移动到 archived/\n *\n * 条件:\n * - status === \"done\"\n * - consolidatedAt 距今超过 autoArchiveDays 天(默认 30)\n */\nexport function archiveDoneSessions(\n repoRoot: string,\n sessions: ScannedSession[],\n autoArchiveDays: number = 30,\n): number {\n const archivedDir = memoryPath(repoRoot, \"captures\", \"archived\");\n const cutoffMs = Date.now() - autoArchiveDays * 24 * 60 * 60 * 1000;\n\n let archivedCount = 0;\n\n for (const s of sessions) {\n if (s.frontmatter.status !== \"done\") continue;\n if (!s.frontmatter.consolidatedAt) continue;\n\n const consolidatedTime = Date.parse(s.frontmatter.consolidatedAt);\n if (Number.isNaN(consolidatedTime)) continue;\n if (consolidatedTime > cutoffMs) continue; // 还没过期\n\n try {\n mkdirSync(archivedDir, { recursive: true });\n renameSync(s.absolutePath, join(archivedDir, s.filename));\n archivedCount++;\n } catch {\n // 忽略移动失败(可能文件已被其他进程删除)\n }\n }\n\n return archivedCount;\n}\n","import { debugLog } from \"../config/debugLog.js\";\nimport { type HermesConfig, type LlmConfigV2, type RepoContext } from \"../config/types.js\";\nimport {\n readConsolidateState,\n releaseConsolidateLock,\n writeConsolidateLock,\n writeConsolidateState,\n} from \"./state.js\";\nimport { scanAllSessions, filterPendingSessions, type ScannedSession } from \"./sessionScanner.js\";\nimport {\n buildLlmConsolidateInput,\n callLlmConsolidate,\n} from \"./llmConsolidateV2.js\";\nimport { writeKnowledgeFiles, writeMemoryMd } from \"./writeKnowledge.js\";\nimport { archiveDoneSessions } from \"./archive.js\";\nimport { markSessionConsolidated } from \"../capture/writeCapture.js\";\n\n// ─── Options & Result ────────────────────────\n\nexport interface RunConsolidateOptions {\n repoRoot: string;\n config: HermesConfig;\n force?: boolean;\n dryRun?: boolean;\n debug?: boolean;\n}\n\nexport interface ConsolidateResultV2 {\n ran: boolean;\n reason?: string;\n sessionsProcessed: number; // 处理的 session 文件数\n knowledgeCreated: number; // 新建知识文件数\n knowledgeUpdated: number; // 更新知识文件数\n skippedCount: number; // 跳过的 session 数\n archived: number; // 归档的文件数\n}\n\n// ─── Main orchestrator ───────────────────────\n\n/**\n * v2 consolidate 主函数:\n *\n * 1. 扫描 captures/raw/ 中 pending/stale 的 session 文件\n * 2. 构造 LLM 输入(sessions + 已有知识 + MEMORY.md)\n * 3. 单次 LLM 调用 → 知识文件 + MEMORY.md\n * 4. 写入磁盘(knowledge files + MEMORY.md)\n * 5. 更新 session 状态 → done\n * 6. 自动归档过期 done 文件\n */\nexport async function runConsolidate(\n opts: RunConsolidateOptions,\n): Promise<ConsolidateResultV2> {\n const { repoRoot, config, force, dryRun, debug } = opts;\n\n writeConsolidateLock(repoRoot);\n try {\n const llmConfig: LlmConfigV2 = config.llm;\n\n if (!llmConfig.enabled) {\n return {\n ran: false,\n reason: \"llm-not-enabled\",\n sessionsProcessed: 0,\n knowledgeCreated: 0,\n knowledgeUpdated: 0,\n skippedCount: 0,\n archived: 0,\n };\n }\n\n // Step 1: 扫描 session 文件\n const allSessions = scanAllSessions(repoRoot);\n const pendingSessions = force\n ? allSessions\n : filterPendingSessions(allSessions);\n\n debugLog(\n debug === true,\n \"consolidate\",\n `扫描到 ${allSessions.length} 个 session,其中 ${pendingSessions.length} 个待处理`,\n );\n\n if (pendingSessions.length === 0 && !force) {\n return {\n ran: false,\n reason: \"no-pending-sessions\",\n sessionsProcessed: 0,\n knowledgeCreated: 0,\n knowledgeUpdated: 0,\n skippedCount: 0,\n archived: 0,\n };\n }\n\n // dry-run:只返回预览信息\n if (dryRun) {\n return {\n ran: true,\n reason: \"dry-run\",\n sessionsProcessed: pendingSessions.length,\n knowledgeCreated: 0,\n knowledgeUpdated: 0,\n skippedCount: 0,\n archived: 0,\n };\n }\n\n // Step 2: 构造 LLM 输入\n const llmInput = buildLlmConsolidateInput(repoRoot, pendingSessions);\n debugLog(debug === true, \"consolidate\", `LLM 输入: ${llmInput.pendingSessions.length} sessions, ${llmInput.existingKnowledge.length} existing knowledge`);\n\n // Step 3: 单次 LLM 调用\n let llmResult;\n try {\n llmResult = await callLlmConsolidate(llmInput, llmConfig);\n } catch (err) {\n console.error(`[consolidate] LLM 调用失败: ${(err as Error).message}`);\n throw err;\n }\n\n debugLog(\n debug === true,\n \"consolidate\",\n `LLM 返回: ${llmResult.knowledgeFiles.length} knowledge files, ${llmResult.skippedSessions.length} skipped`,\n );\n\n // Step 4: 写入知识文件 + MEMORY.md\n const writeResult = writeKnowledgeFiles(repoRoot, llmResult.knowledgeFiles);\n writeMemoryMd(repoRoot, llmResult.memoryMd);\n\n // Step 5: 更新 session 状态为 done\n const processedSessionIds = new Set<string>();\n for (const s of pendingSessions) {\n markSessionConsolidated(repoRoot, s.sessionId);\n processedSessionIds.add(s.sessionId);\n }\n // 也标记 skipped 的 session 为 done(已评估过)\n for (const ss of llmResult.skippedSessions) {\n markSessionConsolidated(repoRoot, ss.sessionId);\n processedSessionIds.add(ss.sessionId);\n }\n\n // Step 6: 更新 consolidate-state.json\n const prevState = readConsolidateState(repoRoot);\n const newDomains = extractDomainsFromResults(llmResult.knowledgeFiles);\n\n writeConsolidateState(repoRoot, {\n version: 2,\n lastConsolidatedAt: new Date().toISOString(),\n stats: {\n totalCapturesProcessed:\n prevState.stats.totalCapturesProcessed +\n pendingSessions.reduce((sum, s) => sum + s.frontmatter.captureCount, 0),\n domains: [...new Set([...prevState.stats.domains, ...newDomains])],\n knowledgeFilesCreated:\n prevState.stats.knowledgeFilesCreated +\n writeResult.created.length,\n },\n processedSessions: {\n ...prevState.processedSessions,\n ...Object.fromEntries(\n [...processedSessionIds].map((id) => [\n id,\n { status: \"done\" as const, consolidatedAt: new Date().toISOString(), lastCaptureAt: new Date().toISOString() },\n ]),\n ),\n },\n });\n\n // Step 7: 自动归档\n const archived = archiveDoneSessions(\n repoRoot,\n allSessions,\n config.consolidate.autoArchiveDays,\n );\n\n return {\n ran: true,\n sessionsProcessed: pendingSessions.length,\n knowledgeCreated: writeResult.created.length,\n knowledgeUpdated: writeResult.updated.length,\n skippedCount: llmResult.skippedSessions.length,\n archived,\n };\n } finally {\n releaseConsolidateLock(repoRoot);\n }\n}\n\n// ─── Helpers ─────────────────────────────────\n\n/** 从 LLM 返回结果中提取所有涉及到的域名 */\nfunction extractDomainsFromResults(\n files: Array<{ frontmatter: Record<string, unknown> }>,\n): string[] {\n const domains = new Set<string>();\n for (const f of files) {\n const domain = f.frontmatter.domain;\n if (typeof domain === \"string\" && domain && domain !== \"null\") {\n domains.add(domain);\n }\n }\n return [...domains];\n}\n","/** 运行锁过期(毫秒) */\nexport const CONSOLIDATE_LOCK_TTL_MS = 30 * 60 * 1000;\n","import { loadRepoContext } from \"../config/readConfig.js\";\nimport {\n runConsolidate,\n type ConsolidateResultV2,\n} from \"./runConsolidate.js\";\nimport { CONSOLIDATE_LOCK_TTL_MS } from \"./constants.js\";\nimport { scanAllSessions, filterPendingSessions } from \"./sessionScanner.js\";\nimport { readConsolidateLock, isLockStale } from \"./state.js\";\n\n/**\n * v2: flush 命令入口。\n * 直接调用 runConsolidate(单次 LLM 调用)。\n */\nexport async function runFlushCommand(opts: {\n cwd?: string;\n force?: boolean;\n dryRun?: boolean;\n debug?: boolean;\n}): Promise<ConsolidateResultV2> {\n const ctx = loadRepoContext(opts.cwd);\n if (!ctx) {\n return {\n ran: false,\n reason: \"not-initialized\",\n sessionsProcessed: 0,\n knowledgeCreated: 0,\n knowledgeUpdated: 0,\n skippedCount: 0,\n archived: 0,\n };\n }\n\n // 检查是否有可处理的 session\n const allSessions = scanAllSessions(ctx.repoRoot);\n const pendingSessions = opts.force\n ? allSessions\n : filterPendingSessions(allSessions);\n\n if (pendingSessions.length === 0 && !opts.force && !opts.dryRun) {\n return {\n ran: false,\n reason: \"no-pending-sessions\",\n sessionsProcessed: 0,\n knowledgeCreated: 0,\n knowledgeUpdated: 0,\n skippedCount: 0,\n archived: 0,\n };\n }\n\n return runConsolidate({\n repoRoot: ctx.repoRoot,\n config: ctx.config,\n force: opts.force,\n dryRun: opts.dryRun,\n debug: opts.debug ?? ctx.config.debug,\n });\n}\n\n/**\n * v2: 自动调度 consolidate(由 capture hook 触发)。\n *\n * 暂时保留接口但简化逻辑:不再自动调度,\n * 因为 v2 采用懒 consolidate 策略(手动 flush)。\n * 后续如需自动触发可在此扩展。\n */\nexport function maybeScheduleConsolidate(opts: {\n repoRoot: string;\n debug?: boolean;\n}): void {\n const lock = readConsolidateLock(opts.repoRoot);\n if (lock && !isLockStale(lock, CONSOLIDATE_LOCK_TTL_MS)) {\n return; // 锁已被持有\n }\n\n // v2: 不再自动调度,仅记录日志\n // 如需自动 flush,可取消下面的注释\n /*\n const child = spawn(process.execPath, [cliPath(), 'flush', '-C', opts.repoRoot], {\n detached: true, stdio: 'ignore', cwd: opts.repoRoot\n });\n child.unref();\n */\n}\n","import { debugLog } from \"../config/debugLog.js\";\nimport { effectiveLlmMode, isLlmAvailable } from \"../config/llmConfig.js\";\nimport { readLlmConfigAtRepo } from \"../config/readLlmConfig.js\";\nimport type { AssistantId } from \"../init/assistants/types.js\";\nimport { enqueueLlmJob } from \"./enqueueLlmJob.js\";\nimport { llmFormat, simpleFormat } from \"./formatCapture.js\";\nimport { needsLlm } from \"./needsLlm.js\";\nimport type { CaptureResult } from \"./types.js\";\nimport { maybeScheduleConsolidate } from \"../consolidate/scheduleConsolidate.js\";\nimport {\n appendCaptureToSession,\n} from \"./writeCapture.js\";\nimport type { ParsedSession } from \"./types.js\";\n\nfunction finishCapture(\n repoRoot: string,\n debug: boolean | undefined,\n result: CaptureResult,\n): CaptureResult {\n if (result.written) {\n maybeScheduleConsolidate({ repoRoot, debug });\n }\n return result;\n}\n\nexport interface CommitCaptureOptions {\n repoRoot: string;\n session: ParsedSession;\n jsonlPath: string;\n assistant: AssistantId;\n dryRun?: boolean;\n debug?: boolean;\n}\n\nexport async function commitCapture(\n opts: CommitCaptureOptions,\n): Promise<CaptureResult> {\n const { repoRoot, session, jsonlPath, assistant, dryRun, debug } = opts;\n const formatted = simpleFormat(session, assistant);\n\n if (dryRun) {\n debugLog(\n debug === true,\n \"capture\",\n `[dry-run] would capture session=${session.sessionId} from ${jsonlPath}`,\n );\n return { written: false, reason: \"dry-run\", jsonlPath };\n }\n\n // v2: 使用 session 聚合模式写入\n const result = appendCaptureToSession(repoRoot, formatted);\n const captureFile = result.relativePath;\n\n // v2: 不再维护 sessions/index.json\n\n const llm = readLlmConfigAtRepo(repoRoot);\n if (!isLlmAvailable(llm) || !needsLlm(session)) {\n debugLog(debug === true, \"capture\", `ok: ${captureFile} (format=simple)`);\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n }\n\n const mode = effectiveLlmMode(llm!);\n if (mode === \"sync\") {\n const upgraded = await llmFormat(session, assistant, llm!);\n if (upgraded) {\n // v2: LLM upgrade 后重新追加到同一 session 文件(覆盖最后一个 capture 段落)\n // 简化处理:当前暂不实现 LLM in-place upgrade,后续在 Phase 2 完善\n debugLog(debug === true, \"capture\", `ok: ${captureFile} (format=llm-sync)`);\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n }\n debugLog(debug === true, \"capture\", `ok: ${captureFile} (format=simple, llm-fallback)`);\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n }\n\n const enqueued = enqueueLlmJob({\n repoRoot,\n sessionId: session.sessionId,\n jsonlPath,\n captureFile,\n assistant,\n debug,\n });\n if (enqueued) {\n debugLog(debug === true, \"capture\", `ok: ${captureFile} (format=simple, llm-enqueued)`);\n } else {\n debugLog(debug === true, \"capture\", `ok: ${captureFile} (format=simple, llm-skip-enqueue)`);\n }\n\n return finishCapture(repoRoot, debug, {\n written: true,\n capturePath: captureFile,\n jsonlPath,\n });\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join, resolve } from \"node:path\";\n\n/** Claude Code:项目目录名 = 绝对路径将 `/` 替换为 `-`(见官方 ~/.claude/projects/) */\nexport function encodeClaudeProjectDir(absPath: string): string {\n return resolve(absPath).replace(/\\//g, \"-\");\n}\n\nexport interface ResolveSessionOptions {\n /** Claude Stop hook stdin JSON 的 transcript_path(官方首选) */\n transcriptPath?: string;\n cwd?: string;\n}\n\n/**\n * 解析 Claude Code 会话 JSONL 路径。\n * 依据 https://code.claude.com/docs/en/claude-directory#application-data\n *\n * 优先级:\n * 1. HERMES_SESSION_JSONL(测试 / 手动覆盖)\n * 2. transcriptPath(hook stdin 的 transcript_path)\n * 3. ~/.claude/projects/<encoded-cwd>/*.jsonl(当前仓库)\n * 4. 全局 projects 下最新 .jsonl(含旧版 sessions 子目录回退)\n */\nexport function resolveSessionJsonlPath(\n repoRoot: string,\n options: ResolveSessionOptions = {},\n): string | null {\n const override = process.env.HERMES_SESSION_JSONL;\n if (override && existsSync(override)) {\n return resolve(override);\n }\n\n const fromHook = options.transcriptPath;\n if (fromHook && existsSync(fromHook)) {\n return resolve(fromHook);\n }\n\n const sessionId =\n process.env.CLAUDE_SESSION_ID ??\n process.env.CLAUDE_CODE_SESSION_ID ??\n process.env.SESSION_ID;\n\n const claudeHome = process.env.CLAUDE_CONFIG_DIR\n ? resolve(process.env.CLAUDE_CONFIG_DIR)\n : join(homedir(), \".claude\");\n const projectsRoot = join(claudeHome, \"projects\");\n if (!existsSync(projectsRoot)) {\n return null;\n }\n\n const cwd = resolve(options.cwd ?? repoRoot);\n const preferredProjectDir = encodeClaudeProjectDir(cwd);\n const preferredPath = join(projectsRoot, preferredProjectDir);\n if (existsSync(preferredPath)) {\n const hit = pickNewestJsonl(preferredPath, sessionId);\n if (hit) {\n return hit;\n }\n const legacySessions = join(preferredPath, \"sessions\");\n if (existsSync(legacySessions)) {\n const legacyHit = pickNewestJsonl(legacySessions, sessionId);\n if (legacyHit) {\n return legacyHit;\n }\n }\n }\n\n const candidates: Array<{ path: string; mtime: number }> = [];\n\n for (const projectDir of readdirSync(projectsRoot, { withFileTypes: true })) {\n if (!projectDir.isDirectory()) continue;\n const projectPath = join(projectsRoot, projectDir.name);\n collectJsonlCandidates(projectPath, sessionId, candidates);\n const legacySessions = join(projectPath, \"sessions\");\n if (existsSync(legacySessions)) {\n collectJsonlCandidates(legacySessions, sessionId, candidates);\n }\n }\n\n if (candidates.length === 0) {\n return null;\n }\n\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\n/** @deprecated 使用 readHookInputSync;保留兼容测试与旧调用 */\nexport function readHookTranscriptPathSync(): string | null {\n if (process.stdin.isTTY) {\n return null;\n }\n try {\n const raw = readFileSync(0, \"utf8\").trim();\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw) as { transcript_path?: unknown };\n const p = parsed.transcript_path;\n if (typeof p === \"string\" && existsSync(p)) {\n return resolve(p);\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction pickNewestJsonl(\n dir: string,\n sessionId: string | undefined,\n): string | null {\n const candidates: Array<{ path: string; mtime: number }> = [];\n collectJsonlCandidates(dir, sessionId, candidates);\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction collectJsonlCandidates(\n dir: string,\n sessionId: string | undefined,\n out: Array<{ path: string; mtime: number }>,\n): void {\n if (!existsSync(dir)) {\n return;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n continue;\n }\n const fullPath = join(dir, entry.name);\n if (\n sessionId &&\n !entry.name.includes(sessionId) &&\n basename(entry.name, \".jsonl\") !== sessionId\n ) {\n continue;\n }\n try {\n const st = statSync(fullPath);\n out.push({ path: fullPath, mtime: st.mtimeMs });\n } catch {\n // skip\n }\n }\n}\n","import { commitCapture } from \"../commitCapture.js\";\nimport type { CaptureResult } from \"../types.js\";\nimport { parseJsonlFile } from \"./parseJsonl.js\";\nimport { resolveSessionJsonlPath } from \"./resolveSession.js\";\n\nexport async function runClaudeCodeCapture(\n repoRoot: string,\n cwd?: string,\n dryRun?: boolean,\n options?: { transcriptPath?: string; debug?: boolean },\n): Promise<CaptureResult> {\n const jsonlPath = resolveSessionJsonlPath(repoRoot, {\n cwd,\n transcriptPath: options?.transcriptPath,\n });\n if (!jsonlPath) {\n return { written: false, reason: \"no session jsonl found\" };\n }\n\n // v2: 始终捕获(去掉 shouldCapture 质量过滤)\n const session = parseJsonlFile(jsonlPath);\n\n return commitCapture({\n repoRoot,\n session,\n jsonlPath,\n assistant: \"claude-code\",\n dryRun,\n debug: options?.debug,\n });\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join, resolve } from \"node:path\";\n\n/**\n * CodeBuddy 项目目录名:绝对路径去掉 leading `/`,再将 `/` 换为 `-`。\n * 例:`/Users/you/proj` → `Users-you-proj`(与 Cursor 一致,非 Claude leading `-`)\n */\nexport function encodeCodebuddyProjectDir(absPath: string): string {\n return resolve(absPath).replace(/^\\//, \"\").replace(/\\//g, \"-\");\n}\n\nexport interface ResolveCodebuddySessionOptions {\n repoRoot: string;\n cwd?: string;\n transcriptPath?: string;\n}\n\n/**\n * 解析 CodeBuddy 会话 JSONL。\n *\n * 优先级:\n * 1. HERMES_CODEBUDDY_SESSION\n * 2. transcriptPath(hook stdin)\n * 3. ~/.codebuddy/projects/<encoded-cwd> 下最新 .jsonl(含子目录)\n */\nexport function resolveCodebuddySessionJsonl(\n options: ResolveCodebuddySessionOptions,\n): string | null {\n const override = process.env.HERMES_CODEBUDDY_SESSION;\n if (override && existsSync(override)) {\n return resolve(override);\n }\n\n const fromHook = options.transcriptPath;\n if (fromHook && existsSync(fromHook)) {\n return resolve(fromHook);\n }\n\n const sessionId =\n process.env.CODEBUDDY_SESSION_ID ?? process.env.SESSION_ID;\n\n const codebuddyHome = process.env.CODEBUDDY_CONFIG_DIR\n ? resolve(process.env.CODEBUDDY_CONFIG_DIR)\n : join(homedir(), \".codebuddy\");\n const projectsRoot = join(codebuddyHome, \"projects\");\n if (!existsSync(projectsRoot)) {\n return null;\n }\n\n const cwd = resolve(options.cwd ?? options.repoRoot);\n const preferredProjectDir = encodeCodebuddyProjectDir(cwd);\n const preferredPath = join(projectsRoot, preferredProjectDir);\n if (existsSync(preferredPath)) {\n const hit = pickNewestJsonlRecursive(preferredPath, sessionId);\n if (hit) {\n return hit;\n }\n }\n\n const candidates: Array<{ path: string; mtime: number }> = [];\n for (const projectDir of readdirSync(projectsRoot, { withFileTypes: true })) {\n if (!projectDir.isDirectory()) {\n continue;\n }\n collectJsonlRecursive(join(projectsRoot, projectDir.name), sessionId, candidates);\n }\n\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction pickNewestJsonlRecursive(\n dir: string,\n sessionId: string | undefined,\n): string | null {\n const candidates: Array<{ path: string; mtime: number }> = [];\n collectJsonlRecursive(dir, sessionId, candidates);\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction collectJsonlRecursive(\n dir: string,\n sessionId: string | undefined,\n out: Array<{ path: string; mtime: number }>,\n): void {\n if (!existsSync(dir)) {\n return;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n collectJsonlRecursive(full, sessionId, out);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n continue;\n }\n if (\n sessionId &&\n !entry.name.includes(sessionId) &&\n basename(entry.name, \".jsonl\") !== sessionId\n ) {\n continue;\n }\n try {\n const st = statSync(full);\n out.push({ path: full, mtime: st.mtimeMs });\n } catch {\n // skip\n }\n }\n}\n","import { commitCapture } from \"../commitCapture.js\";\nimport type { CaptureResult } from \"../types.js\";\nimport { parseJsonlFile } from \"../claude-code/parseJsonl.js\";\nimport { resolveCodebuddySessionJsonl } from \"./resolveSession.js\";\n\nexport async function runCodebuddyCapture(\n repoRoot: string,\n cwd?: string,\n dryRun?: boolean,\n options?: { transcriptPath?: string; debug?: boolean },\n): Promise<CaptureResult> {\n const jsonlPath = resolveCodebuddySessionJsonl({\n repoRoot,\n cwd,\n transcriptPath: options?.transcriptPath,\n });\n if (!jsonlPath) {\n return { written: false, reason: \"no codebuddy session found\" };\n }\n\n // v2: 始终捕获(去掉 shouldCapture 质量过滤),由 LLM 在 consolidate 时判断价值\n const session = parseJsonlFile(jsonlPath);\n if (session.messages.length <= 1 && session.toolCalls === 0) {\n return {\n written: false,\n reason: \"empty session (no messages or tool calls)\",\n jsonlPath,\n };\n }\n\n return commitCapture({\n repoRoot,\n session,\n jsonlPath,\n assistant: \"codebuddy\",\n dryRun,\n debug: options?.debug,\n });\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { HookInput } from \"../hookInput.js\";\n\n/**\n * Cursor 项目目录名:绝对路径去掉 leading `/`,再将 `/` 换为 `-`。\n * 例:`/Users/you/proj` → `Users-you-proj`\n * (与 Claude `encodeClaudeProjectDir` 的 leading `-` 不同)\n */\nexport function encodeCursorProjectDir(absPath: string): string {\n return resolve(absPath).replace(/^\\//, \"\").replace(/\\//g, \"-\");\n}\n\nexport interface ResolveCursorSessionOptions {\n repoRoot: string;\n cwd?: string;\n hookInput?: HookInput | null;\n}\n\n/**\n * 解析 Cursor Agent 会话 JSONL。\n *\n * 优先级:\n * 1. HERMES_CURSOR_SESSION(测试 / 手动)\n * 2. hook session_id → ~/.cursor/projects/<encoded>/agent-transcripts/<id>/<id>.jsonl\n * 3. workspace_roots[0] 或 repoRoot 对应项目下最新 transcript\n */\nexport function resolveCursorSessionJsonl(\n options: ResolveCursorSessionOptions,\n): string | null {\n const override = process.env.HERMES_CURSOR_SESSION;\n if (override && existsSync(override)) {\n return resolve(override);\n }\n\n const cursorHome = process.env.CURSOR_CONFIG_DIR\n ? resolve(process.env.CURSOR_CONFIG_DIR)\n : join(homedir(), \".cursor\");\n const projectsRoot = join(cursorHome, \"projects\");\n if (!existsSync(projectsRoot)) {\n return null;\n }\n\n const sessionId =\n options.hookInput?.sessionId ??\n options.hookInput?.conversationId ??\n process.env.CURSOR_SESSION_ID ??\n process.env.CURSOR_AGENT_SESSION_ID;\n\n const workspace =\n options.hookInput?.workspaceRoots?.[0] ??\n (options.cwd ? resolve(options.cwd) : resolve(options.repoRoot));\n\n const encoded = encodeCursorProjectDir(workspace);\n const projectDir = join(projectsRoot, encoded);\n const transcriptsRoot = join(projectDir, \"agent-transcripts\");\n\n if (!existsSync(transcriptsRoot)) {\n return pickNewestCursorJsonl(projectsRoot);\n }\n\n if (sessionId) {\n const direct = join(transcriptsRoot, sessionId, `${sessionId}.jsonl`);\n if (existsSync(direct)) {\n return direct;\n }\n const nested = findJsonlUnderDir(join(transcriptsRoot, sessionId), sessionId);\n if (nested) {\n return nested;\n }\n }\n\n return pickNewestCursorJsonl(transcriptsRoot);\n}\n\nfunction findJsonlUnderDir(dir: string, sessionId: string): string | null {\n if (!existsSync(dir)) {\n return null;\n }\n const direct = join(dir, `${sessionId}.jsonl`);\n if (existsSync(direct)) {\n return direct;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isFile() && entry.name.endsWith(\".jsonl\")) {\n return join(dir, entry.name);\n }\n if (entry.isDirectory()) {\n const found = findJsonlUnderDir(join(dir, entry.name), sessionId);\n if (found) {\n return found;\n }\n }\n }\n return null;\n}\n\nfunction pickNewestCursorJsonl(root: string): string | null {\n const candidates: Array<{ path: string; mtime: number }> = [];\n collectJsonlRecursive(root, candidates);\n if (candidates.length === 0) {\n return null;\n }\n candidates.sort((a, b) => b.mtime - a.mtime);\n return candidates[0]?.path ?? null;\n}\n\nfunction collectJsonlRecursive(\n dir: string,\n out: Array<{ path: string; mtime: number }>,\n): void {\n if (!existsSync(dir)) {\n return;\n }\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n collectJsonlRecursive(full, out);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n continue;\n }\n try {\n const st = statSync(full);\n out.push({ path: full, mtime: st.mtimeMs });\n } catch {\n // skip\n }\n }\n}\n","import { commitCapture } from \"../commitCapture.js\";\nimport type { CaptureResult } from \"../types.js\";\nimport type { HookInput } from \"../hookInput.js\";\nimport { parseJsonlFile } from \"../claude-code/parseJsonl.js\";\nimport { resolveCursorSessionJsonl } from \"./resolveSession.js\";\n\nexport async function runCursorCapture(\n repoRoot: string,\n cwd?: string,\n dryRun?: boolean,\n options?: { hookInput?: HookInput | null; debug?: boolean },\n): Promise<CaptureResult> {\n if (\n options?.hookInput?.status === \"aborted\" &&\n !options.hookInput.sessionId\n ) {\n return { written: false, reason: \"cursor stop aborted\" };\n }\n\n const jsonlPath = resolveCursorSessionJsonl({\n repoRoot,\n cwd,\n hookInput: options?.hookInput,\n });\n if (!jsonlPath) {\n return { written: false, reason: \"no cursor session found\" };\n }\n\n // v2: 始终捕获(去掉 shouldCapture 质量过滤)\n const session = parseJsonlFile(jsonlPath);\n\n return commitCapture({\n repoRoot,\n session,\n jsonlPath,\n assistant: \"cursor\",\n dryRun,\n debug: options?.debug,\n });\n}\n","import type { RepoContext } from \"../config/types.js\";\nimport { runClaudeCodeCapture } from \"./claude-code/run.js\";\nimport { runCodebuddyCapture } from \"./codebuddy/run.js\";\nimport { runCursorCapture } from \"./cursor/run.js\";\nimport {\n isClaudeCaptureHook,\n isCodebuddyCaptureHook,\n isCursorCaptureHook,\n type HookInput,\n} from \"./hookInput.js\";\nimport type { CaptureResult } from \"./types.js\";\n\nexport async function routeCapture(\n ctx: RepoContext,\n options: {\n cwd?: string;\n dryRun?: boolean;\n transcriptPath?: string;\n hookInput?: HookInput | null;\n },\n): Promise<CaptureResult> {\n const assistants = ctx.config.assistants;\n const hasClaude = assistants.includes(\"claude-code\");\n const hasCursor = assistants.includes(\"cursor\");\n const hasCodebuddy = assistants.includes(\"codebuddy\");\n\n if (!hasClaude && !hasCursor && !hasCodebuddy) {\n return { written: false, reason: \"no capture assistant in config\" };\n }\n\n const hook = options.hookInput;\n const debug = ctx.config.debug === true;\n const codebuddyFromHook = isCodebuddyCaptureHook(hook);\n const claudeFromHook = isClaudeCaptureHook(hook);\n const cursorFromHook = isCursorCaptureHook(hook);\n\n if (codebuddyFromHook && hasCodebuddy) {\n return runCodebuddyCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n transcriptPath: hook?.transcriptPath ?? options.transcriptPath,\n debug,\n });\n }\n\n if (claudeFromHook && hasClaude) {\n return runClaudeCodeCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n transcriptPath: hook?.transcriptPath ?? options.transcriptPath,\n debug,\n });\n }\n\n if (cursorFromHook && hasCursor) {\n return runCursorCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n hookInput: hook,\n debug,\n });\n }\n\n if (hasClaude) {\n const claudeResult = await runClaudeCodeCapture(\n ctx.repoRoot,\n options.cwd,\n options.dryRun,\n {\n transcriptPath: options.transcriptPath,\n debug,\n },\n );\n if (claudeResult.written) {\n return claudeResult;\n }\n if (!hasCursor && !hasCodebuddy) {\n return claudeResult;\n }\n }\n\n if (hasCursor) {\n const cursorResult = await runCursorCapture(\n ctx.repoRoot,\n options.cwd,\n options.dryRun,\n {\n hookInput: hook,\n debug,\n },\n );\n if (cursorResult.written) {\n return cursorResult;\n }\n if (!hasCodebuddy) {\n return cursorResult;\n }\n }\n\n if (hasCodebuddy) {\n return runCodebuddyCapture(ctx.repoRoot, options.cwd, options.dryRun, {\n transcriptPath: options.transcriptPath,\n debug,\n });\n }\n\n return { written: false, reason: \"no capture assistant in config\" };\n}\n","import { debugLog } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport type { HookInput } from \"./hookInput.js\";\nimport { routeCapture } from \"./router.js\";\nimport type { CaptureResult } from \"./types.js\";\n\nexport interface CaptureOptions {\n cwd?: string;\n dryRun?: boolean;\n strict?: boolean;\n /** Claude Stop hook stdin 中的 transcript_path(兼容旧调用) */\n transcriptPath?: string;\n hookInput?: HookInput | null;\n}\n\nfunction logCaptureResult(debug: boolean, result: CaptureResult): void {\n if (!debug) {\n return;\n }\n if (result.written && result.capturePath) {\n debugLog(true, \"capture\", `ok: ${result.capturePath}`);\n return;\n }\n const parts = [result.reason ?? \"unknown\"];\n if (result.jsonlPath) {\n parts.push(`jsonl=${result.jsonlPath}`);\n }\n debugLog(true, \"capture\", `skip: ${parts.join(\", \")}`);\n}\n\nexport async function runCapture(\n options: CaptureOptions = {},\n): Promise<CaptureResult> {\n const ctx = loadRepoContext(options.cwd);\n if (!ctx) {\n return { written: false, reason: \"not initialized\" };\n }\n\n const result = await routeCapture(ctx, {\n cwd: options.cwd,\n dryRun: options.dryRun,\n transcriptPath: options.transcriptPath,\n hookInput: options.hookInput,\n });\n logCaptureResult(ctx.config.debug, result);\n return result;\n}\n","import { readHookInputSync, isCodebuddyCaptureHook } from \"../capture/hookInput.js\";\nimport { runCapture } from \"../capture/runCapture.js\";\nimport { configureDebugLogging, debugLog } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { finalizeHookCommand } from \"../hookExit.js\";\n\nexport interface CaptureCommandOptions {\n cwd?: string;\n dryRun?: boolean;\n strict?: boolean;\n}\n\nexport function runCaptureCommand(opts: CaptureCommandOptions): void {\n const ctx = loadRepoContext(opts.cwd);\n const debug = ctx?.config.debug === true;\n configureDebugLogging(ctx?.repoRoot ?? null, debug);\n const hookInput = readHookInputSync();\n\n if (hookInput && isCodebuddyCaptureHook(hookInput)) {\n const stdinPath =\n hookInput.transcriptPathRaw ??\n hookInput.transcriptPath ??\n \"(missing)\";\n debugLog(\n debug,\n \"capture\",\n `codebuddy stop stdin transcript_path=${stdinPath}`,\n );\n }\n\n finalizeHookCommand(async () => {\n await runCapture({\n cwd: opts.cwd,\n dryRun: opts.dryRun,\n strict: opts.strict,\n hookInput,\n transcriptPath: hookInput?.transcriptPath,\n });\n }, opts.strict, debug);\n}\n","import { hookExit } from \"../hookExit.js\";\nimport { runFlushCommand } from \"../consolidate/scheduleConsolidate.js\";\nimport type { ConsolidateResultV2 } from \"../consolidate/runConsolidate.js\";\n\nexport async function runFlushCommandCli(opts: {\n cwd?: string;\n force?: boolean;\n dryRun?: boolean;\n strict?: boolean;\n}): Promise<void> {\n try {\n const result = await runFlushCommand({\n cwd: opts.cwd,\n force: opts.force,\n dryRun: opts.dryRun,\n });\n\n if (result.ran) {\n if (result.reason === \"dry-run\") {\n console.error(\n `hermes-repo: dry-run would process ${result.sessionsProcessed} session(s)`,\n );\n } else {\n const parts: string[] = [];\n if (result.knowledgeCreated > 0)\n parts.push(`${result.knowledgeCreated} created`);\n if (result.knowledgeUpdated > 0)\n parts.push(`${result.knowledgeUpdated} updated`);\n if (result.skippedCount > 0)\n parts.push(`${result.skippedCount} skipped`);\n if (result.archived > 0)\n parts.push(`${result.archived} archived`);\n const suffix = parts.length > 0 ? `, ${parts.join(\", \")}` : \"\";\n\n console.error(\n `hermes-repo: consolidated ${result.sessionsProcessed} session(s)${suffix}`,\n );\n }\n } else {\n switch (result.reason) {\n case \"not-initialized\":\n console.error(\n \"hermes-repo flush: not initialized (.memory/config.json missing)\",\n );\n break;\n case \"llm-not-enabled\":\n console.error(\"hermes-repo flush: LLM not enabled in config.json\");\n break;\n case \"no-pending-sessions\":\n console.error(\"hermes-repo flush: no pending sessions to process\");\n break;\n default:\n console.error(`hermes-repo flush: ${result.reason ?? \"skipped\"}`);\n }\n }\n\n hookExit(0, opts.strict);\n } catch (err) {\n console.error(\n `hermes-repo flush: ${err instanceof Error ? err.message : String(err)}`,\n );\n hookExit(1, opts.strict);\n }\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { debugFromContext } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { memoryPath } from \"../init/paths.js\";\nimport { INJECT_MAX_CHARS } from \"./constants.js\";\n\n// ─── v2 两阶段注入 ─────────────────────────\n//\n// Phase 0: 注入 MEMORY.md 导航摘要 + rules/ 全部文件内容\n// AI 可按需 cat domains/workflows/decisions/incidents 具体文件\n\nexport interface InjectResult {\n injected: boolean;\n chars: number;\n}\n\n/**\n * v2 inject 主函数。\n *\n * 输出格式:\n * - Cursor hook: JSON {\"additional_context\": \"...\"}\n * - 其他: 纯文本 markdown 到 stdout\n *\n * 内容组成:\n * 1. MEMORY.md 导航摘要(项目知识库入口)\n * 2. 分隔线\n * 3. rules/ 目录下所有 .md 文件的完整内容\n */\nexport function runInject(\n cwd?: string,\n options?: { cursorHookOutput?: boolean },\n): InjectResult {\n const ctx = loadRepoContext(cwd);\n if (!ctx) {\n return { injected: false, chars: 0 };\n }\n\n const repoRoot = ctx.repoRoot;\n\n // 1. 读取 MEMORY.md 导航\n const memoryContent = readMemoryMd(repoRoot);\n // 2. 读取 rules/ 全文\n const rulesContent = readAllRules(repoRoot);\n\n if (!memoryContent && !rulesContent) {\n debugFromContext(ctx, \"inject\", \"skip: no MEMORY.md or rules/\");\n return { injected: false, chars: 0 };\n }\n\n // 组装注入内容\n const sections: string[] = [];\n\n if (memoryContent) {\n sections.push(memoryContent);\n }\n\n if (rulesContent) {\n sections.push(\n \"\",\n \"---\",\n \"\",\n \"> 以下为必读规则全文(每次会话均应遵守)\",\n \"\",\n rulesContent,\n );\n }\n\n let content = sections.join(\"\\n\");\n\n // 截断保护\n if (content.length > INJECT_MAX_CHARS) {\n content =\n `${content.slice(0, INJECT_MAX_CHARS)}\\n\\n...(truncated, total ${content.length} chars)`;\n }\n\n // 输出\n if (options?.cursorHookOutput) {\n process.stdout.write(\n `${JSON.stringify({ additional_context: content })}\\n`,\n );\n } else {\n process.stdout.write(content);\n if (!content.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n }\n\n debugFromContext(ctx, \"inject\", `ok: injected ${content.length} chars`);\n\n return { injected: true, chars: content.length };\n}\n\n// ─── Helpers ────────────────────────────────\n\nfunction memoryPathOnDisk(repoRoot: string): string {\n return memoryPath(repoRoot, \"MEMORY.md\");\n}\n\nfunction rulesPathOnDisk(repoRoot: string): string {\n return memoryPath(repoRoot, \"rules\");\n}\n\nfunction readMemoryMd(repoRoot: string): string | null {\n const path = memoryPathOnDisk(repoRoot);\n if (!existsSync(path)) return null;\n\n try {\n const content = readFileSync(path, \"utf8\");\n return content.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * 读取 rules/ 下所有 .md 文件,拼接为一个文档块。\n * 返回 null 如果目录不存在或无文件。\n */\nfunction readAllRules(repoRoot: string): string | null {\n const rulesDir = rulesPathOnDisk(repoRoot);\n let files: string[];\n try {\n files = readdirSync(rulesDir)\n .filter((f) => f.endsWith(\".md\"))\n .sort(); // 字母排序确保稳定顺序\n } catch {\n return null; // 目录不存在\n }\n\n if (files.length === 0) return null;\n\n const parts: string[] = [];\n for (const file of files) {\n try {\n const filePath = join(rulesDir, file);\n const content = readFileSync(filePath, \"utf8\").trim();\n if (!content) continue;\n\n // 每个规则文件加标题头\n parts.push(`### ${file}`, \"\", content, \"\");\n } catch {\n // 跳过无法读取的文件\n }\n }\n\n return parts.length > 0 ? parts.join(\"\\n\") : null;\n}\n","/** v2 两阶段注入:导航 + 规则全文,目标 ~8K chars(含 rules 全文) */\nexport const INJECT_MAX_CHARS = 8000;\n","import { isCursorInjectHook, readHookInputSync } from \"../capture/hookInput.js\";\nimport { configureDebugLogging } from \"../config/debugLog.js\";\nimport { loadRepoContext } from \"../config/readConfig.js\";\nimport { finalizeHookCommand } from \"../hookExit.js\";\nimport { runInject } from \"../inject/runInject.js\";\n\nexport interface InjectCommandOptions {\n cwd?: string;\n strict?: boolean;\n}\n\nexport function runInjectCommand(opts: InjectCommandOptions): void {\n const ctx = loadRepoContext(opts.cwd);\n const debug = ctx?.config.debug === true;\n configureDebugLogging(ctx?.repoRoot ?? null, debug);\n\n const hookInput = readHookInputSync();\n const cursorHookOutput = isCursorInjectHook(hookInput);\n\n finalizeHookCommand(() => {\n runInject(opts.cwd, { cursorHookOutput });\n }, opts.strict, debug);\n}\n","import { spawnSync } from \"node:child_process\";\nimport { resolve } from \"node:path\";\nimport {\n DEFAULT_ASSISTANT_IDS,\n parseToolsArg,\n validateAssistantSelection,\n} from \"./assistants/registry.js\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport { ensureMemoryTree } from \"./ensureDirs.js\";\nimport { mergeAssistants } from \"./mergeAssistants.js\";\nimport { mergeHermesGitignore } from \"./mergeGitignore.js\";\nimport type { InitCliOptions, InitReport, InitResolvedOptions } from \"./types.js\";\nimport { writeScaffoldFiles } from \"./writeScaffoldFile.js\";\nimport { gatherInitOptions } from \"./prompts.js\";\n\nexport function resolveTargetDir(cwd?: string): string {\n const targetDir = resolve(cwd ?? process.cwd());\n const gitCheck = spawnSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd: targetDir,\n encoding: \"utf8\",\n });\n if (gitCheck.status !== 0) {\n console.warn(\n \"warn: 当前目录可能不是 Git 仓库,init 仍会继续(建议在有 git 的项目根目录执行)\",\n );\n }\n return targetDir;\n}\n\nfunction resolveSelectedAssistants(opts: InitCliOptions): AssistantId[] {\n if (opts.assistants) {\n validateAssistantSelection(opts.assistants);\n return opts.assistants;\n }\n if (opts.tools) {\n if (!opts.yes) {\n console.error(\"init --tools requires -y in non-interactive mode\");\n process.exit(1);\n }\n return parseToolsArg(opts.tools);\n }\n if (opts.yes) {\n return [...DEFAULT_ASSISTANT_IDS];\n }\n return [];\n}\n\nexport function printInitReport(report: InitReport): void {\n const created = report.files.filter((f) => f.action === \"created\");\n const skipped = report.files.filter((f) => f.action === \"skipped\");\n const overwritten = report.files.filter((f) => f.action === \"overwritten\");\n const appended = report.files.filter((f) => f.action === \"appended\");\n const replaced = report.files.filter((f) => f.action === \"replaced\");\n\n console.log(`\\nhermes-repo init 完成 → ${report.targetDir}\\n`);\n console.log(`已启用助手: ${report.assistants.join(\", \")}\\n`);\n\n if (created.length > 0) {\n console.log(`已创建 (${created.length}):`);\n for (const f of created) {\n console.log(` + ${f.path}`);\n }\n }\n\n if (overwritten.length > 0) {\n console.log(`已覆盖 (${overwritten.length}):`);\n for (const f of overwritten) {\n console.log(` ~ ${f.path}`);\n }\n }\n\n if (appended.length > 0) {\n console.log(`已追加 (${appended.length}):`);\n for (const f of appended) {\n console.log(` + ${f.path}`);\n }\n }\n\n if (replaced.length > 0) {\n console.log(`已刷新 hermes 块 (${replaced.length}):`);\n for (const f of replaced) {\n console.log(` ↻ ${f.path}`);\n }\n }\n\n if (skipped.length > 0) {\n console.log(`已跳过 (${skipped.length}):`);\n for (const f of skipped) {\n console.log(` - ${f.path}`);\n }\n }\n\n if (report.gitignoreAction) {\n console.log(`\\n.gitignore: ${report.gitignoreAction} hermes-repo 标记块`);\n }\n\n for (const warning of report.warnings) {\n console.warn(`warn: ${warning}`);\n }\n\n console.log(\"\");\n}\n\nexport async function runInit(opts: InitCliOptions): Promise<InitReport> {\n if (!process.stdin.isTTY && !opts.yes) {\n console.error(\"init requires -y in non-interactive environments\");\n process.exit(1);\n }\n\n if (opts.tools && !opts.yes) {\n console.error(\"init --tools requires -y\");\n process.exit(1);\n }\n\n let resolved: InitResolvedOptions;\n\n if (opts.yes) {\n const targetDir = resolveTargetDir(opts.cwd);\n const selected = resolveSelectedAssistants(opts);\n resolved = {\n targetDir,\n force: Boolean(opts.force),\n includeExampleTemplates: opts.includeExampleTemplates ?? true,\n assistants: mergeAssistants(targetDir, selected),\n cancelled: false,\n };\n } else {\n const gathered = await gatherInitOptions(opts);\n if (gathered.cancelled) {\n console.log(\"init 已取消\");\n process.exit(0);\n }\n resolved = {\n ...gathered,\n assistants: mergeAssistants(gathered.targetDir, gathered.assistants),\n };\n }\n\n const report: InitReport = {\n targetDir: resolved.targetDir,\n assistants: resolved.assistants,\n files: [],\n warnings: [],\n };\n\n ensureMemoryTree(resolved.targetDir);\n writeScaffoldFiles(resolved.targetDir, resolved, report);\n\n const gitignore = mergeHermesGitignore(resolved.targetDir);\n report.gitignoreAction = gitignore.action;\n if (gitignore.warnBroadMemoryIgnore) {\n report.warnings.push(\n \".gitignore 中存在对整个 .memory/ 的忽略规则,可能与团队层放行冲突,请手动检查\",\n );\n }\n\n printInitReport(report);\n\n return report;\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CLAUDE_SETTINGS_LOCAL_REL,\n claudeSettingsLocalPath,\n mergeClaudeLocalSettings,\n} from \"../mergeClaudeSettings.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const claudeCodeAdapter: AssistantAdapter = {\n id: \"claude-code\",\n label: \"Claude Code(Stop / SessionStart hooks)\",\n available: true,\n scaffoldPaths: [CLAUDE_SETTINGS_LOCAL_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".claude\"), { recursive: true });\n const { content, action } = mergeClaudeLocalSettings(ctx.repoRoot);\n writeFileSync(claudeSettingsLocalPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CLAUDE_SETTINGS_LOCAL_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { renderTemplate } from \"./templateDir.js\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CLAUDE_SETTINGS_LOCAL_REL = \".claude/settings.local.json\";\n\nexport function claudeSettingsLocalPath(repoRoot: string): string {\n return join(repoRoot, \".claude\", \"settings.local.json\");\n}\n\ntype HookHandlers = { hooks: { type: string; command: string }[] }[];\n\n/** 每次 init 合并 hermes 管理的 Stop / SessionStart 到 Claude local settings */\nexport function mergeClaudeLocalSettings(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const settingsPath = claudeSettingsLocalPath(repoRoot);\n const existed = existsSync(settingsPath);\n\n const templateParsed = JSON.parse(renderTemplate(\"hooks.json.tpl\")) as {\n hooks: {\n Stop: HookHandlers;\n SessionStart: HookHandlers;\n };\n };\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevHooks =\n existing.hooks &&\n typeof existing.hooks === \"object\" &&\n !Array.isArray(existing.hooks)\n ? (existing.hooks as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n hooks: {\n ...prevHooks,\n Stop: templateParsed.hooks.Stop,\n SessionStart: templateParsed.hooks.SessionStart,\n },\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { PACKAGE_NAME } from \"../index.js\";\n\nfunction resolveTemplateDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, \"templates\"),\n join(here, \"..\", \"..\", \"templates\"),\n ];\n for (const dir of candidates) {\n if (existsSync(dir)) {\n return dir;\n }\n }\n return join(here, \"templates\");\n}\n\nconst templateDir = resolveTemplateDir();\n\nexport function resolveTemplatePath(name: string): string {\n return join(templateDir, name);\n}\n\nexport function readTemplate(name: string): string {\n return readFileSync(resolveTemplatePath(name), \"utf8\");\n}\n\nexport function renderTemplate(name: string): string {\n const raw = readTemplate(name);\n return raw.replaceAll(\"__PACKAGE_NAME__\", PACKAGE_NAME);\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport const PACKAGE_NAME = \"@riconext/hermes-repo\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport function readPkgVersion(): string {\n const pkgPath = join(__dirname, \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { version: string };\n return pkg.version;\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CODEX_CONFIG_REL,\n codexConfigPath,\n mergeCodexConfig,\n} from \"../mergeCodexConfig.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const codexAdapter: AssistantAdapter = {\n id: \"codex\",\n label: \"OpenAI Codex(AGENTS.md + .codex/config.toml)\",\n available: true,\n scaffoldPaths: [CODEX_CONFIG_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".codex\"), { recursive: true });\n const { content, action } = mergeCodexConfig(ctx.repoRoot);\n writeFileSync(codexConfigPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CODEX_CONFIG_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CODEX_CONFIG_REL = \".codex/config.toml\";\n\nconst CODEX_HERMES_START_MARKER =\n \"# >>> hermes-repo codex (do not edit this block manually)\";\nconst CODEX_HERMES_END_MARKER = \"# <<< hermes-repo codex\";\n\nfunction buildCodexHermesBlock(): string {\n return [\n CODEX_HERMES_START_MARKER,\n \"# Hermes uses AGENTS.md as the shared Codex project guidance entry.\",\n \"# Run `npx @riconext/hermes-repo search <keyword>` to inspect project memory.\",\n \"# Run `npx @riconext/hermes-repo ref --capture <path> --reason \\\"...\\\"` after using memory.\",\n CODEX_HERMES_END_MARKER,\n ].join(\"\\n\");\n}\n\nexport function codexConfigPath(repoRoot: string): string {\n return join(repoRoot, \".codex\", \"config.toml\");\n}\n\nfunction spliceHermesBlock(existing: string, block: string): string {\n const startIdx = existing.indexOf(CODEX_HERMES_START_MARKER);\n const endIdx = existing.indexOf(CODEX_HERMES_END_MARKER);\n\n if (startIdx >= 0 && endIdx >= startIdx) {\n const before = existing.slice(0, startIdx).trimEnd();\n const after = existing.slice(endIdx + CODEX_HERMES_END_MARKER.length).trimStart();\n return `${before ? `${before}\\n\\n` : \"\"}${block}${after ? `\\n\\n${after}` : \"\"}\\n`;\n }\n\n const trimmed = existing.trimEnd();\n return `${trimmed ? `${trimmed}\\n\\n` : \"\"}${block}\\n`;\n}\n\n/** Codex project config is preserved; init only manages a commented Hermes marker block. */\nexport function mergeCodexConfig(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const configPath = codexConfigPath(repoRoot);\n const existed = existsSync(configPath);\n const block = buildCodexHermesBlock();\n\n if (!existed) {\n return {\n content: `${block}\\n`,\n action: \"created\",\n };\n }\n\n const existing = readFileSync(configPath, \"utf8\");\n const hasBlock =\n existing.includes(CODEX_HERMES_START_MARKER) &&\n existing.includes(CODEX_HERMES_END_MARKER);\n\n return {\n content: spliceHermesBlock(existing, block),\n action: hasBlock ? \"replaced\" : \"appended\",\n };\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CODEBUDDY_SETTINGS_LOCAL_REL,\n codebuddySettingsLocalPath,\n mergeCodebuddyLocalSettings,\n} from \"../mergeCodebuddySettings.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const codebuddyAdapter: AssistantAdapter = {\n id: \"codebuddy\",\n label: \"CodeBuddy(CLI)\",\n available: true,\n scaffoldPaths: [CODEBUDDY_SETTINGS_LOCAL_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".codebuddy\"), { recursive: true });\n const { content, action } = mergeCodebuddyLocalSettings(ctx.repoRoot);\n writeFileSync(codebuddySettingsLocalPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CODEBUDDY_SETTINGS_LOCAL_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { renderTemplate } from \"./templateDir.js\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CODEBUDDY_SETTINGS_LOCAL_REL = \".codebuddy/settings.local.json\";\n\nexport function codebuddySettingsLocalPath(repoRoot: string): string {\n return join(repoRoot, \".codebuddy\", \"settings.local.json\");\n}\n\ntype HookHandlers = { hooks: { type: string; command: string }[] }[];\n\n/** 每次 init 合并 hermes 管理的 Stop / SessionStart 到 CodeBuddy local settings */\nexport function mergeCodebuddyLocalSettings(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const settingsPath = codebuddySettingsLocalPath(repoRoot);\n const existed = existsSync(settingsPath);\n\n const templateParsed = JSON.parse(\n renderTemplate(\"hooks.codebuddy.json.tpl\"),\n ) as {\n hooks: {\n Stop: HookHandlers;\n SessionStart: HookHandlers;\n };\n };\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevHooks =\n existing.hooks &&\n typeof existing.hooks === \"object\" &&\n !Array.isArray(existing.hooks)\n ? (existing.hooks as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n hooks: {\n ...prevHooks,\n Stop: templateParsed.hooks.Stop,\n SessionStart: templateParsed.hooks.SessionStart,\n },\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n CURSOR_HOOKS_REL,\n cursorHooksPath,\n mergeCursorHooks,\n} from \"../mergeCursorHooks.js\";\nimport type { AssistantAdapter, WriteContext } from \"./types.js\";\n\nexport const cursorAdapter: AssistantAdapter = {\n id: \"cursor\",\n label: \"Cursor(sessionStart / stop hooks)\",\n available: true,\n scaffoldPaths: [CURSOR_HOOKS_REL],\n write(ctx: WriteContext): void {\n mkdirSync(join(ctx.repoRoot, \".cursor\"), { recursive: true });\n const { content, action } = mergeCursorHooks(ctx.repoRoot);\n writeFileSync(cursorHooksPath(ctx.repoRoot), content, \"utf8\");\n ctx.report.files.push({ path: CURSOR_HOOKS_REL, action });\n },\n};\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { renderTemplate } from \"./templateDir.js\";\nimport type { InitFileAction } from \"./types.js\";\n\nexport const CURSOR_HOOKS_REL = \".cursor/hooks.json\";\n\nexport function cursorHooksPath(repoRoot: string): string {\n return join(repoRoot, \".cursor\", \"hooks.json\");\n}\n\ntype CursorHookEntry = { command: string };\n\n/** 每次 init 合并 hermes 管理的 sessionStart / stop 到 .cursor/hooks.json */\nexport function mergeCursorHooks(repoRoot: string): {\n content: string;\n action: InitFileAction;\n} {\n const hooksPath = cursorHooksPath(repoRoot);\n const existed = existsSync(hooksPath);\n\n const templateParsed = JSON.parse(renderTemplate(\"hooks.cursor.json.tpl\")) as {\n version: number;\n hooks: {\n sessionStart: CursorHookEntry[];\n stop: CursorHookEntry[];\n };\n };\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(hooksPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevHooks =\n existing.hooks &&\n typeof existing.hooks === \"object\" &&\n !Array.isArray(existing.hooks)\n ? (existing.hooks as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n version: templateParsed.version,\n hooks: {\n ...prevHooks,\n sessionStart: templateParsed.hooks.sessionStart,\n stop: templateParsed.hooks.stop,\n },\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import type { AssistantAdapter, AssistantId } from \"./types.js\";\nimport { claudeCodeAdapter } from \"./claude-code.js\";\nimport { codexAdapter } from \"./codex.js\";\nimport { codebuddyAdapter } from \"./codebuddy.js\";\nimport { cursorAdapter } from \"./cursor.js\";\n\nexport const DEFAULT_ASSISTANT_IDS: AssistantId[] = [\"claude-code\"];\n\nconst ALL_ADAPTERS: AssistantAdapter[] = [\n claudeCodeAdapter,\n cursorAdapter,\n codebuddyAdapter,\n codexAdapter,\n];\n\nconst ADAPTER_BY_ID = new Map<AssistantId, AssistantAdapter>(\n ALL_ADAPTERS.map((a) => [a.id, a]),\n);\n\nexport function getAdapter(id: AssistantId): AssistantAdapter {\n const adapter = ADAPTER_BY_ID.get(id);\n if (!adapter) {\n throw new Error(`Unknown assistant id: ${id}`);\n }\n return adapter;\n}\n\nexport function listAvailable(): AssistantAdapter[] {\n return ALL_ADAPTERS.filter((a) => a.available);\n}\n\nexport function isKnownAssistantId(id: string): id is AssistantId {\n return ADAPTER_BY_ID.has(id as AssistantId);\n}\n\nexport function parseToolsArg(tools: string): AssistantId[] {\n const ids = tools\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n if (ids.length === 0) {\n throw new Error(\"init --tools requires at least one assistant id\");\n }\n\n const result: AssistantId[] = [];\n for (const id of ids) {\n if (!isKnownAssistantId(id)) {\n throw new Error(`Unknown assistant id: ${id}`);\n }\n const adapter = getAdapter(id);\n if (!adapter.available) {\n throw new Error(`Assistant not available yet: ${id}`);\n }\n result.push(id);\n }\n return result;\n}\n\nexport function validateAssistantSelection(ids: AssistantId[]): void {\n if (ids.length === 0) {\n throw new Error(\"At least one assistant must be selected\");\n }\n for (const id of ids) {\n const adapter = getAdapter(id);\n if (!adapter.available) {\n throw new Error(`Assistant not available yet: ${id}`);\n }\n }\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { GITKEEP_DIRS, MEMORY_DIR, MEMORY_SUBDIRS } from \"./paths.js\";\n\nexport function ensureMemoryTree(repoRoot: string): void {\n const memoryRoot = join(repoRoot, MEMORY_DIR);\n mkdirSync(memoryRoot, { recursive: true });\n\n for (const sub of MEMORY_SUBDIRS) {\n mkdirSync(join(memoryRoot, sub), { recursive: true });\n }\n\n mkdirSync(join(repoRoot, \".claude\"), { recursive: true });\n\n for (const sub of GITKEEP_DIRS) {\n const keepPath = join(memoryRoot, sub, \".gitkeep\");\n writeFileSync(keepPath, \"\", { flag: \"a\" });\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport { memoryPath } from \"./paths.js\";\n\nfunction readExistingAssistants(repoRoot: string): AssistantId[] {\n const configPath = memoryPath(repoRoot, \"config.json\");\n if (!existsSync(configPath)) {\n return [];\n }\n try {\n const config = JSON.parse(readFileSync(configPath, \"utf8\")) as {\n assistants?: unknown;\n };\n if (!Array.isArray(config.assistants)) {\n return [];\n }\n return config.assistants.filter((id): id is AssistantId => typeof id === \"string\");\n } catch {\n return [];\n }\n}\n\n/** 与已有 config.assistants 做并集(保留已有 id + 追加本次选择) */\nexport function mergeAssistants(\n repoRoot: string,\n selected: AssistantId[],\n): AssistantId[] {\n const existing = readExistingAssistants(repoRoot);\n return [...new Set([...existing, ...selected])];\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readTemplate } from \"./templateDir.js\";\n\nconst START_MARKER = \"# >>> hermes-repo memory (do not edit this block manually)\";\nconst END_MARKER = \"# <<< hermes-repo memory\";\n\nexport type GitignoreMergeAction = \"created\" | \"updated\" | \"replaced\" | \"appended\";\n\nexport function mergeHermesGitignore(repoRoot: string): {\n action: GitignoreMergeAction;\n warnBroadMemoryIgnore: boolean;\n} {\n const block = readTemplate(\"gitignore-block.txt\").trimEnd() + \"\\n\";\n const gitignorePath = join(repoRoot, \".gitignore\");\n const contentBefore = existsSync(gitignorePath)\n ? readFileSync(gitignorePath, \"utf8\")\n : \"\";\n\n const warnBroadMemoryIgnore =\n contentBefore.length > 0 &&\n !contentBefore.includes(START_MARKER) &&\n /(^|\\n)\\.memory\\/\\s*$/m.test(contentBefore);\n\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, `${block}\\n`, \"utf8\");\n return { action: \"created\", warnBroadMemoryIgnore: false };\n }\n\n const startIdx = contentBefore.indexOf(START_MARKER);\n const endIdx = contentBefore.indexOf(END_MARKER);\n\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = contentBefore.slice(0, startIdx);\n const after = contentBefore.slice(endIdx + END_MARKER.length);\n const next = `${before}${block}${after}`.replace(/\\n{3,}/g, \"\\n\\n\");\n writeFileSync(gitignorePath, next.endsWith(\"\\n\") ? next : `${next}\\n`, \"utf8\");\n return { action: \"replaced\", warnBroadMemoryIgnore };\n }\n\n if (startIdx !== -1) {\n const before = contentBefore.slice(0, startIdx);\n const next = `${before}${block}\\n`;\n writeFileSync(gitignorePath, next, \"utf8\");\n return { action: \"updated\", warnBroadMemoryIgnore };\n }\n\n const separator = contentBefore.endsWith(\"\\n\") || contentBefore.length === 0 ? \"\\n\" : \"\\n\\n\";\n writeFileSync(gitignorePath, `${contentBefore}${separator}${block}\\n`, \"utf8\");\n return { action: \"appended\", warnBroadMemoryIgnore };\n}\n","import { copyFileSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { getAdapter } from \"./assistants/registry.js\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport type { InitReport, InitResolvedOptions } from \"./types.js\";\nimport { EXAMPLE_TEMPLATE_FILES, memoryPath } from \"./paths.js\";\nimport { renderTemplate, resolveTemplatePath } from \"./templateDir.js\";\nimport { mergeConfigForInit } from \"./mergeConfig.js\";\nimport { mergeAgentsMd } from \"./mergeAgentsMd.js\";\nimport { shouldWriteFile, writeIfAllowed } from \"./scaffoldWrite.js\";\n\nexport { shouldWriteFile } from \"./scaffoldWrite.js\";\n\n/** 生成 v2 config.json 内容 */\nexport function buildConfigJson(assistants: AssistantId[]): string {\n return `${JSON.stringify(\n {\n version: 2,\n storage: { backend: \"file\" },\n assistants,\n debug: false,\n llm: {\n enabled: false,\n baseUrl: \"https://api.openai.com/v1\",\n model: \"gpt-4o\",\n },\n consolidate: {\n autoArchiveDays: 30,\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction writeConfigJson(\n report: InitReport,\n repoRoot: string,\n assistants: AssistantId[],\n): void {\n const { content, action } = mergeConfigForInit(repoRoot, assistants);\n const absolutePath = memoryPath(repoRoot, \"config.json\");\n writeFileSync(absolutePath, content, \"utf8\");\n report.files.push({ path: \".memory/config.json\", action });\n}\n\nfunction copyTemplateIfAllowed(\n report: InitReport,\n templateName: string,\n destAbsolute: string,\n relativePath: string,\n force: boolean,\n): void {\n const { write, action } = shouldWriteFile(destAbsolute, force);\n if (!write) {\n report.files.push({ path: relativePath, action });\n return;\n }\n copyFileSync(resolveTemplatePath(templateName), destAbsolute);\n report.files.push({ path: relativePath, action });\n}\n\nexport function writeScaffoldFiles(\n repoRoot: string,\n opts: InitResolvedOptions,\n report: InitReport,\n): void {\n const { force, includeExampleTemplates, assistants } = opts;\n\n writeConfigJson(report, repoRoot, assistants);\n\n // v2: 不再生成 llm.json(已合并入 config.json)\n\n // MEMORY.md — v2 导航模板\n writeIfAllowed(\n report,\n memoryPath(repoRoot, \"MEMORY.md\"),\n \".memory/MEMORY.md\",\n renderTemplate(\"MEMORY.md.tpl\"),\n force,\n );\n\n // consolidate-state.json — 初始空状态\n writeIfAllowed(\n report,\n memoryPath(repoRoot, \"consolidate-state.json\"),\n \".memory/consolidate-state.json\",\n `${JSON.stringify(\n {\n version: 1,\n lastConsolidatedAt: null,\n stats: {\n totalCapturesProcessed: 0,\n domains: [],\n knowledgeFilesCreated: 0,\n },\n processedSessions: {},\n },\n null,\n 2,\n )}\\n`,\n force,\n );\n\n // v2: 不再生成 sessions/index.json 和 team/steward-log.md\n\n report.files.push({\n path: \"AGENTS.md\",\n action: mergeAgentsMd(repoRoot, force),\n });\n\n for (const id of assistants) {\n getAdapter(id).write({ repoRoot, force, report });\n }\n\n if (includeExampleTemplates && EXAMPLE_TEMPLATE_FILES.length > 0) {\n // v2: templates/ 目录不在 ensureMemoryTree 中,按需创建\n const templatesDir = memoryPath(repoRoot, \"templates\");\n mkdirSync(templatesDir, { recursive: true });\n for (const name of EXAMPLE_TEMPLATE_FILES) {\n const dest = memoryPath(repoRoot, \"templates\", name);\n copyTemplateIfAllowed(\n report,\n name,\n dest,\n `.memory/templates/${name}`,\n force,\n );\n }\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport type { InitFileAction } from \"./types.js\";\nimport { memoryPath } from \"./paths.js\";\n\n/** init 每次都会写入的 config 字段(其余顶层 / storage 子字段保留) */\nexport function mergeConfigForInit(\n repoRoot: string,\n assistants: AssistantId[],\n): { content: string; action: InitFileAction } {\n const configPath = memoryPath(repoRoot, \"config.json\");\n const existed = existsSync(configPath);\n\n let existing: Record<string, unknown> = {};\n if (existed) {\n try {\n existing = JSON.parse(readFileSync(configPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n existing = {};\n }\n }\n\n const prevStorage =\n existing.storage &&\n typeof existing.storage === \"object\" &&\n !Array.isArray(existing.storage)\n ? (existing.storage as Record<string, unknown>)\n : {};\n\n const merged: Record<string, unknown> = {\n ...existing,\n version: 1,\n storage: {\n ...prevStorage,\n backend: \"file\",\n },\n assistants,\n debug: existing.debug === true,\n };\n\n return {\n content: `${JSON.stringify(merged, null, 2)}\\n`,\n action: existed ? \"overwritten\" : \"created\",\n };\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { InitFileAction } from \"./types.js\";\nimport { readTemplate, renderTemplate } from \"./templateDir.js\";\n\nexport const HERMES_AGENTS_START_MARKER =\n \"<!-- >>> hermes-repo agents (do not edit this block manually) -->\";\nexport const HERMES_AGENTS_END_MARKER = \"<!-- <<< hermes-repo agents -->\";\n\nexport function buildHermesAgentsBlockBody(): string {\n return renderTemplate(\"AGENTS.hermes-block.tpl\").trimEnd();\n}\n\nexport function buildHermesAgentsMarkedBlock(): string {\n const body = buildHermesAgentsBlockBody();\n return `${HERMES_AGENTS_START_MARKER}\\n${body}\\n${HERMES_AGENTS_END_MARKER}`;\n}\n\nexport function buildNewAgentsMd(): string {\n return renderTemplate(\"AGENTS.md.tpl\").replace(\n \"__HERMES_AGENTS_BLOCK__\",\n buildHermesAgentsBlockBody(),\n );\n}\n\nexport function agentsMdHasHermesBlock(content: string): boolean {\n const startIdx = content.indexOf(HERMES_AGENTS_START_MARKER);\n const endIdx = content.indexOf(HERMES_AGENTS_END_MARKER);\n return startIdx !== -1 && endIdx !== -1 && endIdx > startIdx;\n}\n\n/** 无标记块但已手写 hermes 指引时视为已接入(避免重复追加) */\nexport function agentsMdHasLegacyHermesContent(content: string): boolean {\n if (agentsMdHasHermesBlock(content)) {\n return false;\n }\n return (\n content.includes(\"@riconext/hermes-repo\") &&\n content.includes(\"## 记忆系统\") &&\n content.includes(\".memory/MEMORY.md\")\n );\n}\n\nexport function agentsMdHasHermesContent(content: string): boolean {\n return agentsMdHasHermesBlock(content) || agentsMdHasLegacyHermesContent(content);\n}\n\n/** 已有正文与 hermes 标记块之间约两行空行 */\nconst GAP_BEFORE_HERMES_BLOCK = \"\\n\\n\\n\";\n\nfunction withGapBeforeHermesBlock(prefix: string): string {\n const trimmed = prefix.trimEnd();\n if (trimmed.length === 0) {\n return \"\";\n }\n return `${trimmed}${GAP_BEFORE_HERMES_BLOCK}`;\n}\n\nfunction spliceHermesBlock(existing: string, block: string): string {\n const startIdx = existing.indexOf(HERMES_AGENTS_START_MARKER);\n const endIdx = existing.indexOf(HERMES_AGENTS_END_MARKER);\n\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + HERMES_AGENTS_END_MARKER.length);\n const next = `${withGapBeforeHermesBlock(before)}${block}${after}`;\n return next.endsWith(\"\\n\") ? next : `${next}\\n`;\n }\n\n if (startIdx !== -1) {\n const before = existing.slice(0, startIdx);\n return `${withGapBeforeHermesBlock(before)}${block}\\n`;\n }\n\n return `${withGapBeforeHermesBlock(existing)}${block}\\n`;\n}\n\nexport function mergeAgentsMd(\n repoRoot: string,\n force: boolean,\n): InitFileAction {\n const agentsPath = join(repoRoot, \"AGENTS.md\");\n const block = buildHermesAgentsMarkedBlock();\n\n if (!existsSync(agentsPath)) {\n writeFileSync(agentsPath, buildNewAgentsMd(), \"utf8\");\n return \"created\";\n }\n\n const content = readFileSync(agentsPath, \"utf8\");\n\n if (agentsMdHasHermesBlock(content)) {\n if (!force) {\n return \"skipped\";\n }\n writeFileSync(agentsPath, spliceHermesBlock(content, block), \"utf8\");\n return \"replaced\";\n }\n\n if (agentsMdHasLegacyHermesContent(content)) {\n return \"skipped\";\n }\n\n writeFileSync(agentsPath, spliceHermesBlock(content, block), \"utf8\");\n return \"appended\";\n}\n","import { existsSync, writeFileSync } from \"node:fs\";\nimport type { InitFileAction, InitReport } from \"./types.js\";\n\nexport function shouldWriteFile(\n absolutePath: string,\n force: boolean,\n): { write: boolean; action: InitFileAction } {\n if (!existsSync(absolutePath)) {\n return { write: true, action: \"created\" };\n }\n if (force) {\n return { write: true, action: \"overwritten\" };\n }\n return { write: false, action: \"skipped\" };\n}\n\nexport function writeIfAllowed(\n report: InitReport,\n absolutePath: string,\n relativePath: string,\n content: string,\n force: boolean,\n): void {\n const { write, action } = shouldWriteFile(absolutePath, force);\n if (!write) {\n report.files.push({ path: relativePath, action });\n return;\n }\n writeFileSync(absolutePath, content, \"utf8\");\n report.files.push({ path: relativePath, action });\n}\n","import { checkbox, confirm, input } from \"@inquirer/prompts\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { listAvailable } from \"./assistants/registry.js\";\nimport type { AssistantId } from \"./assistants/types.js\";\nimport type { InitCliOptions, InitResolvedOptions } from \"./types.js\";\nimport { memoryPath } from \"./paths.js\";\n\nfunction isInitialized(targetDir: string): boolean {\n const configPath = memoryPath(targetDir, \"config.json\");\n if (!existsSync(configPath)) {\n return false;\n }\n try {\n const config = JSON.parse(readFileSync(configPath, \"utf8\")) as {\n version?: number;\n };\n return typeof config.version === \"number\" && config.version >= 1;\n } catch {\n return false;\n }\n}\n\nexport async function gatherInitOptions(\n opts: InitCliOptions,\n): Promise<InitResolvedOptions> {\n const defaultDir = resolve(opts.cwd ?? process.cwd());\n\n const targetInput = await input({\n message: \"目标目录(Git 仓库根)\",\n default: defaultDir,\n });\n const targetDir = resolve(targetInput);\n\n const assistants = (await checkbox({\n message: \"选择要接入的编程助手(可多选)\",\n choices: listAvailable().map((a) => ({\n name: a.label,\n value: a.id,\n checked: a.id === \"claude-code\",\n })),\n validate: (value) => value.length > 0 || \"请至少选择一项\",\n })) as AssistantId[];\n\n const includeExampleTemplates = await confirm({\n message: \"是否写入 capture 示例模板到 .memory/templates/?\",\n default: true,\n });\n\n if (isInitialized(targetDir)) {\n const continueInit = await confirm({\n message: \"检测到已有 .memory/config.json,是否仅补全缺失项?\",\n default: true,\n });\n if (!continueInit) {\n return {\n targetDir,\n force: false,\n includeExampleTemplates,\n assistants,\n cancelled: true,\n };\n }\n }\n\n return {\n targetDir,\n force: Boolean(opts.force),\n includeExampleTemplates,\n assistants,\n cancelled: false,\n };\n}\n","import type { InitCliOptions } from \"../init/types.js\";\nimport { runInit } from \"../init/runInit.js\";\n\nexport async function runInitCommand(opts: InitCliOptions): Promise<void> {\n try {\n await runInit(opts);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["join","dirname","join","join","existsSync","readFileSync","writeFileSync","join","existsSync","readFileSync","existsSync","readFileSync","readFileSync","text","existsSync","mkdirSync","readFileSync","dirname","join","join","dirname","existsSync","readFileSync","mkdirSync","existsSync","mkdirSync","readFileSync","writeFileSync","join","join","existsSync","mkdirSync","writeFileSync","readFileSync","readFileSync","writeFileSync","join","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","resolve","existsSync","mkdirSync","readFileSync","rmSync","writeFileSync","existsSync","readFileSync","mkdirSync","writeFileSync","rmSync","readdirSync","readFileSync","join","readdirSync","join","readFileSync","readFileSync","readdirSync","join","readdirSync","join","readFileSync","input","existsSync","mkdirSync","writeFileSync","dirname","dirname","mkdirSync","existsSync","writeFileSync","mkdirSync","renameSync","join","mkdirSync","renameSync","join","existsSync","readdirSync","readFileSync","basename","join","resolve","existsSync","readdirSync","join","basename","existsSync","readdirSync","statSync","homedir","basename","join","resolve","existsSync","readdirSync","statSync","homedir","join","resolve","collectJsonlRecursive","existsSync","readdirSync","readFileSync","join","existsSync","readFileSync","readdirSync","join","resolve","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","existsSync","readFileSync","dirname","join","fileURLToPath","readFileSync","dirname","join","fileURLToPath","dirname","fileURLToPath","join","existsSync","readFileSync","join","existsSync","readFileSync","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","join","existsSync","readFileSync","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","join","join","existsSync","readFileSync","mkdirSync","join","writeFileSync","mkdirSync","writeFileSync","join","join","mkdirSync","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","existsSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","writeFileSync","mkdirSync","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","existsSync","readFileSync","writeFileSync","join","spliceHermesBlock","join","existsSync","writeFileSync","readFileSync","existsSync","writeFileSync","writeFileSync","mkdirSync","existsSync","readFileSync","resolve","existsSync","readFileSync","resolve","resolve"]}