@lingjingai/scriptctl 0.61.0 → 0.61.2
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/changes/0.61.1.md +15 -0
- package/changes/0.61.2.md +10 -0
- package/dist/bin.js +16126 -11
- package/dist/bin.js.map +7 -1
- package/dist/cli/register-review.d.ts +3 -0
- package/dist/cli/register-review.js +19 -0
- package/dist/cli/register-review.js.map +1 -0
- package/dist/cli.js +4 -10
- package/dist/cli.js.map +1 -1
- package/dist/llm/config.js +4 -0
- package/dist/llm/config.js.map +1 -1
- package/dist/output.js +5 -0
- package/dist/output.js.map +1 -1
- package/dist/package-root.d.ts +2 -0
- package/dist/package-root.js +38 -0
- package/dist/package-root.js.map +1 -0
- package/dist/review-agent.js +2955 -0
- package/dist/review-agent.js.map +7 -0
- package/dist/usecases/changelog.js +3 -8
- package/dist/usecases/changelog.js.map +1 -1
- package/dist/usecases/script/review.d.ts +3 -0
- package/dist/usecases/script/review.js +185 -0
- package/dist/usecases/script/review.js.map +1 -0
- package/dist/usecases/update.js +2 -14
- package/dist/usecases/update.js.map +1 -1
- package/package.json +10 -3
- package/skills/scriptctl/SKILL.md +11 -2
package/dist/bin.js.map
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli.ts", "../src/common.ts", "../src/infra/storage.ts", "../src/failures.ts", "../src/usecases/changelog.ts", "../src/package-root.ts", "../src/usecases/doctor.ts", "../src/infra/env.ts", "../src/infra/script-output-store.ts", "../src/llm/config.ts", "../src/llm/registry.ts", "../src/llm/router.ts", "../src/infra/llm/anthropic-model.ts", "../src/llm/types.ts", "../src/infra/llm/retry.ts", "../src/infra/llm/doubao-video-model.ts", "../src/infra/llm/failure-mapping.ts", "../src/infra/llm/gemini-video-model.ts", "../src/infra/llm/gemini-upload.ts", "../src/infra/llm/openai-compatible-model.ts", "../src/usecases/update.ts", "../src/infra/script-working-copy.ts", "../src/output.ts", "../src/cli/registry.ts", "../src/cli/register-tools.ts", "../src/usecases/script/review.ts", "../src/domain/script/shared.ts", "../src/cli/register-review.ts", "../src/cli/register-script.ts", "../packages/screenplay/dist/model.js", "../packages/screenplay/dist/trace.js", "../packages/screenplay/dist/schema/types.js", "../packages/screenplay/dist/schema/names.js", "../packages/screenplay/dist/schema/issues.js", "../packages/screenplay/dist/schema/ids.js", "../packages/screenplay/dist/schema/timestamp.js", "../packages/screenplay/dist/schema/v3.js", "../packages/screenplay/dist/schema/v4.js", "../packages/screenplay/dist/text.js", "../packages/screenplay/dist/span.js", "../packages/screenplay/dist/tools.js", "../src/usecases/ingest/command.ts", "../src/infra/ingest/source-resolver.ts", "../src/llm/composition.ts", "../src/usecases/ingest/pipeline.ts", "../src/domain/ingest/assembler.ts", "../src/domain/ingest/chunker.ts", "../src/domain/ingest/records.ts", "../src/domain/ingest/environment.ts", "../src/domain/ingest/jsonl-parser.ts", "../src/domain/ingest/serial-context.ts", "../src/domain/ingest/production-validation.ts", "../src/domain/ingest/renumber.ts", "../src/domain/script/v3/parse.ts", "../src/domain/script/v4/from-v3.ts", "../src/domain/script/v3/address.ts", "../src/domain/script/text-util.ts", "../src/domain/script/v4/ids.ts", "../src/infra/ingest/text-reader.ts", "../src/infra/converters.ts", "../src/infra/ingest/workspace-store.ts", "../src/llm/tasks/ingest/text-normalize.ts", "../src/llm/tasks/ingest/body-start.ts", "../src/usecases/ingest/body-start.ts", "../src/usecases/ingest/fanout.ts", "../src/domain/ingest/govern.ts", "../src/llm/tasks/ingest/arc-summary.ts", "../src/llm/tasks/schemas.ts", "../src/llm/tasks/ingest/episode-assets.ts", "../src/llm/tasks/ingest/name-fix.ts", "../src/usecases/ingest/serial-govern.ts", "../src/domain/ingest/asset-audit.ts", "../src/llm/tasks/ingest/asset-audit.ts", "../src/usecases/ingest/final-asset-audit.ts", "../src/usecases/ingest/timings.ts", "../src/usecases/ingest/usage-report.ts", "../src/usecases/ingest/video-pipeline.ts", "../src/domain/ingest/video-source-evolution.ts", "../src/domain/ingest/video-timestamp.ts", "../src/domain/ingest/video-apply.ts", "../src/domain/ingest/video-context.ts", "../src/domain/ingest/video-state-evidence.ts", "../src/infra/ingest/video-discovery.ts", "../src/infra/ingest/video-source-snapshot.ts", "../src/infra/ingest/video-transcode.ts", "../src/infra/ingest/video-state-evidence.ts", "../src/infra/ingest/workspace-lock.ts", "../src/llm/tasks/ingest/video-serial.ts", "../src/usecases/ingest/failure.ts", "../src/usecases/ingest/video-skip-state.ts", "../src/usecases/ingest/status.ts", "../src/usecases/ingest/skip-video-episode.ts", "../src/usecases/ingest/generate-video-state-evidence.ts", "../src/domain/script/v4/parse.ts", "../src/usecases/ingest/view-command.ts", "../src/infra/ingest/review-renderer.ts", "../src/usecases/ingest/view-server.ts", "../src/usecases/script/audit-assets.ts", "../src/domain/script/dispatch.ts", "../src/infra/script-output-api.ts", "../src/usecases/script/session.ts", "../src/domain/script/v4/factory.ts", "../src/domain/script/v3/scene-refs.ts", "../src/usecases/script/lib.ts", "../src/usecases/script/create.ts", "../src/usecases/script/migrate.ts", "../src/domain/script/migrations/v3-to-v4.ts", "../src/domain/script/migrations/registry.ts", "../src/usecases/script/synopsis-generate.ts", "../src/domain/loom/checkpointer.ts", "../src/domain/loom/index.ts", "../src/usecases/script/working-copy.ts", "../src/cli/register-workflows.ts", "../src/bin.ts"],
|
|
4
|
+
"sourcesContent": ["\nimport { Command, CommanderError, Option } from \"commander\";\n\nimport { CliError, EXIT_OK, EXIT_USAGE } from \"./common.js\";\nimport { formatFailure } from \"./failures.js\";\nimport { type RunState } from \"./cli/registry.js\";\nimport { registerToolCommands } from \"./cli/register-tools.js\";\nimport { registerReviewCommand } from \"./cli/register-review.js\";\nimport { registerScriptCommands } from \"./cli/register-script.js\";\nimport { registerWorkflowCommands } from \"./cli/register-workflows.js\";\nimport { loadLocalEnv } from \"./infra/env.js\";\nimport { PRODUCTION_LLM_COMPOSITION, type LlmComposition } from \"./llm/composition.js\";\nimport { LlmTransportError } from \"./llm/types.js\";\nimport { emitError } from \"./output.js\";\nimport { packageVersion } from \"./package-root.js\";\n\n\n\nexport function buildProgram(state: RunState, llm: LlmComposition = PRODUCTION_LLM_COMPOSITION): Command {\n const program = new Command(\"scriptctl\")\n .description(\"Read, edit, ingest, and publish structured scripts\")\n .usage(\"<command> [options]\")\n .exitOverride()\n .allowExcessArguments(false)\n .allowUnknownOption(false)\n .showHelpAfterError(false)\n .configureOutput({\n writeOut: (text) => process.stdout.write(text),\n writeErr: () => {\n // Commander errors are emitted once through the scriptctl error model.\n },\n })\n .option(\"-j, --json\", \"Output structured JSON\")\n .option(\"--format <format>\", \"Output format (addr)\")\n .version(packageVersion(), \"-v, --version\", \"Show the scriptctl version\");\n\n registerWorkflowCommands(program, state, llm);\n registerScriptCommands(program, state);\n registerReviewCommand(program, state);\n registerToolCommands(program, state);\n return program;\n}\n\nfunction optionFor(command: Command, token: string): Option | undefined {\n const flag = token.split(\"=\", 1)[0];\n let current: Command | null | undefined = command;\n while (current) {\n const option = current.options.find((candidate) => candidate.short === flag || candidate.long === flag);\n if (option) return option;\n current = current.parent;\n }\n return undefined;\n}\n\ninterface ShortOptionScan {\n recognized: boolean;\n json: boolean;\n valueOption?: Option;\n hasAttachedValue: boolean;\n}\n\nfunction scanShortOptions(command: Command, token: string): ShortOptionScan {\n if (!token.startsWith(\"-\") || token.startsWith(\"--\") || token.length < 2) {\n return { recognized: false, json: false, hasAttachedValue: false };\n }\n let json = false;\n for (let index = 1; index < token.length; index += 1) {\n const option = optionFor(command, `-${token[index]}`);\n if (!option?.short) {\n return { recognized: false, json: false, hasAttachedValue: false };\n }\n if (option.short === \"-j\") json = true;\n if (option.required || option.optional) {\n return {\n recognized: true,\n json,\n valueOption: option,\n hasAttachedValue: index < token.length - 1,\n };\n }\n }\n return { recognized: true, json, hasAttachedValue: false };\n}\n\nfunction isRecognizedOptionToken(command: Command, token: string): boolean {\n if (token === \"--\") return true;\n if (token.startsWith(\"--\")) return optionFor(command, token) !== undefined;\n return scanShortOptions(command, token).recognized;\n}\n\nfunction consumesNextValue(command: Command, option: Option, next: string | undefined): boolean {\n if (next === undefined || next === \"--\") return false;\n if (option.required) return !isRecognizedOptionToken(command, next);\n return option.optional && !next.startsWith(\"-\");\n}\n\nfunction initialJsonMode(program: Command, args: readonly string[]): boolean {\n let command = program;\n for (let index = 0; index < args.length; index += 1) {\n const token = args[index]!;\n if (token === \"--\") break;\n if (token.startsWith(\"--\")) {\n if (token === \"--json\") return true;\n const option = optionFor(command, token);\n if (\n option\n && !token.includes(\"=\")\n && consumesNextValue(command, option, args[index + 1])\n ) index += 1;\n continue;\n }\n if (token.startsWith(\"-\")) {\n const scanned = scanShortOptions(command, token);\n if (scanned.recognized && scanned.json) return true;\n if (\n scanned.recognized\n && scanned.valueOption\n && !scanned.hasAttachedValue\n && consumesNextValue(command, scanned.valueOption, args[index + 1])\n ) index += 1;\n continue;\n }\n const child = command.commands.find((candidate) => candidate.name() === token);\n if (child) command = child;\n }\n return false;\n}\n\nfunction helpTarget(program: Command, args: readonly string[]): string {\n let command = program;\n for (let index = 0; index < args.length; index += 1) {\n const token = args[index]!;\n if (token.startsWith(\"-\")) {\n const option = optionFor(command, token);\n if (option && !token.includes(\"=\") && (option.required || option.optional)) index += 1;\n continue;\n }\n const child = command.commands.find((candidate) => candidate.name() === token);\n if (!child) break;\n command = child;\n }\n const names: string[] = [];\n let current: Command | null | undefined = command;\n while (current && current.parent) {\n names.unshift(current.name());\n current = current.parent;\n }\n return [\"scriptctl\", ...names, \"--help\"].join(\" \");\n}\n\nfunction commanderMessage(error: CommanderError): string {\n return error.message.replace(/^error:\\s*/i, \"\").replace(/\\.$/, \"\");\n}\n\nexport async function main(\n argv: string[] | null = null,\n llm: LlmComposition = PRODUCTION_LLM_COMPOSITION,\n): Promise<number> {\n loadLocalEnv();\n const args = argv ?? process.argv.slice(2);\n const state: RunState = { jsonMode: false, exitCode: EXIT_OK };\n const program = buildProgram(state, llm);\n state.jsonMode = initialJsonMode(program, args);\n\n if (args.length === 0) {\n program.outputHelp();\n return EXIT_OK;\n }\n\n try {\n await program.parseAsync(args, { from: \"user\" });\n return state.exitCode;\n } catch (error) {\n if (error instanceof CommanderError) {\n if (\n error.code === \"commander.help\"\n || error.code === \"commander.helpDisplayed\"\n || error.code === \"commander.version\"\n ) {\n return EXIT_OK;\n }\n return emitError(\n new CliError(commanderMessage(error), {\n exitCode: EXIT_USAGE,\n errorCode: \"USAGE_ERROR\",\n hint: `Run '${helpTarget(program, args)}'.`,\n }),\n state.jsonMode,\n );\n }\n if (error instanceof CliError) return emitError(error, state.jsonMode);\n if (error instanceof LlmTransportError) {\n return emitError(\n new CliError(formatFailure(error.failure), {\n exitCode: 70,\n errorCode: \"RUNTIME_ERROR\",\n }),\n state.jsonMode,\n );\n }\n const message = error instanceof Error ? error.message : String(error);\n return emitError(\n new CliError(message, {\n exitCode: 70,\n errorCode: \"RUNTIME_ERROR\",\n }),\n state.jsonMode,\n );\n }\n}\n", "import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n DEFAULT_STORE,\n WorkspaceLayout,\n type ArtifactStore,\n} from \"./infra/storage.js\";\n\nexport const EXIT_OK = 0;\nexport const EXIT_USAGE = 64;\nexport const EXIT_INPUT = 66;\nexport const EXIT_RUNTIME = 70;\nexport const EXIT_NEEDS_AGENT = 78;\n\nexport const DEFAULT_CONCURRENCY = 30;\n// direct init fans out many small, independent batch/title extractions; it runs\n// hotter than the generic default. Other commands keep DEFAULT_CONCURRENCY.\nexport const DEFAULT_DIRECT_CONCURRENCY = 80;\nexport const DEFAULT_BATCH_TARGET_LINES = 36;\nexport const DEFAULT_BATCH_MAX_CHARS = 1800;\nexport const DEFAULT_BATCH_MIN_LINES = 12;\nexport const DEFAULT_BATCH_MODE = \"episode\";\n// Whole-script synopsis reduce: if the concatenated episode synopses fit within\n// this many chars, reduce them in one LLM call; otherwise group + merge in\n// multiple levels. DEFAULT_SUMMARY_GROUP_SIZE is the fallback episodes-per-group\n// cap when char-based grouping still needs a hard bound.\nexport const DEFAULT_SUMMARY_REDUCE_THRESHOLD_CHARS = 6000;\nexport const DEFAULT_SUMMARY_GROUP_SIZE = 8;\n\nexport const DIRECT_REL = path.join(\"draft\", \"scriptctl\", \"direct\");\nexport const SCRIPT_REL = path.join(\"workspace\", \"script.json\");\nexport const SUPPORTED_EXTS = \".txt/.md/.docx/.xlsx/.json\";\nexport const DIRECT_CONTRACT_VERSION = 3;\nexport const SCRIPT_SCHEMA_VERSION = 2;\n\nexport const WORLDVIEW_VALUES = [\n \"\u4E0A\u53E4\u65F6\u4EE3\",\n \"\u53E4\u4EE3\u5386\u53F2\",\n \"\u53E4\u98CE\u67B6\u7A7A\",\n \"\u8FD1\u4EE3\u6C11\u56FD\",\n \"\u73B0\u4EE3\",\n \"\u6B27\u6D32\u4E2D\u4E16\u7EAA\",\n \"\u8D5B\u535A\u670B\u514B\",\n \"\u661F\u9645\u65F6\u4EE3\",\n \"\u897F\u5E7B\u67B6\u7A7A\",\n];\n\nexport const SCRIPT_TARGET_KINDS = new Set([\"actor\", \"location\", \"prop\"]);\nexport const DELIVERY_VALUES = new Set([\"single\", \"simultaneous\", \"overlap\", \"group\"]);\nexport const EFFECTIVE_FROM_VALUES = new Set([\"before_action\", \"after_action\"]);\n\n// Spec for the subagent-driven `scriptctl parse` workflow. Unlike direct batch\n// extraction, the \u6B63\u6587 md carries ONLY the\n// screenplay and registers no assets; each asset KIND lives in its own file\n// (\u4EBA\u7269 / \u573A\u666F / \u9053\u5177 / \u53D1\u58F0\u6E90), plus an optional \u6897\u6982.md for the whole-script\n// synopsis. Many subagents work in parallel \u2014 body md never collide; each asset\n// file is a shared registry consolidated + de-duplicated at parse time.\nexport const PARSE_MD_SPEC =\n \"scriptctl parse \u8F93\u5165 = \u4E00\u4E2A md \u5DE5\u4F5C\u533A\u76EE\u5F55\u3002\u6587\u4EF6\u6309\u804C\u8D23\u5206\u5F00\uFF0C\u4E92\u4E0D\u6DF7\u5199\uFF1A\\n\" +\n \"\\n\" +\n \" ep_001.md, ep_002.md, ... \u6B63\u6587\uFF08\u6BCF\u96C6\u4E00\u4E2A\uFF0C\u53EA\u653E\u5267\u672C\u672C\u8EAB\uFF09\\n\" +\n \" \u4EBA\u7269.md \u5168\u5267\u552F\u4E00\u4E00\u4EFD\u89D2\u8272\u767B\u8BB0\uFF08\u6240\u6709 worker \u5171\u540C\u5F80\u91CC\u52A0\uFF09\\n\" +\n \" \u573A\u666F.md \u5168\u5267\u552F\u4E00\u4E00\u4EFD\u5730\u70B9\u767B\u8BB0\\n\" +\n \" \u9053\u5177.md \u5168\u5267\u552F\u4E00\u4E00\u4EFD\u9053\u5177\u767B\u8BB0\\n\" +\n \" \u53D1\u58F0\u6E90.md \u5168\u5267\u552F\u4E00\u4E00\u4EFD\u975E\u4EBA\u7269\u53D1\u58F0\u6E90\u767B\u8BB0\\n\" +\n \" \u6897\u6982.md \uFF08\u53EF\u9009\uFF09\u6574\u90E8\u5168\u6587\u6897\u6982\\n\" +\n \"\\n\" +\n \"\uD83D\uDD34 \u94C1\u5F8B\uFF1A\u6B63\u6587 md \u53EA\u7BA1\u6B63\u6587\uFF0C\u7EDD\u4E0D\u5728\u6B63\u6587\u91CC\u767B\u8BB0/\u8F93\u51FA\u4EFB\u4F55\u8D44\u4EA7\u3002\u8D44\u4EA7\u4E00\u5F8B\u767B\u8BB0\u5230\u4E0A\u9762\u5BF9\u5E94\\n\" +\n \" \u7684 \u4EBA\u7269/\u573A\u666F/\u9053\u5177/\u53D1\u58F0\u6E90 md \u91CC\u3002\u6B63\u6587\u91CC\u53EA\u201C\u5F15\u7528\u201D\u540D\u5B57\u4E0E\u5DF2\u767B\u8BB0\u72B6\u6001\uFF0C\u4E0D\u5199\u63CF\u8FF0\u3002\\n\" +\n \"\uD83D\uDD34 \u8D44\u4EA7\u5C31\u8FD9 4 \u4EFD\uFF0C\u5168\u5267\u5171\u7528\u3001\u5927\u5BB6\u4E00\u8D77\u52A0\uFF1B\u540C\u540D\u53EA\u767B\u4E00\u6B21\uFF0C\u91CD\u590D\u65E0\u59A8\uFF08parse / \u5408\u5E76\u9636\u6BB5\u53BB\u91CD\uFF09\u3002\\n\" +\n \"\uD83D\uDFE1 \u53EA\u6709\u6B63\u6587\u3001\u8FD8\u6CA1\u5199\u8D44\u4EA7 md\uFF1F\u5148\u8DD1 `scriptctl parse <dir> --extract-assets`\uFF1A\u5B83\u4ECE\u6B63\u6587\u91CC\\n\" +\n \" \u5F15\u7528\u5230\u7684\u8D44\u4EA7\u540D\u51FA\u53D1\uFF0C\u7528 LLM \u8865\u51FA\u63CF\u8FF0 / \u4E16\u754C\u89C2 / \u4E3B\u89D2\uFF0C\u5199\u56DE\u4E0A\u9762\u8FD9\u51E0\u4EFD\u8D44\u4EA7 md \u4F9B\u4F60\u590D\u6838\uFF1B\\n\" +\n \" \u590D\u6838\u5FAE\u8C03\u540E\u518D\u8DD1 `scriptctl parse <dir>`\uFF08\u7EAF\u786E\u5B9A\u6027\uFF09\u88C5\u914D script.json\u3002\\n\" +\n \"\\n\" +\n \"==================== 1. \u6B63\u6587 md\uFF08\u6BCF\u96C6\u4E00\u4E2A\uFF0Cep_<NNN>.md\uFF09 ====================\\n\" +\n \"# <\u672C\u96C6\u6807\u9898> \u2190 \u7B2C\u4E00\u884C\uFF0C\u975E\u300C\u5267\u672C/\u6897\u6982\u300D\u7684\u9876\u7EA7\u6807\u9898\u5373\u672C\u96C6\u6807\u9898\uFF1B\u7F3A\u7701\u65F6 parse \u4ECE\u6B63\u6587\u751F\u6210\u77ED\u6807\u9898\\n\" +\n \"\\n\" +\n \"## \u6897\u6982\\n\" +\n \"<\u672C\u96C6\u4E00\u6BB5\u8BDD\u6897\u6982\uFF0C\u7EAF\u6587\u672C\uFF0C\u53EF\u591A\u884C>\\n\" +\n \"\\n\" +\n \"# \u5267\u672C\\n\" +\n \"\\n\" +\n \"## \u573A\u666F 1\\n\" +\n \"- \u65F6\u7A7A: <\u5185|\u5916> <\u65E5|\u591C>\\n\" +\n \"- \u5730\u70B9: <\u5730\u70B9\u540D>[\u573A\u666F\u72B6\u6001] \u2190 \u53EA\u5199\u540D\u5B57\uFF0C\u5F15\u7528 \u573A\u666F.md \u91CC\u767B\u8BB0\u7684\u5730\u70B9/\u72B6\u6001\\n\" +\n \"- \u89D2\u8272: <\u89D2\u82721>, <\u89D2\u82722>(\u72B6\u6001), <\u89D2\u82723> \u2190 \u53EA\u5199\u540D\u5B57\uFF0C\u5F15\u7528 \u4EBA\u7269.md \u91CC\u767B\u8BB0\u7684\u89D2\u8272/\u72B6\u6001\\n\" +\n \"- \u9053\u5177: <\u9053\u51771>, <\u9053\u51772>(\u72B6\u6001), <\u9053\u51773>[\u72B6\u6001] \u2190 \u53EA\u5199\u540D\u5B57\uFF0C\u5F15\u7528 \u9053\u5177.md \u91CC\u767B\u8BB0\u7684\u9053\u5177/\u72B6\u6001\\n\" +\n \"\\n\" +\n \"> [act] \u52A8\u4F5C\u6216\u73AF\u5883\u63CF\u5199\u3002\\n\" +\n \"> [dlg|name] \u89D2\u8272\u5BF9\u767D\u539F\u6587\u3002\\n\" +\n \"> [dlg|name|emotion] \u5E26\u60C5\u7EEA\u6807\u7B7E\u7684\u5BF9\u767D\u3002\\n\" +\n \"> [dlg|system:<\u53D1\u58F0\u6E90\u540D>] \u975E\u4EBA\u7269\u53D1\u58F0\u6E90\u5BF9\u767D\u3002\\n\" +\n \"> [dlg|prop:<\u9053\u5177\u540D>] \u9053\u5177\u53D1\u58F0\u5BF9\u767D\u3002\\n\" +\n \"> [dlg|broadcast:<\u5E7F\u64AD\u540D>] \u5E7F\u64AD / \u5587\u53ED\u53D1\u58F0\u5BF9\u767D\u3002\\n\" +\n \"> [dlg|<speaker1>/<speaker2>|simultaneous] \u591A\u4EBA\u540C\u65F6\u8BF4\u540C\u4E00\u53E5\u3002\\n\" +\n \"> [dlg|overlap] <speaker1>:<line1> / <speaker2>:<line2>\\n\" +\n \"> [think|name] \u89D2\u8272\u5FC3\u58F0/\u5185\u5FC3\u72EC\u767D\u3002\\n\" +\n \"\\n\" +\n \"## \u573A\u666F 2\\n\" +\n \"...\\n\" +\n \"\\n\" +\n \"\u8D44\u4EA7 md \u7684\u683C\u5F0F\uFF1A\u6BCF\u4E2A\u8D44\u4EA7\u4E00\u4E2A\u9876\u7EA7 bullet\uFF0C\u5B83\u7684\u201C\u72B6\u6001\u201D\uFF08\u5916\u89C2\u9020\u578B\u6863\u4F4D\uFF09\u5199\u6210\u7F29\u8FDB\u7684\u5B50 bullet\u3002\\n\" +\n \" - <\u8D44\u4EA7\u540D>: <\u8EAB\u4EFD/\u63CF\u8FF0>\\n\" +\n \" - <\u72B6\u6001\u540D>: <\u8FD9\u4E2A\u72B6\u6001\u4E0B\u7684\u5177\u4F53\u53EF\u89C6\u5916\u89C2>\\n\" +\n \" - <\u72B6\u6001\u540D>: ...\\n\" +\n \"\uFF08\u4E5F\u63A5\u53D7\u6241\u5E73\u5199\u6CD5 `- <\u8D44\u4EA7\u540D>|<\u72B6\u6001\u540D>: \u63CF\u8FF0`\uFF1B\u4E24\u79CD\u90FD\u884C\uFF0C\u6700\u540E\u5408\u5E76\u53BB\u91CD\u3002\uFF09\\n\" +\n \"\u6B63\u6587\u672A\u663E\u5F0F\u5199\u72B6\u6001\u65F6\uFF0Cparse \u4F1A\u81EA\u52A8\u7ED1\u5B9A\u8BE5\u8D44\u4EA7\u7684 `\u9ED8\u8BA4` \u72B6\u6001\uFF1B\u6CA1\u6709 `\u9ED8\u8BA4` \u4E14\u53EA\u6709\u4E00\u4E2A\u72B6\u6001\u65F6\uFF0C\u7ED1\u5B9A\u552F\u4E00\u72B6\u6001\u3002\\n\" +\n \"\u591A\u4E2A\u975E\u9ED8\u8BA4\u72B6\u6001\u65E0\u6CD5\u786E\u5B9A\u65F6\u4FDD\u6301 state_id:null\uFF0C\u5E76\u7531 validate \u7ED9\u51FA warning\u3002\\n\" +\n \"\\n\" +\n \"==================== 2. \u4EBA\u7269.md\uFF08\u89D2\u8272\u767B\u8BB0 + \u72B6\u6001\uFF09 ====================\\n\" +\n \"# \u4EBA\u7269\\n\" +\n \"- <\u89D2\u8272\u540D>: <\u89D2\u8272\u8EAB\u4EFD/\u5916\u8C8C\u63CF\u8FF0> \u2190 \u6BCF\u4E2A\u4F1A\u5728\u6B63\u6587\u51FA\u73B0\u7684\u89D2\u8272\u90FD\u8981\u767B\u8BB0\u4E14\u6709\u975E\u7A7A\u63CF\u8FF0\\n\" +\n \" - \u9ED8\u8BA4: <\u8FD9\u4E2A\u89D2\u8272\u9ED8\u8BA4\u5F62\u8C61\u7684\u5177\u4F53\u5916\u89C2>\\n\" +\n \" - <\u72B6\u6001\u540D>: <\u6362\u88C5/\u9020\u578B\u540E\u7684\u5177\u4F53\u5916\u89C2> \u2190 \u6301\u4E45\u5916\u89C2\u9020\u578B\u6863\u4F4D\uFF08\u6574\u5957\u7740\u88C5/\u53D1\u578B/\u6301\u7EED\u5986\u9020\uFF09\\n\" +\n \"\\n\" +\n \"==================== 3. \u573A\u666F.md\uFF08\u5730\u70B9\u767B\u8BB0 + \u72B6\u6001\uFF09 ====================\\n\" +\n \"# \u573A\u666F\\n\" +\n \"- <\u5730\u70B9\u540D>: <\u5730\u70B9\u7528\u9014/\u6C1B\u56F4>\\n\" +\n \" - \u9ED8\u8BA4: <\u9ED8\u8BA4\u73AF\u5883\u5916\u89C2>\\n\" +\n \" - <\u72B6\u6001\u540D>: <\u4F8B\u5982 \u767D\u5929/\u591C\u665A/\u88AB\u6BC1\u540E \u7684\u5916\u89C2>\\n\" +\n \"\\n\" +\n \"==================== 4. \u9053\u5177.md\uFF08\u9053\u5177\u767B\u8BB0 + \u72B6\u6001\uFF09 ====================\\n\" +\n \"# \u9053\u5177\\n\" +\n \"- <\u9053\u5177\u540D>: <\u9053\u5177\u63CF\u8FF0>\\n\" +\n \" - \u9ED8\u8BA4: <\u9ED8\u8BA4\u5916\u89C2>\\n\" +\n \" - <\u72B6\u6001\u540D>: <\u4F8B\u5982 \u7834\u635F/\u53D1\u5149 \u7684\u5916\u89C2>\\n\" +\n \"\\n\" +\n \"==================== 5. \u53D1\u58F0\u6E90.md\uFF08\u975E\u4EBA\u7269\u53D1\u58F0\u6E90\u767B\u8BB0\uFF0C\u65E0\u72B6\u6001\uFF09 ====================\\n\" +\n \"# \u53D1\u58F0\u6E90\\n\" +\n \"- <\u53D1\u58F0\u6E90\u540D>(system): <\u58F0\u97F3\u63CF\u8FF0>\\n\" +\n \"- <\u5E7F\u64AD\u540D>(broadcast)\\n\" +\n \"- <\u7FA4\u4F53\u540D>(group)\\n\" +\n \"\\n\" +\n \"==================== 6. \u6897\u6982.md\uFF08\u53EF\u9009\uFF0C\u6574\u90E8\u5168\u6587\u6897\u6982\uFF09 ====================\\n\" +\n \"# \u6897\u6982\\n\" +\n \"<\u6574\u90E8\u5168\u6587\u6897\u6982\uFF0C\u7EAF\u6587\u672C\uFF0C\u53EF\u591A\u884C>\\n\" +\n \"\\n\" +\n \"==================== 7. \u5143\u4FE1\u606F.md\uFF08\u53EF\u9009\uFF0C\u6574\u90E8\u5143\u4FE1\u606F\uFF1B\u4E00\u822C\u7531 merger \u6536\u53E3\u65F6\u5199\uFF09 ====================\\n\" +\n \"worldview: <\u4E16\u754C\u89C2\uFF0C\u53D6\u8FD9\u4E9B\u679A\u4E3E\u4E4B\u4E00\uFF1A\" + WORLDVIEW_VALUES.join(\" / \") + \">\\n\" +\n \"style: <\u98CE\u683C\uFF0C\u81EA\u7531\u6587\u672C\uFF0C\u5982 \u90FD\u5E02\u751C\u5BA0 / \u60AC\u7591\u590D\u4EC7>\\n\" +\n \"title: <\u5267\u540D>\\n\" +\n \"\u4E3B\u89D2: <\u4E3B\u89D2\u540D1>, <\u4E3B\u89D2\u540D2> \u2190 \u5217\u5728\u8FD9\u91CC\u7684\u8BBE\u4E3A role_type=\u4E3B\u89D2\uFF0C\u5176\u4F59\u89D2\u8272=\u914D\u89D2\\n\" +\n \"\\n\" +\n \"Rules:\\n\" +\n \"- \u6B63\u6587 `- \u89D2\u8272/\u5730\u70B9/\u9053\u5177:` \u548C\u5BF9\u767D anchor \u7528\u7684\u540D\u5B57\uFF0C\u5FC5\u987B\u662F\u5BF9\u5E94 md \u91CC\u767B\u8BB0\u7684\u89C4\u8303\u540D\u3002\\n\" +\n \"- \uD83D\uDD34 \u72B6\u6001\u8981\u62BD\u5168\uFF1A\u51E1\u662F\u67D0\u89D2\u8272/\u5730\u70B9/\u9053\u5177\u5728\u5267\u4E2D\u51FA\u73B0\u53EF\u8FA8\u7684\u6301\u4E45\u5916\u89C2\u6863\u4F4D\uFF08\u6362\u88C5\u3001\u53D1\u578B\u3001\u663E\u8457\\n\" +\n \" \u4F24\u5986\u3001\u573A\u666F\u767D\u5929/\u591C\u665A/\u88AB\u6BC1\u7B49\uFF09\uFF0C\u90FD\u8981\u5728\u5176\u4E0B\u767B\u4E00\u4E2A\u72B6\u6001\u5B50 bullet\uFF1B\u5E76\u5728\u6B63\u6587\u573A\u666F `- \u89D2\u8272:`\\n\" +\n \" \u884C\u7528 `\u540D(\u72B6\u6001\u540D)` \u5F15\u7528\u5F53\u96C6\u6240\u5904\u72B6\u6001\uFF0C\u6CA1\u5199=\u9ED8\u8BA4\u3002\u7ED9\u6BCF\u4E2A\u8D44\u4EA7\u81F3\u5C11\u767B\u4E00\u4E2A `\u9ED8\u8BA4` \u72B6\u6001\u3002\\n\" +\n \"- \u72B6\u6001\u63CF\u8FF0\u53EA\u5199\u7A33\u5B9A\u53EF\u89C6\u5916\u89C2\uFF0C\u4E0D\u5199\u955C\u5934/\u5267\u60C5\u8C03\u5EA6\uFF1B\u4E0D\u8981\u628A\u201C\u80CC\u5BF9\u955C\u5934\u3001\u6B63\u8138\u672A\u9732\u3001\u7279\u5199\u3001\\n\" +\n \" \u521D\u59CB\u3001\u8F6C\u8EAB\u3001\u63A5\u8FC7\u624B\u3001\u62E5\u543B\u3001\u7AD9\u5728\u821E\u53F0\u4E0A\u201D\u7B49\u52A8\u4F5C\u3001\u906E\u6321\u3001\u673A\u4F4D\u6216\u60C5\u8282\u8BCD\u5199\u8FDB\u72B6\u6001\u63CF\u8FF0\u3002\\n\" +\n \"- \u6BCF\u4E2A\u72B6\u6001\u53EF\u5728\u4E0B\u4E00\u884C\u5199 `\u63D0\u53D6\u7F18\u7531:`\uFF0C\u7528\u81EA\u7136\u8BED\u8A00\u8BF4\u660E\u539F\u6587\u8BC1\u636E\u548C\u4E3A\u4EC0\u4E48\u5B83\u662F\u72EC\u7ACB\u53EF\u590D\u7528\\n\" +\n \" \u5916\u89C2\u72B6\u6001\uFF1B\u4E0D\u8981\u5199\u7ED3\u6784\u5316\u6807\u7B7E\u3002\u8FDE\u7EED\u53D8\u5316\u8FC7\u7A0B\u5E27\u3001\u5C40\u90E8\u5149\u6548\u5F3A\u5F31\u3001\u900F\u660E/\u6D88\u6563/\u51DD\u5B9E\u8FDB\u5EA6\u3001\\n\" +\n \" \u660F\u8FF7\u5367\u5E8A\u3001\u666E\u901A\u4FBF\u88C5\u9ED8\u8BA4\u4E0D\u4F5C\u4E3A\u72EC\u7ACB\u72B6\u6001\u3002\\n\" +\n \"- \u660E\u786E\u4EEA\u5F0F\u8EAB\u4EFD\u53EF\u4FDD\u5B88\u8865\u9020\u578B\u72B6\u6001\uFF1A\u5A5A\u793C\u91CC\u4F4D\u4E8E\u7EA2\u6BEF\u5C3D\u5934\u3001\u63A5\u8FC7\u65B0\u5A18\u624B\u3001\u821E\u53F0\u62E5\u543B\u7684\u65B0\u90CE\uFF0C\\n\" +\n \" \u5E94\u767B\u8BB0\u201C\u65B0\u90CE\u9020\u578B/\u5A5A\u793C\u6B63\u88C5\u201D\u72B6\u6001\uFF1B\u6574\u5957\u670D\u88C5\u9020\u578B\u5C5E\u4E8E\u4EBA\u7269\u72B6\u6001\uFF0C\u4E0D\u4F5C\u4E3A\u9053\u5177\u3002\\n\" +\n \"- \u8D44\u4EA7\u540D\u662F\u89C4\u8303\u5B9E\u4F53\u540D\uFF0C\u4E0D\u5939\u62EC\u53F7 / \u72B6\u6001 / \u60C5\u7EEA / \u8EAB\u4EFD\u6CE8\u89E3\uFF1B\u60C5\u7EEA / \u59FF\u6001 / \u4E34\u65F6\u810F\u6C61\u4F24\u53E3 /\\n\" +\n \" \u5904\u5883\u4F18\u5148\u653E\u8FDB action \u6587\u672C\u6216 dlg \u7684 emotion \u6807\u7B7E\uFF0Cparse/direct \u4E0D\u4F1A\u6309\u5173\u952E\u8BCD\u81EA\u52A8\u5220\u9664\\n\" +\n \" \u5DF2\u663E\u5F0F\u767B\u8BB0\u7684\u4EBA\u7269\u72B6\u6001\u3002\\n\" +\n \"- \u573A\u666F\u540D\u4E0D\u8981\u5199\u6210\u300C\u591C\u665A\u7684\u6559\u5BA4 / \u9EC4\u660F\u7684\u8857\u9053\u300D\u8FD9\u79CD\u72B6\u6001\u5316\u8D44\u4EA7\uFF1B\u767B\u8BB0\u4E3A\u300C\u6559\u5BA4 / \u8857\u9053\u300D\uFF0C\u628A\\n\" +\n \" \u591C\u665A / \u9EC4\u660F\u5199\u6210\u8BE5\u573A\u666F\u7684\u72B6\u6001\u3002parse/direct \u4F1A\u5BF9\u786E\u5B9A\u7684\u65F6\u95F4\u72B6\u6001\u505A\u4FDD\u5B88\u89C4\u8303\u5316\u3002\\n\" +\n \"- \u4EBA\u7269\u6301\u6709\u6216\u4F69\u6234\u7684\u7269\u4EF6\u5E94\u663E\u5F0F\u767B\u8BB0 / \u5F15\u7528\u4E3A\u9053\u5177\uFF0C\u4E0D\u8981\u5199\u6210\u4EBA\u7269\u72B6\u6001\uFF1Bparse/direct \u4E0D\u4F1A\\n\" +\n \" \u4ECE\u4EBA\u7269\u540D / \u4EBA\u7269\u5F15\u7528 / \u4EBA\u7269\u72B6\u6001\u6807\u7B7E\u81EA\u52A8\u62C6\u51FA\u9053\u5177\u3002\\n\" +\n \"- \u9053\u5177\u662F\u9700\u8981\u4F5C\u4E3A\u72EC\u7ACB\u89C6\u89C9\u8D44\u4EA7\u8FFD\u8E2A\u7684\u5177\u4F53\u7269\u4EF6\uFF0C\u4E0D\u662F\u52A8\u4F5C\u91CC\u51FA\u73B0\u7684\u6240\u6709\u7269\u54C1\u540D\u3002\u53EA\u6709\u63A8\u52A8\\n\" +\n \" \u5267\u60C5\u3001\u627F\u8F7D\u89C4\u5219 / \u8BC1\u636E / \u79D8\u5BC6 / \u4EFB\u52A1\u3001\u9700\u8981\u770B\u6E05\u7279\u5B9A\u6587\u5B57 / \u56FE\u6848 / \u7167\u7247 / \u754C\u9762\u3001\u8DE8\u573A\\n\" +\n \" \u53CD\u590D\u51FA\u73B0\u9700\u4FDD\u6301\u5916\u89C2\u3001\u6216\u4F5C\u4E3A `prop:<\u9053\u5177\u540D>` \u53D1\u58F0\u65F6\uFF0C\u624D\u5199\u8FDB \u9053\u5177.md / \u6B63\u6587 `- \u9053\u5177:`\u3002\\n\" +\n \" \u4E0D\u6EE1\u8DB3\u8FD9\u4E9B\u6761\u4EF6\u6216\u62FF\u4E0D\u51C6\u65F6\uFF0C\u4E0D\u8981\u63D0\u5347\u4E3A\u9053\u5177\u3002\\n\" +\n \" \u4EC5\u4EC5\u88AB\u62FF\u8D77\u3001\u4F7F\u7528\u3001\u4F69\u6234\u3001\u770B\u89C1\u3001\u6254\u51FA\u3001\u643A\u5E26\u3001\u635F\u574F\u3001\u77ED\u6682\u53C2\u4E0E\u52A8\u4F5C\uFF0C\u4E0D\u6784\u6210\u9053\u5177\u767B\u8BB0\u7406\u7531\u3002\\n\" +\n \" \u4E0D\u8981\u4E3A\u666E\u901A\u7269\u54C1\u7C7B\u522B\u521B\u5EFA\u201C\u67D0\u4EBA\u7684\u67D0\u7269\u201D\u8FD9\u7C7B\u4E13\u5C5E\u53D8\u4F53\uFF0C\u9664\u975E\u8FD9\u4E2A\u5B9E\u4F53\u672C\u8EAB\u9700\u8981\u8DE8\u573A\u8FDE\u7EED\uFF0C\\n\" +\n \" \u6216\u5E26\u6709\u5FC5\u987B\u770B\u6E05\u7684\u5DEE\u5F02\u5316\u5185\u5BB9\u3002\\n\" +\n \" \u666E\u901A\u52A8\u4F5C\u5DE5\u5177\u3001\u4E34\u65F6\u624B\u6301\u7269\u3001\u80CC\u666F\u6446\u8BBE\u3001\u666E\u901A\u751F\u6D3B\u7528\u54C1\u3001\u666E\u901A\u5BB6\u5177\u3001\u666E\u901A\u670D\u88C5\u914D\u4EF6\u53EA\u7559\u5728\\n\" +\n \" action \u6587\u672C\u3002\u5E94\u62BD\uFF1A\u53EF\u8BFB\u89C4\u5219 / \u8BC1\u636E\u7269\u3001\u4EFB\u52A1\u6216\u79D8\u5BC6\u8F7D\u4F53\u3001\u51B2\u7A81\u5173\u952E\u6B66\u5668\u3001\u901A\u884C\u94A5\u5319\u6216\u51ED\u8BC1\u3001\\n\" +\n \" \u53CD\u590D\u51FA\u73B0\u7684\u62A4\u8EAB\u7B26 / \u88C5\u7F6E\u3001\u4F1A\u53D1\u58F0\u7684\u7269\u4EF6\uFF1B\u4E0D\u5E94\u62BD\uFF1A\u666E\u901A\u901A\u8BAF\u8BBE\u5907\u3001\u5DE5\u5177\u3001\u9910\u5177\u3001\u4E66\u672C\u3001\\n\" +\n \" \u8863\u7269\u3001\u5BB6\u5177\u3001\u88C5\u9970\u7269\u7B49\u4E00\u6B21\u6027\u52A8\u4F5C\u7EC6\u8282\u3002\\n\" +\n \"- \u540C\u7C7B\u8D44\u4EA7\u540D\u6309 canonical key \u53BB\u91CD\uFF1A\u6298\u53E0\u7A7A\u767D\u3001\u5FFD\u7565\u7ED3\u6784\u6027\u6807\u70B9\u548C ASCII \u5927\u5C0F\u5199\uFF1B\u5982\\n\" +\n \" `\u674E\u56DB A` / `\u674E\u56DB a` \u4F1A\u5408\u5E76\u4E3A\u9996\u4E2A\u663E\u793A\u540D\uFF0C\u5176\u4ED6\u540D\u5B57\u8FDB\u5165 aliases\u3002\\n\" +\n \"- \u7FA4\u4F53\u8BCD\uFF08\u4F17\u4EBA / \u7FA4\u4F17 / \u56F4\u89C2\u8005 / \u8DEF\u4EBA\u4EEC\uFF09\u4E0D\u8FDB \u4EBA\u7269.md\uFF0C\u767B\u5230 \u53D1\u58F0\u6E90.md \u7528 group \u6216\u5199\u52A8\u4F5C\u65C1\u767D\u3002\\n\" +\n \"- \u52A8\u4F5C / \u5BF9\u767D\u6B63\u6587\u9010\u5B57\u4FDD\u7559\uFF0C\u4E0D\u8981\u8F6C\u8FF0 / \u7FFB\u8BD1 / \u6982\u62EC / \u52A0\u6CE8\u91CA\uFF1B\u52A8\u4F5C\u79CD\u7C7B\u53EA\u6709 act/dlg/think\u3002\\n\" +\n \"- \u6BCF\u4E2A\u51FA\u73B0\u5728\u6B63\u6587\u91CC\u7684\u89D2\u8272\uFF0C\u90FD\u8981\u5728 \u4EBA\u7269.md \u7ED9\u51FA\u975E\u7A7A\u63CF\u8FF0\uFF08\u5426\u5219\u6821\u9A8C\u62A5\u9519\uFF09\u3002\\n\";\n\nexport interface CommandOutput<T extends Record<string, unknown> = Record<string, unknown>> {\n /** Exact default-mode text. Commands own its wording and layout. */\n text: string;\n /** Structured command data. JSON mode spreads these fields at the top level. */\n data: T;\n}\n\nexport interface ValidationIssue {\n code?: string;\n severity?: string;\n summary?: string;\n repair_hint?: string;\n episode?: string;\n scene?: string;\n action_index?: number;\n [key: string]: unknown;\n}\n\nexport interface RunState {\n status?: string;\n command?: string;\n init_stage?: string;\n provider?: string;\n model?: string;\n updated_at?: string;\n [key: string]: unknown;\n}\n\nexport interface Script {\n version?: number;\n title?: string;\n worldview?: string;\n style?: string;\n synopsis?: string;\n theme?: string;\n logline?: string;\n main_characters?: Array<Record<string, unknown>>;\n actors?: Array<Record<string, unknown>>;\n locations?: Array<Record<string, unknown>>;\n props?: Array<Record<string, unknown>>;\n speakers?: Array<Record<string, unknown>>;\n episodes?: Array<Record<string, unknown>>;\n [key: string]: unknown;\n}\n\nexport interface CliErrorOptions {\n exitCode: number;\n errorCode: string;\n hint?: string;\n data?: Record<string, unknown>;\n}\n\nexport class CliError extends Error {\n readonly exitCode: number;\n readonly errorCode: string;\n readonly hint?: string;\n readonly data: Record<string, unknown>;\n\n constructor(message: string, opts: CliErrorOptions) {\n super(message);\n this.name = \"CliError\";\n this.exitCode = opts.exitCode;\n this.errorCode = opts.errorCode;\n this.hint = opts.hint;\n this.data = opts.data ?? {};\n }\n}\n\nexport function workspaceLayout(workspace: string): WorkspaceLayout {\n return new WorkspaceLayout(workspace);\n}\n\nexport function directDir(workspace: string): string {\n return workspaceLayout(workspace).directDir;\n}\n\nexport function scriptJsonPath(opts: Record<string, unknown>): string {\n const v = opts[\"script_path\"] ?? opts[\"scriptPath\"];\n return path.resolve(typeof v === \"string\" && v.length > 0 ? v : SCRIPT_REL);\n}\n\nexport function fmtId(prefix: string, n: number): string {\n return `${prefix}_${String(n).padStart(3, \"0\")}`;\n}\n\nexport function readJson<T = unknown>(p: string): T {\n return DEFAULT_STORE.readJson<T>(p);\n}\n\nexport function writeJson(p: string, data: unknown): void {\n DEFAULT_STORE.writeJson(p, data);\n}\n\nexport function readText(p: string): string {\n return DEFAULT_STORE.readText(p);\n}\n\nexport function exists(p: string): boolean {\n return DEFAULT_STORE.exists(p);\n}\n\nexport function writeText(p: string, text: string): void {\n DEFAULT_STORE.writeText(p, text);\n}\n\nexport function deletePath(p: string): void {\n DEFAULT_STORE.delete(p);\n}\n\nexport function deleteTree(p: string): void {\n DEFAULT_STORE.deleteTree(p);\n}\n\nexport function copyFile(src: string, dst: string): void {\n DEFAULT_STORE.copyToPath(src, dst);\n}\n\nexport function sha256Text(text: string): string {\n return crypto.createHash(\"sha256\").update(text, \"utf-8\").digest(\"hex\");\n}\n\nexport function sha256File(p: string): string {\n const digest = crypto.createHash(\"sha256\");\n const fd = fs.openSync(p, \"r\");\n try {\n const buf = Buffer.alloc(1024 * 1024);\n while (true) {\n const n = fs.readSync(fd, buf, 0, buf.length, null);\n if (n <= 0) break;\n digest.update(buf.subarray(0, n));\n }\n } finally {\n fs.closeSync(fd);\n }\n return digest.digest(\"hex\");\n}\n\nexport type ArtifactStoreRef = ArtifactStore;\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nexport interface ArtifactStore {\n exists(p: string): boolean;\n readText(p: string): string;\n writeText(p: string, text: string): void;\n readJson<T = unknown>(p: string): T;\n writeJson(p: string, data: unknown): void;\n list(p: string, pattern?: string): string[];\n delete(p: string): void;\n deleteTree(p: string): void;\n copyToPath(src: string, dst: string): void;\n}\n\nexport class WorkspaceLayout {\n readonly workspace: string;\n\n constructor(workspace: string) {\n this.workspace = workspace;\n }\n\n get sourceText(): string {\n return path.join(this.workspace, \"source.txt\");\n }\n\n get directDir(): string {\n return path.join(this.workspace, \"draft\", \"scriptctl\", \"direct\");\n }\n\n get directScript(): string {\n return path.join(this.directDir, \"script.initial.json\");\n }\n\n get validation(): string {\n return path.join(this.directDir, \"validation.json\");\n }\n\n get runState(): string {\n return path.join(this.directDir, \"run_state.json\");\n }\n\n get episodeResultsDir(): string {\n return path.join(this.directDir, \"episode_results\");\n }\n\n get batchResultsDir(): string {\n return path.join(this.directDir, \"batch_results\");\n }\n\n outputScript(outputDir: string): string {\n return path.join(outputDir, \"script.json\");\n }\n}\n\nfunction globToRegExp(pattern: string): RegExp {\n let re = \"\";\n for (const ch of pattern) {\n if (ch === \"*\") re += \"[^/]*\";\n else if (ch === \"?\") re += \"[^/]\";\n else if (\".+^$()[]{}|\\\\\".includes(ch)) re += \"\\\\\" + ch;\n else re += ch;\n }\n return new RegExp(\"^\" + re + \"$\");\n}\n\nexport class LocalArtifactStore implements ArtifactStore {\n exists(p: string): boolean {\n return fs.existsSync(p);\n }\n\n readText(p: string): string {\n return fs.readFileSync(p, \"utf-8\");\n }\n\n writeText(p: string, text: string): void {\n fs.mkdirSync(path.dirname(p), { recursive: true });\n fs.writeFileSync(p, text, \"utf-8\");\n }\n\n readJson<T = unknown>(p: string): T {\n return JSON.parse(fs.readFileSync(p, \"utf-8\")) as T;\n }\n\n writeJson(p: string, data: unknown): void {\n this.writeText(p, JSON.stringify(data, null, 2) + \"\\n\");\n }\n\n list(p: string, pattern: string = \"*\"): string[] {\n if (!fs.existsSync(p)) return [];\n const re = globToRegExp(pattern);\n const entries = fs.readdirSync(p);\n const matched: string[] = [];\n for (const name of entries) {\n if (re.test(name)) matched.push(path.join(p, name));\n }\n matched.sort();\n return matched;\n }\n\n delete(p: string): void {\n if (fs.existsSync(p)) fs.unlinkSync(p);\n }\n\n deleteTree(p: string): void {\n if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true });\n }\n\n copyToPath(src: string, dst: string): void {\n fs.mkdirSync(path.dirname(dst), { recursive: true });\n fs.copyFileSync(src, dst);\n }\n}\n\nexport const DEFAULT_STORE: ArtifactStore = new LocalArtifactStore();\n", "export const FAILURE_CODES = {\n policy: [\"content_blocked\"],\n network: [\"dns_failed\", \"connection_refused\", \"connection_reset\", \"network_unreachable\", \"tls_failed\", \"network_failed\"],\n timeout: [\"connect_timeout\", \"request_timeout\", \"media_processing_timeout\"],\n rate_limit: [\"rate_limited\"],\n authentication: [\"authentication_failed\"],\n authorization: [\"permission_denied\"],\n provider: [\"resource_not_found\", \"provider_unavailable\", \"request_rejected\", \"attempts_exhausted\"],\n media: [\"media_upload_failed\", \"media_processing_failed\", \"media_too_large\", \"unsupported_media\"],\n response: [\"output_truncated\", \"empty_response\", \"malformed_response\"],\n pipeline: [\"serial_parse_failed\", \"source_mismatch\", \"pipeline_mismatch\"],\n validation: [\"script_validation_failed\"],\n cancelled: [\"cancelled\"],\n unknown: [\"unknown\", \"legacy_unclassified\"],\n} as const;\n\nexport type FailureCodeByType = {\n [Type in keyof typeof FAILURE_CODES]: (typeof FAILURE_CODES)[Type][number];\n};\n\nexport type FailureType = keyof typeof FAILURE_CODES;\n\nexport type FailureClassification = {\n [Type in FailureType]: {\n failure_type: Type;\n failure_code: FailureCodeByType[Type];\n };\n}[FailureType];\n\nexport type GeminiPolicySource = \"prompt\" | \"candidate\";\n\nexport type GeminiPolicyReason =\n | \"SAFETY\"\n | \"PROHIBITED_CONTENT\"\n | \"BLOCKLIST\"\n | \"SPII\"\n | \"RECITATION\"\n | \"IMAGE_SAFETY\"\n | \"IMAGE_PROHIBITED_CONTENT\"\n | \"IMAGE_RECITATION\"\n | \"ESCALATION\"\n | \"OTHER\"\n | \"UNSPECIFIED\"\n | \"UNKNOWN\";\n\nexport interface ProviderSafetyRating {\n category: string;\n probability: string;\n blocked: boolean;\n}\n\nexport interface FailureContext {\n provider?: string;\n model?: string;\n operation?: string;\n http_status?: number;\n system_code?: string;\n provider_source?: GeminiPolicySource;\n provider_reason?: GeminiPolicyReason;\n provider_reason_raw?: string;\n finish_message?: string;\n safety_ratings?: ProviderSafetyRating[];\n details?: string[];\n}\n\nexport type OperationalFailure = FailureClassification & FailureContext & {\n retryable: boolean;\n message: string;\n};\n\nfunction oneOf<const Values extends readonly string[]>(value: unknown, values: Values): value is Values[number] {\n return typeof value === \"string\" && values.some((candidate) => candidate === value);\n}\n\nexport function parseFailureClassification(type: unknown, code: unknown): FailureClassification | null {\n switch (type) {\n case \"policy\": return oneOf(code, FAILURE_CODES.policy) ? { failure_type: type, failure_code: code } : null;\n case \"network\": return oneOf(code, FAILURE_CODES.network) ? { failure_type: type, failure_code: code } : null;\n case \"timeout\": return oneOf(code, FAILURE_CODES.timeout) ? { failure_type: type, failure_code: code } : null;\n case \"rate_limit\": return oneOf(code, FAILURE_CODES.rate_limit) ? { failure_type: type, failure_code: code } : null;\n case \"authentication\": return oneOf(code, FAILURE_CODES.authentication) ? { failure_type: type, failure_code: code } : null;\n case \"authorization\": return oneOf(code, FAILURE_CODES.authorization) ? { failure_type: type, failure_code: code } : null;\n case \"provider\": return oneOf(code, FAILURE_CODES.provider) ? { failure_type: type, failure_code: code } : null;\n case \"media\": return oneOf(code, FAILURE_CODES.media) ? { failure_type: type, failure_code: code } : null;\n case \"response\": return oneOf(code, FAILURE_CODES.response) ? { failure_type: type, failure_code: code } : null;\n case \"pipeline\": return oneOf(code, FAILURE_CODES.pipeline) ? { failure_type: type, failure_code: code } : null;\n case \"validation\": return oneOf(code, FAILURE_CODES.validation) ? { failure_type: type, failure_code: code } : null;\n case \"cancelled\": return oneOf(code, FAILURE_CODES.cancelled) ? { failure_type: type, failure_code: code } : null;\n case \"unknown\": return oneOf(code, FAILURE_CODES.unknown) ? { failure_type: type, failure_code: code } : null;\n default: return null;\n }\n}\n\nexport function createOperationalFailure(\n classification: FailureClassification,\n fields: FailureContext & { retryable: boolean; message: string },\n): OperationalFailure {\n return { ...classification, ...fields };\n}\n\nexport function classificationOf(failure: OperationalFailure): FailureClassification {\n switch (failure.failure_type) {\n case \"policy\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"network\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"timeout\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"rate_limit\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"authentication\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"authorization\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"provider\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"media\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"response\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"pipeline\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"validation\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"cancelled\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n case \"unknown\": return { failure_type: failure.failure_type, failure_code: failure.failure_code };\n }\n}\n\nexport function contextOf(failure: OperationalFailure): FailureContext {\n return {\n ...(failure.provider !== undefined ? { provider: failure.provider } : {}),\n ...(failure.model !== undefined ? { model: failure.model } : {}),\n ...(failure.operation !== undefined ? { operation: failure.operation } : {}),\n ...(failure.http_status !== undefined ? { http_status: failure.http_status } : {}),\n ...(failure.system_code !== undefined ? { system_code: failure.system_code } : {}),\n ...(failure.provider_source !== undefined ? { provider_source: failure.provider_source } : {}),\n ...(failure.provider_reason !== undefined ? { provider_reason: failure.provider_reason } : {}),\n ...(failure.provider_reason_raw !== undefined ? { provider_reason_raw: failure.provider_reason_raw } : {}),\n ...(failure.finish_message !== undefined ? { finish_message: failure.finish_message } : {}),\n ...(failure.safety_ratings !== undefined ? { safety_ratings: failure.safety_ratings } : {}),\n ...(failure.details !== undefined ? { details: failure.details } : {}),\n };\n}\n\nexport function aggregateFailures(failures: OperationalFailure[], message: string): OperationalFailure {\n if (failures.length === 0) {\n return createOperationalFailure(\n { failure_type: \"unknown\", failure_code: \"unknown\" },\n { retryable: false, message },\n );\n }\n const first = failures[0];\n const sameClassification = failures.every(\n (failure) => failure.failure_type === first.failure_type && failure.failure_code === first.failure_code,\n );\n const classification: FailureClassification = sameClassification\n ? classificationOf(first)\n : { failure_type: \"provider\", failure_code: \"attempts_exhausted\" };\n return createOperationalFailure(classification, {\n retryable: failures.some((failure) => failure.retryable),\n message,\n });\n}\n\nexport function formatFailure(failure: OperationalFailure): string {\n const route = failure.provider || failure.model\n ? `${failure.provider ?? \"provider\"}/${failure.model ?? \"model\"} `\n : \"\";\n const reason = failure.provider_reason ? ` provider_reason=${failure.provider_reason}` : \"\";\n const system = failure.system_code ? ` system_code=${failure.system_code}` : \"\";\n const status = failure.http_status !== undefined ? ` http_status=${failure.http_status}` : \"\";\n const details = failure.details?.length ? ` | ${failure.details.join(\" | \")}` : \"\";\n return `${route}${failure.failure_type}/${failure.failure_code}${reason}${system}${status}: ${failure.message}${details}`;\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT, EXIT_OK, EXIT_USAGE, type CommandOutput } from \"../common.js\";\nimport { packageRoot, packageVersion } from \"../package-root.js\";\n\ninterface ChangelogOptions {\n _args?: string[];\n from?: unknown;\n to?: unknown;\n unreleased?: unknown;\n}\n\ninterface PackageJson {\n version?: string;\n}\n\nconst VERSION_RE = /^\\d+\\.\\d+\\.\\d+$/;\nconst UNRELEASED = \"unreleased\";\n\nfunction changesDir(): string {\n return path.join(packageRoot(), \"changes\");\n}\n\nfunction readPackageVersion(): string {\n return packageVersion();\n}\n\nfunction versionParts(version: string): [number, number, number] {\n if (!VERSION_RE.test(version)) {\n throw new CliError(\"Version must use x.y.z.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CHANGELOG_VERSION_INVALID\",\n hint: \"Pass a released version such as `scriptctl changelog 0.25.10`.\",\n data: { expected: [\"x.y.z\"], actual: [version || \"<empty>\"] },\n });\n }\n const [major, minor, patch] = version.split(\".\").map((part) => Number(part)) as [number, number, number];\n return [major, minor, patch];\n}\n\nfunction compareVersions(a: string, b: string): number {\n const av = versionParts(a);\n const bv = versionParts(b);\n for (let i = 0; i < 3; i++) {\n if (av[i] !== bv[i]) return av[i]! - bv[i]!;\n }\n return 0;\n}\n\nfunction listReleasedVersions(): string[] {\n const dir = changesDir();\n return fs.readdirSync(dir)\n .filter((name) => name.endsWith(\".md\"))\n .map((name) => name.slice(0, -\".md\".length))\n .filter((version) => VERSION_RE.test(version))\n .sort(compareVersions);\n}\n\nfunction readChangeFile(version: string): string {\n return fs.readFileSync(path.join(changesDir(), `${version}.md`), \"utf-8\").trimEnd();\n}\n\nfunction missingVersion(version: string, available: string[]): CliError {\n return new CliError(`No changelog entry exists for ${version}.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"CHANGELOG_VERSION_NOT_FOUND\",\n hint: available.length > 0\n ? `Available versions: ${available.join(\", \")}`\n : \"Add changes/<version>.md first.\",\n data: { expected: [\"existing changelog version\"], actual: [version] },\n });\n}\n\nfunction emptyRange(from: string, to: string): CliError {\n return new CliError(`No released changelog entries found after ${from} through ${to}.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"CHANGELOG_RANGE_EMPTY\",\n hint: \"Choose a wider range or run `scriptctl changelog <version>` for a known release.\",\n data: { expected: [\"a version range containing released changelog entries\"], actual: [`--from ${from}`, `--to ${to}`] },\n });\n}\n\nfunction bodyForVersions(versions: string[]): string {\n return versions.map(readChangeFile).join(\"\\n\\n\");\n}\n\nexport function commandChangelog(opts: ChangelogOptions): [CommandOutput, number] {\n const args = opts._args ?? [];\n const versionArg = args[0]?.trim() ?? \"\";\n const from = String(opts.from ?? \"\").trim();\n const to = String(opts.to ?? \"\").trim();\n const unreleased = Boolean(opts.unreleased);\n\n if (args.length > 1) {\n throw new CliError(\"changelog accepts at most one version argument.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CHANGELOG_TOO_MANY_ARGS\",\n hint: \"Pass a single version, or use --from/--to for a range.\",\n data: { expected: [\"scriptctl changelog [version] [--from X] [--to Y] [--unreleased]\"], actual: [args.join(\" \")] },\n });\n }\n if (unreleased && (versionArg || from || to)) {\n throw new CliError(\"--unreleased cannot combine with version, --from, or --to.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CHANGELOG_SELECTOR_CONFLICT\",\n hint: \"Run `scriptctl changelog --unreleased` by itself.\",\n data: { expected: [\"either --unreleased, a version, or a --from/--to range\"], actual: [\"--unreleased with another selector\"] },\n });\n }\n if (versionArg && (from || to)) {\n throw new CliError(\"A version argument cannot combine with --from or --to.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CHANGELOG_SELECTOR_CONFLICT\",\n hint: \"Run `scriptctl changelog 0.25.10` or `scriptctl changelog --from 0.25.8 --to 0.25.10`.\",\n data: { expected: [\"either a version argument, or --from/--to\"], actual: [versionArg, from ? `--from ${from}` : \"\", to ? `--to ${to}` : \"\"].filter(Boolean) },\n });\n }\n\n if (unreleased) {\n const body = readChangeFile(UNRELEASED);\n return [{ text: body, data: { content: body, versions: [], unreleased: true } }, EXIT_OK];\n }\n\n const available = listReleasedVersions();\n const current = readPackageVersion();\n\n if (versionArg) {\n versionParts(versionArg);\n if (!available.includes(versionArg)) throw missingVersion(versionArg, available);\n const body = readChangeFile(versionArg);\n return [{ text: body, data: { content: body, versions: [versionArg], unreleased: false } }, EXIT_OK];\n }\n\n if (from || to) {\n if (!from) {\n throw new CliError(\"--from is required for range queries.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CHANGELOG_FROM_MISSING\",\n hint: \"Run `scriptctl changelog --from 0.25.8 --to 0.25.10`.\",\n data: { expected: [\"--from <x.y.z>\"], actual: [to ? `--to ${to}` : \"<missing>\"] },\n });\n }\n versionParts(from);\n const upper = to || current;\n versionParts(upper);\n if (!available.includes(upper)) throw missingVersion(upper, available);\n const versions = available.filter((version) => compareVersions(version, from) > 0 && compareVersions(version, upper) <= 0);\n if (versions.length === 0) throw emptyRange(from, upper);\n const content = bodyForVersions(versions);\n return [{ text: content, data: { content, versions, from, to: upper, unreleased: false } }, EXIT_OK];\n }\n\n if (!available.includes(current)) throw missingVersion(current, available);\n const body = readChangeFile(current);\n return [{ text: body, data: { content: body, versions: [current], unreleased: false } }, EXIT_OK];\n}\n", "// The package root is found by walking up from this module rather than by a\n// fixed number of `..` steps. The shipped CLI is one bundled file in `dist/`,\n// while `tsc`'s per-file output nests modules under `dist/<area>/`, so a fixed\n// count is only ever right for one of the two layouts.\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst NAME = \"@lingjingai/scriptctl\";\nlet cached = \"\";\n\nexport function packageRoot(): string {\n if (cached) return cached;\n let cursor = path.dirname(fileURLToPath(import.meta.url));\n for (;;) {\n try {\n const raw = fs.readFileSync(path.join(cursor, \"package.json\"), \"utf-8\");\n if ((JSON.parse(raw) as { name?: string }).name === NAME) {\n cached = cursor;\n return cursor;\n }\n } catch {\n // No readable package.json here; keep walking.\n }\n const parent = path.dirname(cursor);\n if (parent === cursor) throw new Error(`${NAME} package root not found`);\n cursor = parent;\n }\n}\n\nexport function packageVersion(): string {\n const raw = fs.readFileSync(path.join(packageRoot(), \"package.json\"), \"utf-8\");\n const version = (JSON.parse(raw) as { version?: unknown }).version;\n if (typeof version !== \"string\") throw new Error(`${NAME} package.json has no string version`);\n return version;\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { createRequire } from \"node:module\";\n\nimport { EXIT_OK, type CommandOutput } from \"../common.js\";\nimport { candidateEnvPaths } from \"../infra/env.js\";\nimport { resolveOutputMode } from \"../infra/script-output-store.js\";\nimport { loadLlmConfig } from \"../llm/config.js\";\nimport { ModelRouter } from \"../llm/router.js\";\n\nconst require = createRequire(import.meta.url);\n\nfunction moduleAvailable(name: string): boolean {\n try {\n require.resolve(name);\n return true;\n } catch {\n return false;\n }\n}\n\n// Read-only probe \u2014 never creates or modifies anything. doctor must stay\n// side-effect-free so `--json` consumers can re-run it idempotently.\nfunction probeLocalOutputDir(dir: string): {\n writable: boolean;\n hasScript: boolean;\n} {\n let writable = false;\n try {\n const stat = fs.statSync(dir);\n if (stat.isDirectory()) {\n fs.accessSync(dir, fs.constants.W_OK);\n writable = true;\n }\n } catch {\n writable = false;\n }\n let hasScript = false;\n try {\n hasScript = fs.statSync(path.join(dir, \"script.json\")).isFile();\n } catch {\n hasScript = false;\n }\n return { writable, hasScript };\n}\n\n// Default output path mirrors LocalScriptOutputStore.fromEnv()'s fallback:\n// sibling of the default workspace dir, which lives at <cwd>/workspace, so\n// the default output is <cwd>/output. The project-template lays both out\n// at the same level under each stage dir.\nfunction defaultLocalOutputDir(): string {\n return path.join(path.dirname(path.resolve(\"workspace\")), \"output\");\n}\n\nexport function commandDoctor(opts: Record<string, unknown> = {}): [CommandOutput, number] {\n const envPaths = candidateEnvPaths();\n const existingEnvPaths: string[] = [];\n const seen = new Set<string>();\n for (const p of envPaths) {\n try {\n if (!fs.existsSync(p) || !fs.statSync(p).isFile()) continue;\n const resolved = fs.realpathSync(p);\n if (seen.has(resolved)) continue;\n seen.add(resolved);\n existingEnvPaths.push(p);\n } catch {\n // ignore individual entries that cannot be inspected\n }\n }\n\n const explicitLlmConfig = typeof opts[\"llm_config\"] === \"string\" ? opts[\"llm_config\"].trim() : \"\";\n const llmConfig = loadLlmConfig(explicitLlmConfig || undefined);\n const llmRouter = new ModelRouter(llmConfig);\n const llmRoutes = llmRouter.routes();\n const credentialChecks = Object.entries(llmConfig.providers).map(([alias, provider]) => ({\n alias,\n configured: Boolean((process.env[provider.apiKeyEnv] ?? \"\").trim()),\n env: provider.apiKeyEnv,\n }));\n // openai-compatible providers need an explicit endpoint (the built-in `gw`\n // reads PROJECT_LITELLM_GATEWAY_BASE_URL). CommandOutput the resolved host so a\n // missing / mis-pointed gateway is visible \u2014 a null baseUrl here is why\n // ingest normalization fails at connection time. anthropic/gemini use their\n // SDK default endpoint, so a null baseUrl there is expected and not reported.\n const endpointChecks = Object.entries(llmConfig.providers)\n .filter(([, provider]) => provider.protocol === \"openai-compatible\")\n .map(([alias, provider]) => {\n let host = \"not set\";\n if (provider.baseUrl) {\n try { host = new URL(provider.baseUrl).host; } catch { host = provider.baseUrl; }\n }\n return { alias, host };\n });\n\n // doctor reports the AMBIENT binding (env + project-group inference), so it\n // resolves with no per-call flags. mode is null when the env is unbound or\n // holds a typo'd SCRIPTCTL_OUTPUT_MODE \u2014 both surface as \"not configured\".\n const { mode } = resolveOutputMode();\n const localDirRaw = (process.env.SCRIPTCTL_OUTPUT_DIR ?? \"\").trim() || defaultLocalOutputDir();\n const localProbe = mode === \"local\" ? probeLocalOutputDir(localDirRaw) : null;\n\n const gatewayUrlConfigured = Boolean(process.env.AWB_BASE_URL);\n const gatewayAccessConfigured = Boolean(process.env.LINGJING_AWB_ACCESS_KEY);\n const projectGroupConfigured = Boolean(process.env.SANDBOX_PROJECT_GROUP_NO);\n\n const dependencies: Record<string, boolean> = {\n \"@anthropic-ai/sdk\": moduleAvailable(\"@anthropic-ai/sdk\"),\n \"@google/genai\": moduleAvailable(\"@google/genai\"),\n jszip: moduleAvailable(\"jszip\"),\n \"fast-xml-parser\": moduleAvailable(\"fast-xml-parser\"),\n };\n const missingDeps = Object.entries(dependencies)\n .filter(([, ok]) => !ok)\n .map(([name]) => name);\n\n const nodeVersion = process.versions.node;\n const envFileLine = `env_file: ${existingEnvPaths[0] ?? \"missing\"}`;\n const fmtCheck = (ok: boolean): string => (ok ? \"configured\" : \"not configured\");\n // Workspace storage is always the local filesystem. Stable since pre-0.7.0;\n // scripts that grep `storage:` keep working.\n const storageLine = \"storage: local-filesystem\";\n\n const result = [\n `node: ${nodeVersion}`,\n storageLine,\n envFileLine,\n `llm config: ${llmConfig.source}`,\n `llm routes: ${llmRoutes.length}`,\n ...credentialChecks.map((check) => `llm provider ${check.alias}: ${fmtCheck(check.configured)}`),\n ...endpointChecks.map((check) => `llm provider ${check.alias} endpoint: ${check.host}`),\n ];\n // Doctor result lines vary by where the published script lands, but the\n // word \"mode\" / \"local\" / \"remote\" is deliberately absent: upper layers\n // must not know there are two backends.\n if (mode === null) {\n // Unbound: no per-call flag and no env binding. Stay neutral \u2014 naming the\n // backend kinds (or the env var) here would leak the mode concept.\n result.push(`output target: not configured`);\n } else if (mode === \"local\" && localProbe) {\n result.push(`output writable: ${fmtCheck(localProbe.writable)}`);\n result.push(`output snapshot: ${localProbe.hasScript ? \"present\" : \"absent\"}`);\n } else {\n result.push(`gateway endpoint: ${fmtCheck(gatewayUrlConfigured)}`);\n result.push(`gateway access credential: ${fmtCheck(gatewayAccessConfigured)}`);\n result.push(`gateway project identifier: ${fmtCheck(projectGroupConfigured)}`);\n }\n for (const [name, ok] of Object.entries(dependencies)) {\n result.push(`dependency ${name}: ${ok ? \"ok\" : \"missing\"}`);\n }\n\n const nextSteps: string[] = [];\n if (missingDeps.length > 0) {\n nextSteps.push(\"Install missing CLI dependencies (see above).\");\n }\n if (credentialChecks.some((check) => !check.configured)) {\n nextSteps.push(\"Configure every credential referenced by the selected LLM configuration.\");\n }\n if (endpointChecks.some((check) => check.host === \"not set\")) {\n nextSteps.push(\"An openai-compatible provider has no endpoint \u2014 set PROJECT_LITELLM_GATEWAY_BASE_URL (built-in gateway) or the provider's baseUrl.\");\n }\n // A typo'd SCRIPTCTL_OUTPUT_MODE resolves to mode=null (unbound), same as\n // unset \u2014 reported as \"not configured\" below. We deliberately don't name the\n // env var here: that would leak the mode concept to the upper layer.\n if (mode === null) {\n nextSteps.push(\"Configure an output target before running `publish` / script CRUD.\");\n } else if (mode === \"local\") {\n if (localProbe && !localProbe.writable) {\n nextSteps.push(\"Output target is not writable; check directory permissions.\");\n }\n } else if (!gatewayUrlConfigured || !gatewayAccessConfigured || !projectGroupConfigured) {\n nextSteps.push(\"Configure gateway credentials before running `publish` / script CRUD against the remote project.\");\n }\n if (nextSteps.length === 0) {\n nextSteps.push(\"Environment looks ready.\");\n }\n\n const [major, minor] = nodeVersion.split(\".\").map((n) => parseInt(n, 10));\n const nodeOk = (major ?? 0) > 20 || ((major ?? 0) === 20 && (minor ?? 0) >= 0);\n\n // checks.output exposes only the relevant sub-keys; presence of `endpoint`\n // (remote-style) vs `dir` (local-style) is the implicit discriminator.\n // No `mode` field \u2014 upper layers must not branch on a mode concept.\n const outputChecks: Record<string, unknown> =\n mode === null\n ? { configured: false }\n : mode === \"local\"\n ? {\n dir: {\n ok: Boolean(localProbe?.writable),\n writable: Boolean(localProbe?.writable),\n hasScript: Boolean(localProbe?.hasScript),\n },\n }\n : {\n endpoint: { ok: gatewayUrlConfigured },\n access: { ok: gatewayAccessConfigured },\n project: { ok: projectGroupConfigured },\n };\n\n const checks: Record<string, unknown> = {\n node: { version: nodeVersion, ok: nodeOk },\n storage: { backend: \"local-filesystem\", ok: true },\n env: {\n ok: existingEnvPaths.length > 0,\n paths: existingEnvPaths,\n },\n llm: {\n config_source: llmConfig.source,\n ...(llmConfig.sourcePath ? { config_path: llmConfig.sourcePath } : {}),\n providers: credentialChecks.map((check) => ({\n alias: check.alias,\n ok: check.configured,\n credential_env: check.env,\n ...(endpointChecks.find((e) => e.alias === check.alias)\n ? { endpoint: endpointChecks.find((e) => e.alias === check.alias)!.host }\n : {}),\n })),\n profiles: Object.keys(llmConfig.models),\n routes: llmRoutes.map((route) => ({\n task: route.task,\n profile: route.profile,\n provider: route.provider,\n protocol: route.protocol,\n model: route.model,\n })),\n },\n output: outputChecks,\n dependencies,\n };\n\n const report: CommandOutput = {\n text: [...result, ...nextSteps].join(\"\\n\"),\n data: { checks },\n };\n return [report, EXIT_OK];\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction expandUser(p: string): string {\n if (p.startsWith(\"~\")) return path.join(os.homedir(), p.slice(1));\n return p;\n}\n\nfunction parseEnvFile(p: string): void {\n const content = fs.readFileSync(p, \"utf-8\");\n for (const rawLine of content.split(/\\r?\\n/)) {\n let line = rawLine.trim();\n if (!line || line.startsWith(\"#\")) continue;\n if (line.startsWith(\"export \")) line = line.slice(7).trim();\n const eq = line.indexOf(\"=\");\n if (eq < 0) continue;\n const key = line.slice(0, eq).trim();\n let value = line.slice(eq + 1).trim();\n if (\n value.length >= 2 &&\n value[0] === value[value.length - 1] &&\n (value[0] === \"'\" || value[0] === '\"')\n ) {\n value = value.slice(1, -1);\n }\n if (key && value && !process.env[key]) {\n process.env[key] = value;\n }\n }\n}\n\nexport function candidateEnvPaths(): string[] {\n const paths: string[] = [];\n const explicit = (process.env.SCRIPTCTL_ENV_FILE ?? \"\").trim();\n if (explicit) paths.push(expandUser(explicit));\n const skillDir = (process.env.SCRIPTCTL_SKILL_DIR ?? \"\").trim();\n if (skillDir) paths.push(path.join(expandUser(skillDir), \".env\"));\n let here: string;\n try {\n here = fileURLToPath(import.meta.url);\n } catch {\n here = process.cwd();\n }\n let cursor = path.resolve(here);\n const seen = new Set<string>();\n while (true) {\n const parent = path.dirname(cursor);\n if (parent === cursor || seen.has(parent)) break;\n seen.add(parent);\n paths.push(path.join(parent, \".env\"));\n cursor = parent;\n }\n return paths;\n}\n\nexport function loadLocalEnv(): void {\n const skip = process.env.SCRIPTCTL_NO_DOTENV;\n if (skip === \"1\" || skip === \"true\" || skip === \"True\") return;\n const visited = new Set<string>();\n for (const envPath of candidateEnvPaths()) {\n let resolved: string;\n try {\n resolved = fs.existsSync(envPath) ? fs.realpathSync(envPath) : envPath;\n } catch {\n resolved = envPath;\n }\n if (visited.has(resolved)) continue;\n if (!fs.existsSync(envPath) || !fs.statSync(envPath).isFile()) continue;\n visited.add(resolved);\n parseEnvFile(envPath);\n }\n}\n", "import { CliError, EXIT_INPUT, EXIT_USAGE } from \"../common.js\";\n\nexport type ConfigMissingSlot = \"gateway\" | \"access\" | \"project\" | \"output\";\n\nexport interface ScriptOutputApiErrorOptions {\n status?: number | null;\n code?: number | string | null;\n payload?: unknown;\n /**\n * Which env var was missing when fromEnv() failed \u2014 used by apiErrorToCli to\n * route the failure into a sanitized public error. Kept as a stable token\n * (not the raw env name) so apiErrorToCli doesn't need to parse messages.\n * \"output\" is the local-mode slot (SCRIPTCTL_OUTPUT_DIR missing or unwritable).\n */\n configMissing?: ConfigMissingSlot;\n}\n\nexport class ScriptOutputApiError extends Error {\n readonly status: number | null;\n readonly code: number | string | null;\n readonly payload: unknown;\n readonly configMissing: ConfigMissingSlot | null;\n\n constructor(message: string, opts: ScriptOutputApiErrorOptions = {}) {\n super(message);\n this.name = \"ScriptOutputApiError\";\n this.status = opts.status ?? null;\n this.code = opts.code ?? null;\n this.payload = opts.payload;\n this.configMissing = opts.configMissing ?? null;\n }\n}\n\nexport interface ReplaceScriptOptions {\n requestId: string;\n baseRevision: number;\n script: Record<string, unknown>;\n source?: string;\n}\n\nexport interface ScriptSnapshot {\n projectGroupNo: string;\n script: Record<string, unknown>;\n revision: number;\n validationStatus?: string | null;\n validationSummary?: Record<string, unknown> | null;\n updatedAt?: string | null;\n}\n\nexport interface PublishPatchOptions {\n baseRevision: number;\n old: Record<string, unknown>;\n edited: Record<string, unknown>;\n validation: {\n status: \"valid\";\n summary: Record<string, unknown>;\n };\n}\n\n/**\n * Incremental edit: publish the RFC6902 diff between the loaded script and the\n * locally-edited script, instead of re-uploading the whole document. `old` is\n * the script as loaded (the edit baseline), `edited` is the post-mutation\n * script. Implementations compute `compare(old, edited)` and send the patch.\n *\n * V1 backends have no incremental endpoint, so their implementation degrades to\n * a whole-document `replaceScript(edited)` \u2014 callers get the same observable\n * result (a new revision) regardless of which store is wired, so editing\n * usecases can always call `patchScript` without branching on the backend.\n */\nexport interface PatchScriptOptions {\n requestId: string;\n baseRevision: number;\n old: Record<string, unknown>;\n edited: Record<string, unknown>;\n source?: string;\n}\n\nexport interface SaveValidationOptions {\n revision: number;\n validationStatus: string;\n validationSummary: Record<string, unknown>;\n issues: Array<Record<string, unknown>>;\n}\n\n/**\n * Abstract \"published script storage\" used by usecases. Two implementations:\n * - RemoteScriptOutputStore: HTTP gateway (production)\n * - LocalScriptOutputStore: filesystem (local debugging)\n *\n * Implementations are selected by the `scriptOutputClient()` factory based on\n * `SCRIPTCTL_OUTPUT_MODE`. Usecase code only touches this interface, so the\n * mode switch is invisible above this layer.\n */\nexport interface ScriptOutputStore {\n /**\n * Stable identifier for the underlying store. For the remote backend this is\n * the gateway-side project group id; for the local backend it is the store\n * directory path. Used in artifact labels and \"not found\" error context.\n */\n readonly projectGroupNo: string;\n getScript(): Promise<Record<string, unknown> | null>;\n getRevision(): Promise<Record<string, unknown> | null>;\n replaceScript(opts: ReplaceScriptOptions): Promise<Record<string, unknown>>;\n /**\n * Apply an incremental edit. V2 stores send an RFC6902 PATCH; V1 stores fall\n * back to a whole-document replace. Both return the same revision envelope as\n * `replaceScript`, so editing usecases never branch on the backend version.\n */\n patchScript(opts: PatchScriptOptions): Promise<Record<string, unknown>>;\n saveValidationResult(opts: SaveValidationOptions): Promise<Record<string, unknown> | null>;\n /**\n * Best-effort write of the project group's `episode_count` (the column the\n * home page \"\u6211\u7684\u9879\u76EE\" card reads). Optional: only the remote gateway store\n * implements it \u2014 the local store omits it. Callers MUST treat a rejection as\n * non-fatal; project-group metadata must never fail the primary script write.\n */\n updateEpisodeCount?(episodeCount: number): Promise<void>;\n}\n\n// Push the project group's episode count after a script write. Best-effort by\n// design: the home-page episode_count is non-essential metadata, so a failure\n// (auth, network, backend lacking the endpoint) is swallowed and never rolls\n// back or surfaces above the primary script save. No-op on stores without the\n// optional method (the local store).\nexport async function syncEpisodeCount(client: ScriptOutputStore, episodeCount: number): Promise<void> {\n if (!client.updateEpisodeCount) return;\n try {\n await client.updateEpisodeCount(episodeCount);\n } catch {\n // ponytail: best-effort metadata \u2014 keep it off agent-facing output.\n }\n}\n\nexport type OutputMode = \"local\" | \"remote\";\n\n/**\n * Single source of truth for output-target resolution. The CLI core is\n * UNBOUND: a bare invocation with no per-call flag and no `SCRIPTCTL_OUTPUT_MODE`\n * env resolves to `mode: null` (the caller then errors) rather than silently\n * defaulting to the remote gateway. \"Where does this write land\" must always be\n * an explicit decision \u2014 never inferred from ambient gateway credentials.\n *\n * Precedence: per-call flag (`--remote` / `--local`) > `SCRIPTCTL_OUTPUT_MODE`\n * env (an explicit binding) > a project group in scope (`SANDBOX_PROJECT_GROUP_NO`\n * env, which the sandbox injects, or a `--project-group-no` flag \u2192 infer remote)\n * > none.\n *\n * The project-group inference is what keeps the sandbox zero-config: the backend\n * already injects `SANDBOX_PROJECT_GROUP_NO`, so a bare command there resolves to\n * remote without any extra binding. A dev box without that var stays unbound. A\n * *typo* in `SCRIPTCTL_OUTPUT_MODE` is \"explicit but broken\" \u2192 it errors rather\n * than falling through to inference, so a misconfiguration isn't silently masked.\n *\n * Returns:\n * - mode: \"local\" | \"remote\" | null (null = unresolved \u2192 caller errors)\n * - conflict: both `--remote` and `--local` were passed (mutually exclusive)\n *\n * Pure (never throws). `resolveOutputModeOrThrow` wraps it with the CliError\n * contract so the conflict / no-target handling lives in exactly one place.\n */\nexport function resolveOutputMode(flags?: {\n remote?: unknown;\n local?: unknown;\n projectGroupNo?: unknown;\n}): {\n mode: OutputMode | null;\n conflict: boolean;\n} {\n const remoteFlag = Boolean(flags?.remote);\n const localFlag = Boolean(flags?.local);\n if (remoteFlag && localFlag) return { mode: null, conflict: true };\n if (remoteFlag) return { mode: \"remote\", conflict: false };\n if (localFlag) return { mode: \"local\", conflict: false };\n\n const raw = (process.env.SCRIPTCTL_OUTPUT_MODE ?? \"\").trim().toLowerCase();\n if (raw === \"local\" || raw === \"remote\") return { mode: raw, conflict: false };\n if (raw !== \"\") {\n // Unrecognized non-empty value (a typo like \"loca\"): explicit but broken \u2014\n // error rather than silently routing anywhere (including via inference).\n return { mode: null, conflict: false };\n }\n\n // `SCRIPTCTL_OUTPUT_MODE` unset: infer remote when a project group is in scope.\n // The presence of a project group identifier is a strong, specific signal of\n // remote intent (the sandbox marker / an explicit `--project-group-no`), unlike\n // generic ambient gateway credentials which must never imply a target.\n const pgFlag = typeof flags?.projectGroupNo === \"string\" ? flags.projectGroupNo.trim() : \"\";\n const pgEnv = (process.env.SANDBOX_PROJECT_GROUP_NO ?? \"\").trim();\n if (pgFlag !== \"\" || pgEnv !== \"\") return { mode: \"remote\", conflict: false };\n return { mode: null, conflict: false };\n}\n\n/**\n * Resolve the store mode or throw the canonical CliError. Single source of truth\n * for the \"where does a STORE write land\" contract, shared by every store\n * builder (scriptOutputClient, parse's makeOutputStore, commandExport, \u2026):\n * - `--remote` + `--local` \u2192 TARGET_FLAG_CONFLICT\n * - nothing resolvable \u2192 SCRIPT_NO_TARGET (the CLI is unbound; refuse\n * to guess \u2014 names only public flags, never the\n * env var, to keep the mode concept out of\n * agent-facing output)\n * Returns a non-null OutputMode on success.\n */\nexport function resolveOutputModeOrThrow(flags?: {\n remote?: unknown;\n local?: unknown;\n projectGroupNo?: unknown;\n}): OutputMode {\n const resolved = resolveOutputMode(flags);\n if (resolved.conflict) {\n throw new CliError(\"--remote and --local are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"TARGET_FLAG_CONFLICT\",\n hint: \"Drop one of the two flags and retry.\",\n data: { expected: [\"exactly one of --remote (publish to the project DB) or --local (write a local store)\"], actual: [\"--remote and --local\"] },\n });\n }\n if (resolved.mode === null) {\n throw new CliError(\"No output target was selected, so this command has nowhere to read or write.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_NO_TARGET\",\n hint: \"Pass `--script-path <file.json>` to read/write a local script file,\",\n data: { expected: [\"an explicit output target\"], actual: [\"no --script-path, no --remote/--local, and no bound default\"] },\n });\n }\n return resolved.mode;\n}\n", "import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nimport { parseDocument } from \"yaml\";\n\nimport { CliError, EXIT_INPUT } from \"../common.js\";\nimport { isLlmTaskId } from \"./registry.js\";\nimport type { LlmProtocol, LlmTaskId } from \"./types.js\";\n\nexport interface LlmProviderConfig {\n protocol: LlmProtocol;\n baseUrl: string | null;\n apiKeyEnv: string;\n timeoutMs: number;\n maxAttempts: number;\n}\n\nexport interface LlmModelConfig {\n provider: string;\n model: string;\n thinkingBudgetTokens?: number;\n reasoning?: string; // OpenAI-compatible reasoning_effort (e.g. low|medium|high|max)\n temperature?: number; // sampling temperature; 0 = near-deterministic (stabilizes serial merges + resume cache)\n}\n\nexport interface ResolvedLlmConfig {\n version: 1;\n providers: Readonly<Record<string, LlmProviderConfig>>;\n models: Readonly<Record<string, LlmModelConfig>>;\n tasks: Readonly<Partial<Record<LlmTaskId, string>>>;\n source: \"builtin\" | \"file\";\n sourcePath: string | null;\n}\n\ntype UnknownRecord = Record<string, unknown>;\n\nconst PROVIDER_KEYS = new Set([\"protocol\", \"baseUrl\", \"apiKey\", \"timeoutMs\", \"maxAttempts\"]);\nconst MODEL_KEYS = new Set([\"provider\", \"model\", \"thinking\", \"reasoning\", \"temperature\"]);\nconst API_KEY_KEYS = new Set([\"env\"]);\nconst THINKING_KEYS = new Set([\"budgetTokens\"]);\n\nfunction configError(message: string, received: string[] = []): CliError {\n return new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: \"LLM_CONFIG_INVALID\",\n hint: \"Fix the selected LLM configuration or environment and rerun `scriptctl doctor`.\",\n data: { expected: [\"valid scriptctl LLM YAML configuration\"], actual: received },\n });\n}\n\nfunction httpUrlAt(value: string, label: string): string {\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(value);\n } catch {\n throw configError(`${label} must be an absolute URL.`);\n }\n if (parsedUrl.protocol !== \"http:\" && parsedUrl.protocol !== \"https:\") {\n throw configError(`${label} must use http or https.`);\n }\n return parsedUrl.toString().replace(/\\/$/, \"\");\n}\n\nexport function normalizeProviderBaseUrl(value: string, label = \"provider base URL\"): string {\n return httpUrlAt(value, label);\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction recordAt(value: unknown, label: string): UnknownRecord {\n if (!isRecord(value)) throw configError(`${label} must be a mapping.`, [`${label}: ${typeof value}`]);\n return value;\n}\n\nfunction stringAt(value: unknown, label: string): string {\n if (typeof value !== \"string\" || !value.trim()) throw configError(`${label} must be a non-empty string.`);\n return value.trim();\n}\n\nfunction integerAt(value: unknown, label: string, min: number, max?: number): number {\n if (!Number.isInteger(value) || typeof value !== \"number\" || value < min || (max !== undefined && value > max)) {\n throw configError(`${label} must be an integer in ${max === undefined ? `[${min}, +\u221E)` : `[${min}, ${max}]`}.`);\n }\n return value;\n}\n\nfunction rejectUnknownKeys(record: UnknownRecord, allowed: ReadonlySet<string>, label: string): void {\n const unknown = Object.keys(record).filter((key) => !allowed.has(key));\n if (unknown.length > 0) throw configError(`${label} contains unknown fields.`, unknown);\n}\n\nfunction parseProvider(name: string, raw: unknown): LlmProviderConfig {\n const provider = recordAt(raw, `providers.${name}`);\n rejectUnknownKeys(provider, PROVIDER_KEYS, `providers.${name}`);\n const protocolRaw = stringAt(provider[\"protocol\"], `providers.${name}.protocol`);\n if (protocolRaw !== \"anthropic\" && protocolRaw !== \"openai-compatible\" && protocolRaw !== \"google-gemini\") {\n throw configError(`providers.${name}.protocol is unsupported.`, [protocolRaw]);\n }\n // Only openai-compatible needs an explicit endpoint; anthropic and\n // google-gemini use their SDK default when baseUrl is omitted.\n const baseUrl = provider[\"baseUrl\"] === undefined && protocolRaw !== \"openai-compatible\"\n ? null\n : httpUrlAt(stringAt(provider[\"baseUrl\"], `providers.${name}.baseUrl`), `providers.${name}.baseUrl`);\n const apiKey = recordAt(provider[\"apiKey\"], `providers.${name}.apiKey`);\n rejectUnknownKeys(apiKey, API_KEY_KEYS, `providers.${name}.apiKey`);\n const apiKeyEnv = stringAt(apiKey[\"env\"], `providers.${name}.apiKey.env`);\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(apiKeyEnv)) {\n throw configError(`providers.${name}.apiKey.env must be an environment variable name.`);\n }\n return {\n protocol: protocolRaw,\n baseUrl,\n apiKeyEnv,\n timeoutMs: integerAt(provider[\"timeoutMs\"], `providers.${name}.timeoutMs`, 1),\n maxAttempts: integerAt(provider[\"maxAttempts\"], `providers.${name}.maxAttempts`, 1, 6),\n };\n}\n\nfunction parseModel(name: string, raw: unknown, providers: Readonly<Record<string, LlmProviderConfig>>): LlmModelConfig {\n const model = recordAt(raw, `models.${name}`);\n rejectUnknownKeys(model, MODEL_KEYS, `models.${name}`);\n const providerName = stringAt(model[\"provider\"], `models.${name}.provider`);\n const provider = providers[providerName];\n if (!provider) throw configError(`models.${name} references an unknown provider.`, [providerName]);\n const result: LlmModelConfig = {\n provider: providerName,\n model: stringAt(model[\"model\"], `models.${name}.model`),\n };\n if (model[\"reasoning\"] !== undefined) result.reasoning = stringAt(model[\"reasoning\"], `models.${name}.reasoning`);\n if (model[\"temperature\"] !== undefined) {\n const t = model[\"temperature\"];\n if (typeof t !== \"number\" || !Number.isFinite(t) || t < 0) throw configError(`models.${name}.temperature must be a number \u2265 0.`);\n result.temperature = t;\n }\n if (model[\"thinking\"] !== undefined) {\n if (provider.protocol !== \"anthropic\") throw configError(`models.${name}.thinking is only valid for anthropic providers.`);\n const thinking = recordAt(model[\"thinking\"], `models.${name}.thinking`);\n rejectUnknownKeys(thinking, THINKING_KEYS, `models.${name}.thinking`);\n result.thinkingBudgetTokens = integerAt(thinking[\"budgetTokens\"], `models.${name}.thinking.budgetTokens`, 1024);\n }\n return result;\n}\n\nexport function parseLlmConfig(value: unknown, sourcePath: string): ResolvedLlmConfig {\n const root = recordAt(value, \"config\");\n rejectUnknownKeys(root, new Set([\"version\", \"providers\", \"models\", \"tasks\"]), \"config\");\n if (root[\"version\"] !== 1) throw configError(\"config.version must be 1.\");\n const rawProviders = recordAt(root[\"providers\"], \"providers\");\n const providers: Record<string, LlmProviderConfig> = {};\n for (const [name, provider] of Object.entries(rawProviders)) providers[name] = parseProvider(name, provider);\n const rawModels = recordAt(root[\"models\"], \"models\");\n const models: Record<string, LlmModelConfig> = {};\n for (const [name, model] of Object.entries(rawModels)) models[name] = parseModel(name, model, providers);\n if (!models[\"default\"]) throw configError(\"models.default is required.\");\n const tasks: Partial<Record<LlmTaskId, string>> = {};\n if (root[\"tasks\"] !== undefined) {\n const rawTasks = recordAt(root[\"tasks\"], \"tasks\");\n for (const [task, profileValue] of Object.entries(rawTasks)) {\n if (!isLlmTaskId(task)) throw configError(\"tasks contains an unknown task id.\", [task]);\n const profile = stringAt(profileValue, `tasks.${task}`);\n if (!models[profile]) throw configError(`tasks.${task} references an unknown model profile.`, [profile]);\n tasks[task] = profile;\n }\n }\n return { version: 1, providers, models, tasks, source: \"file\", sourcePath };\n}\n\nexport const BUILTIN_LLM_CONFIG: ResolvedLlmConfig = {\n version: 1,\n providers: {\n // baseUrl comes from PROJECT_LITELLM_GATEWAY_BASE_URL (see builtinLlmConfig);\n // null until resolved, so the built-in config never bakes in a host.\n gw: { protocol: \"openai-compatible\", baseUrl: null, apiKeyEnv: \"PROJECT_LITELLM_GATEWAY_API_KEY\", timeoutMs: 300_000, maxAttempts: 3 },\n // Video goes direct to Google (not the LiteLLM gateway); longer timeout for\n // upload+processing of large episode files. Credential: GEMINI_API_KEY.\n \"google-gemini\": { protocol: \"google-gemini\", baseUrl: null, apiKeyEnv: \"GEMINI_API_KEY\", timeoutMs: 600_000, maxAttempts: 3 },\n },\n models: {\n // DeepSeek v4 Flash is the default high-volume text profile. It supports the\n // OpenAI-compatible chat completions route used by the gateway.\n // temperature: 0 \u2014 ingest is all judgment/extraction (entity merges, state\n // classification, normalization), never creative writing. Deterministic\n // sampling stops run-to-run drift (a stray `## \u5408\u5E76` folding two distinct\n // characters into one) and keeps resume cache keys stable.\n default: { provider: \"gw\", model: \"deepseek-v4-flash-packy\", temperature: 0 },\n \"ingest-low\": { provider: \"gw\", model: \"deepseek-v4-flash-packy\", temperature: 0 },\n // Serial episode-assets \u2192 sonnet: native tool-calling with a name/aliases-split\n // schema separates canonical names from translations/past-life names far more\n // reliably than grok did (skeleton leads split correctly, no paren-polluted\n // names), which markdown/text mode could not hold on this model.\n \"ingest-normalize\": { provider: \"gw\", model: \"claude-sonnet-4-6-aihubmix\", temperature: 0 },\n \"ingest-video\": { provider: \"google-gemini\", model: \"gemini-3.7-flash\" },\n // `scriptctl review` names this profile directly rather than through a\n // task id: it drives its own agent loop instead of the router, and one\n // Gemini credential serves both the loop and its video checks.\n \"review-agent\": { provider: \"google-gemini\", model: \"gemini-3.8-flash\", temperature: 0 },\n },\n tasks: {\n // Ingest: cheap model for chunk normalization + pronoun resolve + recall;\n // everything else (governance/refine/state, synopsis, metadata) falls to\n // the high `default` model.\n \"ingest.body-start\": \"ingest-low\",\n \"ingest.arc-summary\": \"ingest-low\",\n \"ingest.text-normalize\": \"ingest-low\",\n \"ingest.mention-resolve\": \"ingest-low\",\n \"ingest.asset-recall\": \"ingest-low\",\n // Whole-script duplicate/state audit uses Sonnet native tool-calling for a\n // schema-bound set of findings.\n \"ingest.asset-audit\": \"ingest-normalize\",\n // Serial entity/look extraction and its unresolved-name repair share the same\n // schema-bound function-calling model.\n \"ingest.episode-assets\": \"ingest-normalize\",\n \"ingest.name-fix\": \"ingest-normalize\",\n // Video understanding \u2192 Gemini (\u00A710.3).\n \"ingest.video-serial\": \"ingest-video\",\n },\n source: \"builtin\",\n sourcePath: null,\n};\n\nexport function builtinLlmConfig(): ResolvedLlmConfig {\n const rawBaseUrl = (process.env.PROJECT_LITELLM_GATEWAY_BASE_URL ?? \"\").trim();\n const baseUrl = rawBaseUrl ? httpUrlAt(rawBaseUrl, \"PROJECT_LITELLM_GATEWAY_BASE_URL\") : null;\n return {\n ...BUILTIN_LLM_CONFIG,\n providers: {\n gw: { ...BUILTIN_LLM_CONFIG.providers[\"gw\"]!, baseUrl },\n // Gemini is not gateway-routed; keep its SDK-default endpoint (null).\n \"google-gemini\": { ...BUILTIN_LLM_CONFIG.providers[\"google-gemini\"]! },\n },\n models: { ...BUILTIN_LLM_CONFIG.models },\n tasks: { ...BUILTIN_LLM_CONFIG.tasks },\n };\n}\n\nfunction defaultConfigPath(): string {\n const xdg = (process.env.XDG_CONFIG_HOME ?? \"\").trim();\n return xdg ? path.join(xdg, \"scriptctl\", \"llm.yaml\") : path.join(os.homedir(), \".config\", \"scriptctl\", \"llm.yaml\");\n}\n\nfunction readYamlConfig(filePath: string): ResolvedLlmConfig {\n if (!fs.existsSync(filePath)) throw configError(\"LLM configuration file does not exist.\", [filePath]);\n const document = parseDocument(fs.readFileSync(filePath, \"utf-8\"), { uniqueKeys: true });\n if (document.errors.length > 0) throw configError(\"LLM configuration YAML is invalid.\", document.errors.map((error) => error.message));\n const value: unknown = document.toJS();\n return parseLlmConfig(value, path.resolve(filePath));\n}\n\nexport function loadLlmConfig(explicitPath?: string): ResolvedLlmConfig {\n const flagPath = (explicitPath ?? \"\").trim();\n if (flagPath) return readYamlConfig(flagPath);\n const envPath = (process.env.SCRIPTCTL_LLM_CONFIG ?? \"\").trim();\n if (envPath) return readYamlConfig(envPath);\n const conventionalPath = defaultConfigPath();\n return fs.existsSync(conventionalPath) ? readYamlConfig(conventionalPath) : builtinLlmConfig();\n}\n", "import type { LlmTaskId, LlmTaskMode } from \"./types.js\";\n\nexport interface LlmTaskSpec {\n id: LlmTaskId;\n mode: LlmTaskMode;\n version: string;\n maxOutputTokens: number;\n defaultProfile: \"default\";\n}\n\nfunction spec(id: LlmTaskId, mode: LlmTaskMode, maxOutputTokens: number): LlmTaskSpec {\n return { id, mode, version: \"1\", maxOutputTokens, defaultProfile: \"default\" };\n}\n\nexport const LLM_TASK_REGISTRY = {\n \"direct.episode-titles\": spec(\"direct.episode-titles\", \"tool\", 4096),\n \"direct.batch-extract\": spec(\"direct.batch-extract\", \"text\", 16000),\n \"direct.episode-synopsis\": spec(\"direct.episode-synopsis\", \"tool\", 2048),\n \"direct.synopsis-reduction\": spec(\"direct.synopsis-reduction\", \"tool\", 4096),\n \"direct.script-synopsis\": spec(\"direct.script-synopsis\", \"tool\", 2048),\n \"direct.asset-grouping\": spec(\"direct.asset-grouping\", \"text\", 8000),\n \"direct.asset-curation\": spec(\"direct.asset-curation\", \"text\", 20000),\n \"direct.asset-curation-audit\": spec(\"direct.asset-curation-audit\", \"text\", 20000),\n \"direct.location-canonicalization\": spec(\"direct.location-canonicalization\", \"text\", 20000),\n \"direct.state-curation\": spec(\"direct.state-curation\", \"text\", 20000),\n \"direct.state-binding\": spec(\"direct.state-binding\", \"tool\", 16000),\n \"metadata.global\": spec(\"metadata.global\", \"text\", 16000),\n \"metadata.descriptions\": spec(\"metadata.descriptions\", \"text\", 16000),\n \"synopsis.chunk\": spec(\"synopsis.chunk\", \"text\", 4096),\n \"synopsis.episode\": spec(\"synopsis.episode\", \"text\", 4096),\n // Aggregation output is short, but reasoning models can consume several\n // thousand hidden tokens before emitting it. Use the long-text budget so\n // valid arc and whole-script summaries are not cut off mid-response.\n \"synopsis.arc\": spec(\"synopsis.arc\", \"text\", 16000),\n \"synopsis.script-overview\": spec(\"synopsis.script-overview\", \"text\", 16000),\n // Locate where the actual screenplay body begins: a cheap text classifier\n // scanned over 50-line windows, emitting just `\u8D77\u70B9: <\u884C\u53F7>` / `\u8D77\u70B9: \u65E0`. Text\n // (not tool) mode so it runs on the cheap deepseek-flash profile, which does\n // not support function calling. The reply is tiny, but reasoning models spend\n // hidden tokens first \u2014 too small a budget truncates (finish_reason=length) and\n // the whole call throws. A big cap costs nothing extra (the call stops when the\n // model is done); it only prevents truncation, so match normalize's headroom.\n \"ingest.body-start\": spec(\"ingest.body-start\", \"text\", 16000),\n // Compress a folded run of ~10 episodes' aged synopses into one arc paragraph.\n // Fires rarely (only when the synopsis exceeds budget); output is a short\n // paragraph, so a modest budget suffices (headroom for a reasoning model).\n \"ingest.arc-summary\": spec(\"ingest.arc-summary\", \"text\", 4096),\n \"ingest.text-normalize\": spec(\"ingest.text-normalize\", \"text\", 32000),\n // Serial per-WINDOW asset/state annotation: model reads the running context + a\n // token-bounded window of 1+ episodes (~10k body tokens), returns a structured\n // Delta (SERIAL_DELTA_SCHEMA) covering all their scenes via native tool-calling \u2014\n // canonical names + aliases as separate fields, so no markdown delimiter can\n // mangle a name. Output scales with the window's scene count \u2192 large cap so a\n // dense window never truncates (a big cap costs nothing when small). Tool mode:\n // the serial profile (ingest-normalize) must be a function-calling model.\n \"ingest.episode-assets\": spec(\"ingest.episode-assets\", \"tool\", 32000),\n // Repair pass: names that appear in the body but resolved to nothing in the\n // final registry (a missed merge). The model says merge-into-existing or new.\n \"ingest.name-fix\": spec(\"ingest.name-fix\", \"tool\", 16000),\n \"ingest.mention-resolve\": spec(\"ingest.mention-resolve\", \"text\", 8000),\n \"ingest.asset-extract\": spec(\"ingest.asset-extract\", \"text\", 8000),\n \"ingest.asset-curate\": spec(\"ingest.asset-curate\", \"text\", 32000),\n \"ingest.asset-recall\": spec(\"ingest.asset-recall\", \"text\", 65536),\n \"ingest.asset-refine\": spec(\"ingest.asset-refine\", \"text\", 32000),\n \"ingest.state-reconcile\": spec(\"ingest.state-reconcile\", \"text\", 32000),\n // Final whole-script asset consistency audit. It reads a compact global\n // roster and returns structured findings; no automatic merge is applied.\n \"ingest.asset-audit\": spec(\"ingest.asset-audit\", \"tool\", 32000),\n \"ingest.speaker-audit\": spec(\"ingest.speaker-audit\", \"tool\", 16000),\n // Video understanding (Gemini, \u00A710.2). One serial pass per episode: watches the\n // video with the running cross-episode context and emits the episode content +\n // a registry delta in one structured JSON response. Large output budget (\u00A710.5\n // verified 65536 for a full episode's scenes).\n \"ingest.video-serial\": spec(\"ingest.video-serial\", \"video\", 65536),\n} satisfies Record<LlmTaskId, LlmTaskSpec>;\n\nexport const LLM_TASK_IDS = Object.keys(LLM_TASK_REGISTRY).filter(isLlmTaskId);\n\nexport function isLlmTaskId(value: string): value is LlmTaskId {\n return Object.hasOwn(LLM_TASK_REGISTRY, value);\n}\n", "import * as crypto from \"node:crypto\";\n\nimport { CliError, EXIT_INPUT, EXIT_RUNTIME } from \"../common.js\";\nimport {\n aggregateFailures,\n classificationOf,\n contextOf,\n createOperationalFailure,\n formatFailure,\n type OperationalFailure,\n} from \"../failures.js\";\nimport { AnthropicModel } from \"../infra/llm/anthropic-model.js\";\nimport {\n DoubaoVideoModel,\n type DoubaoRunRequest,\n} from \"../infra/llm/doubao-video-model.js\";\nimport { GeminiVideoModel } from \"../infra/llm/gemini-video-model.js\";\nimport { OpenAiCompatibleModel } from \"../infra/llm/openai-compatible-model.js\";\nimport {\n loadLlmConfig,\n normalizeProviderBaseUrl,\n type LlmModelConfig,\n type LlmProviderConfig,\n type ResolvedLlmConfig,\n} from \"./config.js\";\nimport { LLM_TASK_IDS, LLM_TASK_REGISTRY } from \"./registry.js\";\nimport { LlmTransportError } from \"./types.js\";\nimport type {\n LlmAdapter,\n LlmExecutorOptions,\n LlmRouteInfo,\n LlmRouteUsage,\n LlmTaskExecutor,\n LlmTaskId,\n LlmUsageEvent,\n TaskVideoPort,\n TextGenerationRequest,\n TextGenerationResponse,\n ToolGenerationRequest,\n ToolGenerationResponse,\n VideoUnderstandingPort,\n VideoGenerationResponse,\n TokenUsage,\n} from \"./types.js\";\n\nexport interface ResolvedRoute {\n info: LlmRouteInfo;\n providerConfig: LlmProviderConfig;\n modelConfig: LlmModelConfig;\n}\n\nexport interface DoubaoVideoRunner {\n run(request: DoubaoRunRequest): Promise<VideoGenerationResponse>;\n}\n\n// Keep every built-in Gemini attempt on the current stable Flash model. A custom\n// routed model may fall back once to this model before the cross-provider Doubao\n// fallback. The Gemini Files handle is reused; only generateContent reruns.\nconst VIDEO_FALLBACK_MODELS = [\"gemini-3.7-flash\"] as const;\n\nconst PROXY_GEMINI_MODELS = [\n \"gemini-3.7-flash-c3\",\n \"gemini-3.6-flash-c3\",\n \"gemini-3.5-flash-c3\",\n \"gemini-3.1-pro-preview-think-c3\",\n] as const;\nconst PROXY_GEMINI_API_KEY_ENVS = [\"GEMINI_PROXY_API_KEY\", \"REDRAW_GEMINI_PROXY_API_KEY\"] as const;\nconst PROXY_GEMINI_BASE_URL_ENVS = [\"GEMINI_PROXY_BASE_URL\", \"REDRAW_GEMINI_PROXY_BASE_URL\"] as const;\n\n// Cross-provider last resort after every Gemini model fails: Doubao on Volcengine\n// Ark. Different protocol (Files API sets fps at upload; Responses API references\n// the file id), so it re-uploads the local transcode to its own storage. Credential\n// is ARK_API_KEY; absent \u2192 the fallback is silently skipped, Gemini stays the only path.\n// `model` is an Ark inference-endpoint id (ep-\u2026), which resolves server-side to a\n// video-understanding model. It's account-specific, so ARK_MODEL overrides the default.\nconst DOUBAO_FALLBACK = {\n model: \"ep-20260721150136-98dj9\",\n modelEnv: \"ARK_MODEL\",\n baseUrl: \"https://ark.cn-beijing.volces.com/api/v3\",\n apiKeyEnv: \"ARK_API_KEY\",\n timeoutMs: 600_000,\n maxAttempts: 3,\n} as const;\n\nfunction normalizeBaseUrl(value: string | null): string {\n return value?.trim().replace(/\\/+$/, \"\") ?? \"anthropic-sdk-default\";\n}\n\nfunction routeFingerprint(task: LlmTaskId, provider: LlmProviderConfig, model: LlmModelConfig): string {\n const spec = LLM_TASK_REGISTRY[task];\n const material = JSON.stringify({\n task,\n taskVersion: spec.version,\n protocol: provider.protocol,\n baseUrl: normalizeBaseUrl(provider.baseUrl),\n model: model.model,\n thinkingBudgetTokens: model.thinkingBudgetTokens ?? null,\n });\n return crypto.createHash(\"sha256\").update(material).digest(\"hex\");\n}\n\nfunction configRuntimeError(message: string, required: string[], received: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: \"LLM_CONFIG_INVALID\",\n hint: \"Fix the selected LLM configuration and run `scriptctl doctor`.\",\n data: { expected: required, actual: received },\n });\n}\n\nfunction credentialError(provider: string): CliError {\n return new CliError(\"The selected LLM provider credential is not configured.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"LLM_CREDENTIAL_MISSING\",\n hint: \"Configure the credential and rerun `scriptctl doctor`.\",\n data: { expected: [\"credential environment variable referenced by the selected provider\"], actual: [`provider: ${provider}`, \"credential: missing\"] },\n });\n}\n\nfunction routedFailure(error: unknown, route: LlmRouteInfo): OperationalFailure {\n if (error instanceof LlmTransportError) {\n return createOperationalFailure(classificationOf(error.failure), {\n ...contextOf(error.failure),\n provider: route.provider,\n model: route.model,\n retryable: error.failure.retryable,\n message: error.failure.message,\n });\n }\n return createOperationalFailure(\n { failure_type: \"unknown\", failure_code: \"unknown\" },\n {\n provider: route.provider,\n model: route.model,\n retryable: false,\n message: error instanceof Error ? error.message : String(error),\n },\n );\n}\n\nexport class ModelRouter implements LlmTaskExecutor {\n private readonly adapters = new Map<string, LlmAdapter>();\n private readonly videoAdapters = new Map<string, VideoUnderstandingPort>();\n private readonly doubaoAdapters = new Map<string, DoubaoVideoModel>();\n private readonly resolvedRoutes = new Map<LlmTaskId, ResolvedRoute>();\n private readonly usageLog: LlmUsageEvent[] = [];\n\n constructor(\n private readonly config: ResolvedLlmConfig,\n private readonly options: LlmExecutorOptions = {},\n ) {}\n\n get configSource(): \"builtin\" | \"file\" {\n return this.config.source;\n }\n\n private resolve(task: LlmTaskId): ResolvedRoute {\n const cached = this.resolvedRoutes.get(task);\n if (cached) return cached;\n const spec = LLM_TASK_REGISTRY[task];\n const profile = this.config.tasks[task] ?? spec.defaultProfile;\n const modelConfig = this.config.models[profile];\n if (!modelConfig) throw configRuntimeError(\"The task route references a missing model profile.\", [profile], [`task: ${task}`]);\n const providerConfig = this.config.providers[modelConfig.provider];\n if (!providerConfig) {\n throw configRuntimeError(\"The model profile references a missing provider.\", [modelConfig.provider], [`profile: ${profile}`]);\n }\n if (providerConfig.protocol === \"openai-compatible\" && !providerConfig.baseUrl) {\n throw configRuntimeError(\n \"OpenAI-compatible providers require an explicit endpoint \u2014 set the provider's baseUrl, or PROJECT_LITELLM_GATEWAY_BASE_URL for the built-in gateway.\",\n [\"provider.baseUrl\"],\n [`provider: ${modelConfig.provider}`],\n );\n }\n if (modelConfig.thinkingBudgetTokens !== undefined && spec.mode === \"tool\") {\n throw configRuntimeError(\n \"Anthropic thinking cannot be combined with a forced tool call.\",\n [\"a text task or a profile without thinking\"],\n [`task: ${task}`, `profile: ${profile}`],\n );\n }\n if (modelConfig.thinkingBudgetTokens !== undefined && modelConfig.thinkingBudgetTokens >= spec.maxOutputTokens) {\n throw configRuntimeError(\n \"The thinking token budget must be smaller than the task output budget.\",\n [`thinking budget < ${spec.maxOutputTokens}`],\n [`task: ${task}`, `thinking budget: ${modelConfig.thinkingBudgetTokens}`],\n );\n }\n const videoOverrides = spec.mode === \"video\" ? this.options.videoProvider : undefined;\n const overriddenProvider = videoOverrides?.baseUrl\n ? { ...providerConfig, baseUrl: normalizeProviderBaseUrl(videoOverrides.baseUrl, \"--provider-base-url\") }\n : providerConfig;\n const overriddenModel = videoOverrides?.model\n ? { ...modelConfig, model: videoOverrides.model.trim() }\n : modelConfig;\n if (videoOverrides?.model !== undefined && !overriddenModel.model) {\n throw configRuntimeError(\"The video provider model cannot be empty.\", [\"non-empty --provider-model\"], [\"model: empty\"]);\n }\n const resolved: ResolvedRoute = {\n info: {\n task,\n profile,\n provider: modelConfig.provider,\n protocol: overriddenProvider.protocol,\n baseUrl: overriddenProvider.baseUrl,\n model: overriddenModel.model,\n fingerprint: routeFingerprint(task, overriddenProvider, overriddenModel),\n },\n providerConfig: overriddenProvider,\n modelConfig: overriddenModel,\n };\n this.resolvedRoutes.set(task, resolved);\n return resolved;\n }\n\n route(task: LlmTaskId): LlmRouteInfo {\n return this.resolve(task).info;\n }\n\n routes(): LlmRouteInfo[] {\n return LLM_TASK_IDS.map((task) => this.route(task));\n }\n\n private emptyUsage(): Omit<LlmRouteUsage, keyof LlmRouteInfo> {\n return {\n calls: 0,\n succeeded: 0,\n failed: 0,\n reused: 0,\n attempts: 0,\n durationMs: 0,\n inputTokens: 0,\n outputTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n };\n }\n\n recordReuse(task: LlmTaskId): void {\n const at = new Date().toISOString();\n this.recordEvent(this.route(task), \"reused\", at, at, 0, {});\n }\n\n usage(): LlmRouteUsage[] {\n const aggregate = new Map<string, LlmRouteUsage>();\n for (const event of this.usageLog) {\n const key = `${event.task}\\u0000${event.provider}\\u0000${event.protocol}\\u0000${event.model}\\u0000${event.fingerprint}`;\n const usage = aggregate.get(key) ?? {\n task: event.task,\n profile: event.profile,\n provider: event.provider,\n protocol: event.protocol,\n baseUrl: event.baseUrl,\n model: event.model,\n fingerprint: event.fingerprint,\n ...this.emptyUsage(),\n };\n if (event.status === \"reused\") usage.reused += 1;\n else {\n usage.calls += 1;\n usage[event.status] += 1;\n usage.attempts += event.attempts;\n usage.durationMs += event.durationMs;\n usage.inputTokens += event.inputTokens;\n usage.outputTokens += event.outputTokens;\n usage.cachedInputTokens += event.cachedInputTokens;\n usage.cacheCreationTokens += event.cacheCreationTokens;\n }\n aggregate.set(key, usage);\n }\n return [...aggregate.values()];\n }\n\n usageEvents(): LlmUsageEvent[] {\n return this.usageLog.map((event) => ({ ...event }));\n }\n\n private recordEvent(\n route: LlmRouteInfo,\n status: LlmUsageEvent[\"status\"],\n startedAt: string,\n endedAt: string,\n durationMs: number,\n usage: TokenUsage,\n attempts = 0,\n errorCode?: LlmUsageEvent[\"errorCode\"],\n ): void {\n this.usageLog.push({\n ...route,\n sequence: this.usageLog.length + 1,\n status,\n attempts,\n startedAt,\n endedAt,\n durationMs,\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n cachedInputTokens: usage.cachedInputTokens ?? 0,\n cacheCreationTokens: usage.cacheCreationTokens ?? 0,\n ...(errorCode ? { errorCode } : {}),\n });\n }\n\n private async tracked<T extends { attempts: number; usage?: TokenUsage }>(\n route: LlmRouteInfo,\n operation: () => Promise<T>,\n ): Promise<T> {\n const startedMs = Date.now();\n const startedAt = new Date(startedMs).toISOString();\n try {\n const response = await operation();\n const endedMs = Date.now();\n this.recordEvent(route, \"succeeded\", startedAt, new Date(endedMs).toISOString(), endedMs - startedMs, response.usage ?? {}, response.attempts);\n return response;\n } catch (error) {\n const endedMs = Date.now();\n const transport = error instanceof LlmTransportError ? error : null;\n this.recordEvent(\n route,\n \"failed\",\n startedAt,\n new Date(endedMs).toISOString(),\n endedMs - startedMs,\n transport?.usage ?? {},\n transport?.attempts ?? 1,\n transport?.code,\n );\n throw error;\n }\n }\n\n private videoRoute(route: ResolvedRoute, model: string): LlmRouteInfo {\n const modelConfig = model === route.info.model ? route.modelConfig : { ...route.modelConfig, model };\n return {\n ...route.info,\n model,\n fingerprint: routeFingerprint(route.info.task, route.providerConfig, modelConfig),\n };\n }\n\n private resolvedVideoRoute(route: ResolvedRoute, model: string): ResolvedRoute {\n const modelConfig = model === route.info.model ? route.modelConfig : { ...route.modelConfig, model };\n return {\n info: this.videoRoute(route, model),\n providerConfig: route.providerConfig,\n modelConfig,\n };\n }\n\n private proxyVideoRoutes(task: LlmTaskId): ResolvedRoute[] {\n if (this.options.videoProvider) return [];\n const apiKeyEnv = PROXY_GEMINI_API_KEY_ENVS.find((name) => (process.env[name] ?? \"\").trim());\n const baseUrlEnv = PROXY_GEMINI_BASE_URL_ENVS.find((name) => (process.env[name] ?? \"\").trim());\n if (!apiKeyEnv || !baseUrlEnv) return [];\n const baseUrl = normalizeProviderBaseUrl(process.env[baseUrlEnv]!, baseUrlEnv);\n return PROXY_GEMINI_MODELS.map((model, index) => {\n const providerConfig: LlmProviderConfig = {\n protocol: \"google-gemini\",\n baseUrl,\n apiKeyEnv,\n timeoutMs: 90_000,\n maxAttempts: index < 2 ? 2 : 1,\n };\n const modelConfig: LlmModelConfig = { provider: \"gemini-proxy\", model };\n return {\n info: {\n task,\n profile: \"gemini-proxy\",\n provider: \"gemini-proxy\",\n protocol: \"google-gemini\",\n baseUrl,\n model,\n fingerprint: routeFingerprint(task, providerConfig, modelConfig),\n },\n providerConfig,\n modelConfig,\n };\n });\n }\n\n private doubaoRoute(task: LlmTaskId): LlmRouteInfo {\n const provider: LlmProviderConfig = {\n protocol: \"openai-compatible\",\n baseUrl: DOUBAO_FALLBACK.baseUrl,\n apiKeyEnv: DOUBAO_FALLBACK.apiKeyEnv,\n timeoutMs: DOUBAO_FALLBACK.timeoutMs,\n maxAttempts: DOUBAO_FALLBACK.maxAttempts,\n };\n const model: LlmModelConfig = { provider: \"doubao\", model: this.doubaoModel() };\n return {\n task,\n profile: \"doubao-fallback\",\n provider: \"doubao\",\n protocol: provider.protocol,\n baseUrl: provider.baseUrl,\n model: model.model,\n fingerprint: routeFingerprint(task, provider, model),\n };\n }\n\n private adapter(route: ResolvedRoute): LlmAdapter {\n const key = `${route.info.provider}\\u0000${route.info.model}\\u0000${route.modelConfig.thinkingBudgetTokens ?? \"\"}`;\n const cached = this.adapters.get(key);\n if (cached) return cached;\n const apiKey = (process.env[route.providerConfig.apiKeyEnv] ?? \"\").trim();\n if (!apiKey) throw credentialError(route.info.provider);\n const adapter = route.providerConfig.protocol === \"anthropic\"\n ? new AnthropicModel(route.providerConfig, route.modelConfig, apiKey)\n : new OpenAiCompatibleModel(route.providerConfig, route.modelConfig, apiKey);\n this.adapters.set(key, adapter);\n return adapter;\n }\n\n // model defaults to the route's model; pass an override to build a peer adapter\n // that shares the provider/credential but targets a fallback model.\n protected videoAdapter(route: ResolvedRoute, model?: string): VideoUnderstandingPort {\n if (route.providerConfig.protocol !== \"google-gemini\") {\n throw configRuntimeError(\n \"Video tasks require a google-gemini provider.\",\n [\"provider.protocol: google-gemini\"],\n [`provider: ${route.info.provider}`, `protocol: ${route.providerConfig.protocol}`],\n );\n }\n const modelName = model ?? route.info.model;\n const key = `${route.info.provider} ${route.providerConfig.baseUrl ?? \"official\"} ${modelName}`;\n const cached = this.videoAdapters.get(key);\n if (cached) return cached;\n const apiKey = this.videoCredential(route);\n if (!apiKey) throw credentialError(route.info.provider);\n const modelConfig = model ? { ...route.modelConfig, model } : route.modelConfig;\n const adapter = new GeminiVideoModel(route.providerConfig, modelConfig, apiKey);\n this.videoAdapters.set(key, adapter);\n return adapter;\n }\n\n private videoCredential(route: ResolvedRoute): string {\n const override = this.options.videoProvider?.apiKey;\n const apiKey = override?.kind === \"literal\"\n ? override.value.trim()\n : override?.kind === \"env\"\n ? (process.env[override.name] ?? \"\").trim()\n : (process.env[route.providerConfig.apiKeyEnv] ?? \"\").trim();\n if (!apiKey) throw credentialError(route.info.provider);\n return apiKey;\n }\n\n videoPort(task: LlmTaskId): TaskVideoPort {\n const spec = LLM_TASK_REGISTRY[task];\n if (spec.mode !== \"video\") throw configRuntimeError(\"The task does not support video generation.\", [\"video task\"], [`task: ${task}`]);\n const route = this.resolve(task);\n if (route.providerConfig.protocol !== \"google-gemini\") {\n throw configRuntimeError(\n \"Video tasks require a google-gemini provider.\",\n [\"provider.protocol: google-gemini\"],\n [`provider: ${route.info.provider}`, `protocol: ${route.providerConfig.protocol}`],\n );\n }\n const officialRoutes = (\n this.options.videoProvider\n ? [route.info.model]\n : [route.info.model, ...VIDEO_FALLBACK_MODELS.filter((m) => m !== route.info.model)]\n ).map((model) => this.resolvedVideoRoute(route, model));\n const proxyRoutes = this.proxyVideoRoutes(task);\n if (this.options.videoProvider || proxyRoutes.length === 0) void this.videoAdapter(route);\n return {\n prepare: async (localPath, mimeType, mode, signal) => {\n const prepareRoute = mode === \"base64\" && proxyRoutes.length > 0 ? proxyRoutes[0]! : route;\n try {\n return await this.videoAdapter(prepareRoute).prepare(localPath, mimeType, mode, signal);\n } catch (error) {\n if (signal?.aborted || mode !== \"file-api\" || this.options.videoProvider || !this.doubaoAdapter()) throw error;\n const failure = routedFailure(error, route.info);\n process.stderr.write(`\u21AA\uFE0F Gemini \u6587\u4EF6\u4E0A\u4F20\u5931\u8D25,\u6539\u7531\u8C46\u5305\u8BFB\u53D6\u672C\u5730\u89C6\u9891 (${formatFailure(failure)})\\n`);\n return { kind: \"local-fallback\", path: localPath, mimeType, primaryFailure: failure };\n }\n },\n release: (media, signal) => media.kind === \"base64\" || media.kind === \"local-fallback\"\n ? Promise.resolve()\n : this.videoAdapter(route).release(media, signal),\n generate: async (request) => {\n const failures: OperationalFailure[] = request.media.kind === \"local-fallback\"\n ? [request.media.primaryFailure]\n : [];\n const skipped: string[] = [];\n const geminiChain = request.media.kind === \"local-fallback\"\n ? []\n : request.media.kind === \"base64\"\n ? [...proxyRoutes, ...officialRoutes]\n : officialRoutes;\n for (const [index, attemptRoute] of geminiChain.entries()) {\n try {\n const response = await this.tracked(\n attemptRoute.info,\n () => this.videoAdapter(attemptRoute).generate({ ...request, maxOutputTokens: spec.maxOutputTokens }),\n );\n if (index > 0) process.stderr.write(`\u21AA\uFE0F \u5DF2\u5207\u6362\u5230\u5907\u7528\u6A21\u578B ${attemptRoute.info.model}\\n`);\n return response;\n } catch (error) {\n // Abort is the caller's decision, not a model failure \u2014 stop the whole chain.\n if (request.signal?.aborted) throw error;\n const failure = routedFailure(error, attemptRoute.info);\n failures.push(failure);\n const detail = formatFailure(failure);\n if (index < geminiChain.length - 1) {\n process.stderr.write(`\u21AA\uFE0F ${attemptRoute.info.model} \u5F53\u524D\u4E0D\u53EF\u7528\uFF0C\u5207\u6362\u4E0B\u4E00\u7EBF\u8DEF (${detail})\\n`);\n }\n }\n }\n // Cross-provider last resort: Doubao (Ark). Needs ARK_API_KEY + the local file.\n const doubao = this.options.videoProvider ? null : this.doubaoAdapter();\n const localPath = request.media.kind === \"local-fallback\" ? request.media.path : request.localPath;\n if (doubao && localPath) {\n const attemptRoute = this.doubaoRoute(task);\n try {\n process.stderr.write(`\u21AA\uFE0F Gemini \u5168\u90E8\u5931\u8D25,\u56DE\u9000\u5230\u8C46\u5305 ${this.doubaoModel()}\\n`);\n const response = await this.tracked(attemptRoute, () => doubao.run({\n localPath,\n localMime: request.media.kind === \"local-fallback\" ? request.media.mimeType : request.localMime ?? \"video/mp4\",\n user: request.user,\n fps: request.fps,\n maxOutputTokens: spec.maxOutputTokens,\n ...(request.system ? { system: request.system } : {}),\n ...(request.responseJsonSchema ? { responseJsonSchema: request.responseJsonSchema } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n }));\n return response;\n } catch (error) {\n if (request.signal?.aborted) throw error;\n failures.push(routedFailure(error, attemptRoute));\n }\n } else if (!doubao) {\n if (!this.options.videoProvider) {\n skipped.push(\"doubao: skipped (ARK_API_KEY not set)\");\n }\n } else {\n skipped.push(\"doubao: skipped (no local file to re-upload)\");\n }\n const aggregate = aggregateFailures(failures, \"All configured video model attempts failed.\");\n throw new LlmTransportError(\"request_failed\", aggregate.message, {\n retryable: aggregate.retryable,\n classification: classificationOf(aggregate),\n context: contextOf(aggregate),\n modelFailures: failures,\n details: [...failures.map(formatFailure), ...skipped],\n });\n },\n };\n }\n\n // The Doubao fallback adapter, or null when ARK_API_KEY is unset. Cached per key.\n // Overridable in tests to inject a fake Ark client.\n protected doubaoAdapter(): DoubaoVideoRunner | null {\n const apiKey = (process.env[DOUBAO_FALLBACK.apiKeyEnv] ?? \"\").trim();\n if (!apiKey) return null;\n const model = this.doubaoModel();\n const key = `doubao ${model}`;\n const cached = this.doubaoAdapters.get(key);\n if (cached) return cached;\n const adapter = new DoubaoVideoModel(model, DOUBAO_FALLBACK.timeoutMs, DOUBAO_FALLBACK.maxAttempts, apiKey, DOUBAO_FALLBACK.baseUrl);\n this.doubaoAdapters.set(key, adapter);\n return adapter;\n }\n\n // Ark endpoint id / model name, ARK_MODEL overriding the account-specific default.\n protected doubaoModel(): string {\n return (process.env[DOUBAO_FALLBACK.modelEnv] ?? \"\").trim() || DOUBAO_FALLBACK.model;\n }\n\n async generateText(task: LlmTaskId, request: Omit<TextGenerationRequest, \"maxOutputTokens\">): Promise<TextGenerationResponse> {\n const spec = LLM_TASK_REGISTRY[task];\n if (spec.mode !== \"text\") throw configRuntimeError(\"The task does not support text generation.\", [\"text task\"], [`task: ${task}`]);\n const route = this.resolve(task);\n const adapter = this.adapter(route);\n return this.tracked(route.info, () => adapter.generateText({ ...request, maxOutputTokens: spec.maxOutputTokens }));\n }\n\n async generateTool(task: LlmTaskId, request: Omit<ToolGenerationRequest, \"maxOutputTokens\">): Promise<ToolGenerationResponse> {\n const spec = LLM_TASK_REGISTRY[task];\n if (spec.mode !== \"tool\") throw configRuntimeError(\"The task does not support tool generation.\", [\"tool task\"], [`task: ${task}`]);\n const route = this.resolve(task);\n const adapter = this.adapter(route);\n return this.tracked(route.info, () => adapter.generateTool({ ...request, maxOutputTokens: spec.maxOutputTokens }));\n }\n}\n\nexport function createLlmExecutor(explicitConfigPath?: string, options?: LlmExecutorOptions): ModelRouter {\n return new ModelRouter(loadLlmConfig(explicitConfigPath), options);\n}\n", "import Anthropic, { APIConnectionError, APIConnectionTimeoutError, APIError, APIUserAbortError } from \"@anthropic-ai/sdk\";\nimport type { MessageCreateParamsNonStreaming, Tool } from \"@anthropic-ai/sdk/resources/messages\";\n\nimport type { LlmProviderConfig, LlmModelConfig } from \"../../llm/config.js\";\nimport {\n LlmTransportError,\n type LlmAdapter,\n type TextGenerationRequest,\n type TextGenerationResponse,\n type ToolGenerationRequest,\n type ToolGenerationResponse,\n type TokenUsage,\n} from \"../../llm/types.js\";\nimport { addTokenUsage, withTransientRetry } from \"./retry.js\";\n\n// Anthropic returns usage.{input_tokens,output_tokens} (+ cache token fields we fold\n// into input). Missing \u2192 undefined, so accounting counts it as zero rather than erroring.\n// Anthropic's native usage.input_tokens is FRESH input only \u2014 cache-read and\n// cache-creation are separate buckets, NOT included in input_tokens (the opposite of\n// OpenAI). So the true total input = input_tokens + both cache buckets, and we surface\n// the buckets as subsets of that total to match the shared TokenUsage semantics.\nfunction usageOf(response: { usage?: { input_tokens?: number | null; output_tokens?: number | null; cache_read_input_tokens?: number | null; cache_creation_input_tokens?: number | null } }): TokenUsage {\n const u = response.usage;\n if (!u) return {};\n const cached = u.cache_read_input_tokens ?? 0;\n const created = u.cache_creation_input_tokens ?? 0;\n return {\n inputTokens: (u.input_tokens ?? 0) + cached + created,\n outputTokens: u.output_tokens ?? 0,\n cachedInputTokens: cached,\n cacheCreationTokens: created,\n };\n}\n\nfunction requestError(error: unknown): LlmTransportError {\n if (error instanceof LlmTransportError) return error;\n if (error instanceof APIUserAbortError) return new LlmTransportError(\"request_failed\", \"Anthropic request was aborted.\");\n if (error instanceof APIConnectionTimeoutError) return new LlmTransportError(\"timeout\", \"Anthropic request timed out.\", { retryable: true });\n if (error instanceof APIConnectionError) return new LlmTransportError(\"request_failed\", \"Anthropic connection failed.\", { retryable: true, details: [error.message.slice(0, 500)] });\n if (error instanceof APIError) {\n const status = error.status ?? 0;\n const retryable = status === 408 || status === 429 || status >= 500;\n const code = status === 401 || status === 403 ? \"auth\" : status === 429 ? \"rate_limited\" : \"request_failed\";\n return new LlmTransportError(code, \"Anthropic request failed.\", { retryable, details: [`status: ${status}`, error.message.slice(0, 500)] });\n }\n const message = error instanceof Error ? error.message : String(error);\n return new LlmTransportError(\"request_failed\", \"Anthropic request failed.\", { details: [message.slice(0, 500)] });\n}\n\nexport class AnthropicModel implements LlmAdapter {\n private readonly client: Anthropic;\n\n constructor(\n private readonly provider: LlmProviderConfig,\n private readonly model: LlmModelConfig,\n apiKey: string,\n ) {\n const options: { apiKey: string; baseURL?: string } = { apiKey };\n if (provider.baseUrl) options.baseURL = provider.baseUrl;\n this.client = new Anthropic({ ...options, maxRetries: 0 });\n }\n\n private params(request: TextGenerationRequest): MessageCreateParamsNonStreaming {\n const params: MessageCreateParamsNonStreaming = {\n model: this.model.model,\n max_tokens: request.maxOutputTokens,\n stream: false,\n messages: [{ role: \"user\", content: request.user }],\n };\n if (request.system.trim()) params.system = request.system;\n if (this.model.thinkingBudgetTokens !== undefined) {\n params.thinking = { type: \"enabled\", budget_tokens: this.model.thinkingBudgetTokens };\n }\n return params;\n }\n\n async generateText(request: TextGenerationRequest): Promise<TextGenerationResponse> {\n const result = await withTransientRetry(this.provider.maxAttempts, async () => {\n try {\n const response = await this.client.messages.create(this.params(request), {\n timeout: this.provider.timeoutMs,\n signal: request.signal,\n });\n const usage = usageOf(response);\n if (response.stop_reason === \"max_tokens\") {\n throw new LlmTransportError(\"truncated\", \"Provider output was truncated.\", { usage });\n }\n if (response.stop_reason === \"refusal\") throw new LlmTransportError(\"content_filtered\", \"Provider filtered the response.\", { usage });\n const text = response.content\n .filter((block) => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\\n\")\n .trim();\n if (!text) throw new LlmTransportError(\"empty_response\", \"Provider returned an empty text response.\", { usage });\n return { text, finishReason: response.stop_reason ?? \"\", usage, raw: response };\n } catch (error) {\n throw requestError(error);\n }\n });\n return { ...result.value, attempts: result.attempts, usage: addTokenUsage(result.failedUsage, result.value.usage) };\n }\n\n async generateTool(request: ToolGenerationRequest): Promise<ToolGenerationResponse> {\n const result = await withTransientRetry(this.provider.maxAttempts, async () => {\n try {\n const tool: Tool = {\n name: request.tool.name,\n description: request.tool.description,\n input_schema: { type: \"object\", ...request.tool.inputSchema },\n };\n const response = await this.client.messages.create({\n ...this.params(request),\n tools: [tool],\n tool_choice: { type: \"tool\", name: request.tool.name, disable_parallel_tool_use: true },\n }, {\n timeout: this.provider.timeoutMs,\n signal: request.signal,\n });\n const usage = usageOf(response);\n if (response.stop_reason === \"max_tokens\") {\n throw new LlmTransportError(\"truncated\", \"Provider tool output was truncated.\", { usage });\n }\n if (response.stop_reason === \"refusal\") throw new LlmTransportError(\"content_filtered\", \"Provider filtered the response.\", { usage });\n const block = response.content.find((item) => item.type === \"tool_use\" && item.name === request.tool.name);\n if (!block || block.type !== \"tool_use\") {\n throw new LlmTransportError(\"invalid_response\", \"Provider did not return the required tool call.\", { usage });\n }\n return { input: block.input, finishReason: response.stop_reason ?? \"\", usage, raw: response };\n } catch (error) {\n throw requestError(error);\n }\n });\n return { ...result.value, attempts: result.attempts, usage: addTokenUsage(result.failedUsage, result.value.usage) };\n }\n}\n", "import {\n createOperationalFailure,\n type FailureClassification,\n type FailureContext,\n type OperationalFailure,\n} from \"../failures.js\";\n\nexport type LlmProtocol = \"anthropic\" | \"openai-compatible\" | \"google-gemini\";\n\nexport type LlmTaskId =\n | \"direct.episode-titles\"\n | \"direct.batch-extract\"\n | \"direct.episode-synopsis\"\n | \"direct.synopsis-reduction\"\n | \"direct.script-synopsis\"\n | \"direct.asset-grouping\"\n | \"direct.asset-curation\"\n | \"direct.asset-curation-audit\"\n | \"direct.location-canonicalization\"\n | \"direct.state-curation\"\n | \"direct.state-binding\"\n | \"metadata.global\"\n | \"metadata.descriptions\"\n | \"synopsis.chunk\"\n | \"synopsis.episode\"\n | \"synopsis.arc\"\n | \"synopsis.script-overview\"\n | \"ingest.body-start\"\n | \"ingest.arc-summary\"\n | \"ingest.text-normalize\"\n | \"ingest.episode-assets\"\n | \"ingest.name-fix\"\n | \"ingest.mention-resolve\"\n | \"ingest.asset-extract\"\n | \"ingest.asset-curate\"\n | \"ingest.asset-recall\"\n | \"ingest.asset-refine\"\n | \"ingest.state-reconcile\"\n | \"ingest.asset-audit\"\n | \"ingest.speaker-audit\"\n | \"ingest.video-serial\";\n\nexport type LlmTaskMode = \"text\" | \"tool\" | \"video\";\nexport type JsonSchema = Record<string, unknown>;\n\nexport interface TextGenerationRequest {\n system: string;\n user: string;\n maxOutputTokens: number;\n responseFormat?: \"json_object\";\n signal?: AbortSignal;\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: JsonSchema;\n}\n\nexport interface ToolGenerationRequest extends TextGenerationRequest {\n tool: ToolDefinition;\n}\n\n// Token counts extracted from the provider response. All optional: a provider (or\n// proxy) that doesn't return usage leaves these undefined, and the accounting treats\n// undefined as zero \u2014 never as an error.\nexport interface TokenUsage {\n inputTokens?: number; // total input (already includes the two cache buckets below)\n outputTokens?: number;\n cachedInputTokens?: number; // cache-read portion \u2014 a subset of inputTokens, billed cheap (~0.1x)\n cacheCreationTokens?: number; // cache-write portion \u2014 a subset of inputTokens, billed ~1.25x\n}\n\nexport interface TextGenerationResponse {\n text: string;\n finishReason: string;\n attempts: number;\n usage?: TokenUsage;\n raw?: unknown;\n}\n\nexport interface ToolGenerationResponse {\n input: unknown;\n finishReason: string;\n attempts: number;\n usage?: TokenUsage;\n raw?: unknown;\n}\n\nexport interface LlmAdapter {\n generateText(request: TextGenerationRequest): Promise<TextGenerationResponse>;\n generateTool(request: ToolGenerationRequest): Promise<ToolGenerationResponse>;\n}\n\n// Video understanding (\u00A710.5). A handle to an uploaded media file (Gemini Files\n// API): the remote resource is uploaded once and reused across passes. The URI\n// is ephemeral \u2014 it never enters manifests or fingerprints.\nexport interface VideoFileHandle {\n name: string; // Files API resource name, e.g. \"files/abc-123\"\n uri: string; // file URI for a fileData part\n mimeType: string;\n}\n\nexport type VideoUploadMode = \"file-api\" | \"base64\";\nexport const MAX_INLINE_VIDEO_BYTES = 100_000_000;\n\nexport type VideoMediaInput =\n | { kind: \"file-api\"; file: VideoFileHandle }\n | { kind: \"base64\"; data: string; mimeType: string }\n | {\n kind: \"local-fallback\";\n path: string;\n mimeType: string;\n primaryFailure: OperationalFailure;\n };\n\nexport type VideoProviderCredential =\n | { kind: \"literal\"; value: string }\n | { kind: \"env\"; name: string };\n\nexport interface VideoProviderOverrides {\n baseUrl?: string;\n apiKey?: VideoProviderCredential;\n model?: string;\n}\n\nexport interface LlmExecutorOptions {\n videoProvider?: VideoProviderOverrides;\n}\n\nexport interface VideoGenerationRequest {\n media: VideoMediaInput;\n system?: string;\n user: string;\n fps: number;\n maxOutputTokens: number;\n responseJsonSchema?: JsonSchema; // structured output (corrections)\n // Path to the local (transcoded) media on disk. The primary Gemini path ignores\n // this \u2014 it uses the already-uploaded `file` handle. A cross-provider fallback\n // (Doubao/Ark) can't reuse that handle, so it re-uploads this local file to its\n // own Files API. Present whenever the caller still holds the local file.\n localPath?: string;\n localMime?: string;\n signal?: AbortSignal;\n}\n\nexport interface VideoGenerationResponse {\n text: string;\n finishReason: string;\n attempts: number;\n usage?: TokenUsage;\n raw?: unknown;\n}\n\n// The Gemini adapter implements this port; it owns prepare/generate/release and\n// does not import ingest domain or construct business prompts (\u00A710.5, \u00A713).\nexport interface VideoUnderstandingPort {\n prepare(localPath: string, mimeType: string, mode: VideoUploadMode, signal?: AbortSignal): Promise<VideoMediaInput>;\n generate(request: VideoGenerationRequest): Promise<VideoGenerationResponse>;\n release(media: VideoMediaInput, signal?: AbortSignal): Promise<void>;\n}\n\n// A task-bound view of the video port: the executor injects the task's output\n// budget so callers omit maxOutputTokens (mirrors generateText(task, req)).\nexport interface TaskVideoPort {\n prepare(localPath: string, mimeType: string, mode: VideoUploadMode, signal?: AbortSignal): Promise<VideoMediaInput>;\n generate(request: Omit<VideoGenerationRequest, \"maxOutputTokens\">): Promise<VideoGenerationResponse>;\n release(media: VideoMediaInput, signal?: AbortSignal): Promise<void>;\n}\n\nexport interface LlmRouteInfo {\n task: LlmTaskId;\n profile: string;\n provider: string;\n protocol: LlmProtocol;\n baseUrl: string | null;\n model: string;\n fingerprint: string;\n}\n\nexport interface LlmRouteUsage extends LlmRouteInfo {\n calls: number;\n succeeded: number;\n failed: number;\n reused: number;\n attempts: number;\n durationMs: number;\n inputTokens: number;\n outputTokens: number;\n cachedInputTokens: number;\n cacheCreationTokens: number;\n}\n\nexport type LlmUsageStatus = \"succeeded\" | \"failed\" | \"reused\";\n\n// One immutable accounting event per routed model execution. Unlike `usage()`,\n// which is a convenience aggregate, this is the lossless source used by ingest's\n// streaming usage ledger. Fallback models carry their actual provider/model route.\nexport interface LlmUsageEvent extends LlmRouteInfo {\n sequence: number;\n status: LlmUsageStatus;\n attempts: number;\n startedAt: string;\n endedAt: string;\n durationMs: number;\n inputTokens: number;\n outputTokens: number;\n cachedInputTokens: number;\n cacheCreationTokens: number;\n errorCode?: LlmErrorCode;\n}\n\nexport interface LlmTaskExecutor {\n generateText(task: LlmTaskId, request: Omit<TextGenerationRequest, \"maxOutputTokens\">): Promise<TextGenerationResponse>;\n generateTool(task: LlmTaskId, request: Omit<ToolGenerationRequest, \"maxOutputTokens\">): Promise<ToolGenerationResponse>;\n videoPort(task: LlmTaskId): TaskVideoPort;\n route(task: LlmTaskId): LlmRouteInfo;\n routes(): LlmRouteInfo[];\n recordReuse(task: LlmTaskId): void;\n usage(): LlmRouteUsage[];\n usageEvents(): LlmUsageEvent[];\n readonly configSource: \"builtin\" | \"file\";\n}\n\nexport type LlmErrorCode =\n | \"auth\"\n | \"permission_denied\"\n | \"endpoint\"\n | \"network\"\n | \"timeout\"\n | \"rate_limited\"\n | \"request_failed\"\n | \"truncated\"\n | \"content_filtered\"\n | \"empty_response\"\n | \"invalid_response\"\n | \"cancelled\";\n\nfunction defaultFailureClassification(code: LlmErrorCode): FailureClassification {\n switch (code) {\n case \"auth\": return { failure_type: \"authentication\", failure_code: \"authentication_failed\" };\n case \"permission_denied\": return { failure_type: \"authorization\", failure_code: \"permission_denied\" };\n case \"endpoint\": return { failure_type: \"provider\", failure_code: \"resource_not_found\" };\n case \"network\": return { failure_type: \"network\", failure_code: \"network_failed\" };\n case \"timeout\": return { failure_type: \"timeout\", failure_code: \"request_timeout\" };\n case \"rate_limited\": return { failure_type: \"rate_limit\", failure_code: \"rate_limited\" };\n case \"request_failed\": return { failure_type: \"provider\", failure_code: \"request_rejected\" };\n case \"truncated\": return { failure_type: \"response\", failure_code: \"output_truncated\" };\n case \"content_filtered\": return { failure_type: \"policy\", failure_code: \"content_blocked\" };\n case \"empty_response\": return { failure_type: \"response\", failure_code: \"empty_response\" };\n case \"invalid_response\": return { failure_type: \"response\", failure_code: \"malformed_response\" };\n case \"cancelled\": return { failure_type: \"cancelled\", failure_code: \"cancelled\" };\n }\n}\n\nexport interface LlmTransportErrorOptions {\n retryable?: boolean;\n details?: string[];\n attempts?: number;\n usage?: TokenUsage;\n classification?: FailureClassification;\n context?: FailureContext;\n modelFailures?: OperationalFailure[];\n}\n\nexport class LlmTransportError extends Error {\n readonly code: LlmErrorCode;\n readonly retryable: boolean;\n readonly details: string[];\n readonly failure: OperationalFailure;\n readonly modelFailures: OperationalFailure[];\n attempts: number;\n usage: TokenUsage;\n\n constructor(code: LlmErrorCode, message: string, options: LlmTransportErrorOptions = {}) {\n super(message);\n this.name = \"LlmTransportError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.details = options.details ?? [];\n this.attempts = options.attempts ?? 1;\n this.usage = options.usage ?? {};\n this.failure = createOperationalFailure(\n options.classification ?? defaultFailureClassification(code),\n {\n retryable: this.retryable,\n message,\n ...options.context,\n ...(this.details.length > 0 ? { details: this.details } : {}),\n },\n );\n this.modelFailures = options.modelFailures ?? [];\n }\n}\n", "import { LlmTransportError, type TokenUsage } from \"../../llm/types.js\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface RetryResult<T> {\n value: T;\n attempts: number;\n failedUsage: TokenUsage;\n}\n\nexport function addTokenUsage(left: TokenUsage = {}, right: TokenUsage = {}): TokenUsage {\n const sum = (key: keyof TokenUsage): number | undefined =>\n left[key] === undefined && right[key] === undefined\n ? undefined\n : (left[key] ?? 0) + (right[key] ?? 0);\n const inputTokens = sum(\"inputTokens\");\n const outputTokens = sum(\"outputTokens\");\n const cachedInputTokens = sum(\"cachedInputTokens\");\n const cacheCreationTokens = sum(\"cacheCreationTokens\");\n return {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),\n ...(cacheCreationTokens !== undefined ? { cacheCreationTokens } : {}),\n };\n}\n\nexport async function withTransientRetry<T>(maxAttempts: number, operation: () => Promise<T>): Promise<RetryResult<T>> {\n let failedUsage: TokenUsage = {};\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n try {\n return { value: await operation(), attempts: attempt, failedUsage };\n } catch (error) {\n if (error instanceof LlmTransportError) {\n failedUsage = addTokenUsage(failedUsage, error.usage);\n error.attempts = attempt;\n error.usage = failedUsage;\n }\n if (!(error instanceof LlmTransportError) || !error.retryable || attempt === maxAttempts) throw error;\n // Exponential backoff (30s cap) \u2014 a shared LAN gateway under load needs the\n // retries spaced out, not hammered within a few seconds.\n await delay(Math.min(30_000, 1000 * 2 ** (attempt - 1)));\n }\n }\n throw new Error(\"unreachable retry state\");\n}\n", "// Doubao / Volcengine Ark video-understanding adapter \u2014 the LAST-resort fallback\n// after the Gemini model chain is exhausted (\u00A710.5). Ark is a different protocol:\n// the Files API sets sampling fps at UPLOAD time (preprocess_configs[video][fps]),\n// then the Responses API references the file by id. So this adapter can't fit the\n// upload/generate split of VideoUnderstandingPort cleanly \u2014 it exposes one\n// self-contained run(): upload the local transcode \u2192 poll ACTIVE \u2192 respond \u2192\n// best-effort delete. Transport only; it never builds business prompts. HTTP is\n// reached through a narrow structural client so tests inject a fake.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { File } from \"node:buffer\";\nimport { Agent, fetch, FormData } from \"undici\";\n\nimport {\n LlmTransportError,\n type JsonSchema,\n type TokenUsage,\n type VideoGenerationResponse,\n} from \"../../llm/types.js\";\nimport { httpError, httpStatusOf, networkError } from \"./failure-mapping.js\";\nimport { addTokenUsage, withTransientRetry } from \"./retry.js\";\n\n// Ark responses payload \u2014 the subset we read. output[] holds reasoning + message\n// items; message.content[].text (type output_text) is the answer. status is\n// \"completed\" | \"incomplete\" (incomplete_details.reason tells why).\nexport interface ArkResponse {\n status?: string;\n incomplete_details?: { reason?: string };\n output?: Array<{ type?: string; content?: Array<{ type?: string; text?: string }> }>;\n usage?: { input_tokens?: number; output_tokens?: number };\n}\n\nexport interface ArkFile {\n id?: string;\n status?: string; // processing | active | failed\n}\n\nexport interface ArkClient {\n uploadFile(params: { filePath: string; mimeType: string; fps: number }): Promise<ArkFile>;\n getFile(params: { id: string }): Promise<ArkFile>;\n createResponse(params: Record<string, unknown>, signal?: AbortSignal): Promise<ArkResponse>;\n deleteFile(params: { id: string }): Promise<void>;\n}\n\nconst POLL_INTERVAL_MS = 2000;\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// Map an SDK/HTTP error to a transport error with the shared retry policy: retry\n// only transient network/timeout/408/429/5xx.\nfunction toArkError(error: unknown, signal: AbortSignal | undefined, what: string, model: string): LlmTransportError {\n if (error instanceof LlmTransportError) return error;\n const message = error instanceof Error ? error.message : String(error);\n const status = httpStatusOf(error);\n const context = { provider: \"doubao\", model, operation: what };\n if (status !== null) {\n return httpError(status, `Doubao ${what} failed.`, message.slice(0, 500), context);\n }\n return networkError(error, signal, `Doubao ${what} failed.`, message.slice(0, 500), context);\n}\n\nfunction arkUsage(u: ArkResponse[\"usage\"]): TokenUsage {\n if (!u) return {};\n const num = (v: unknown): number | undefined => (typeof v === \"number\" ? v : undefined);\n return { inputTokens: num(u.input_tokens), outputTokens: num(u.output_tokens) };\n}\n\n// Concatenate every output_text across message items (reasoning items carry no\n// output_text, so they are naturally skipped).\nfunction extractText(res: ArkResponse): string {\n const parts: string[] = [];\n for (const item of res.output ?? []) {\n if (item.type !== \"message\") continue;\n for (const c of item.content ?? []) {\n if (c.type === \"output_text\" && typeof c.text === \"string\") parts.push(c.text);\n }\n }\n return parts.join(\"\").trim();\n}\n\nexport interface DoubaoRunRequest {\n localPath: string;\n localMime: string;\n system?: string;\n user: string;\n fps: number;\n maxOutputTokens: number;\n responseJsonSchema?: JsonSchema;\n signal?: AbortSignal;\n}\n\nexport class DoubaoVideoModel {\n private readonly client: ArkClient;\n\n constructor(\n private readonly model: string,\n private readonly timeoutMs: number,\n private readonly maxAttempts: number,\n apiKey: string,\n baseUrl: string,\n client?: ArkClient,\n ) {\n this.client = client ?? createArkClient(apiKey, baseUrl, timeoutMs);\n }\n\n // upload local transcode \u2192 poll ACTIVE \u2192 respond \u2192 best-effort delete.\n async run(request: DoubaoRunRequest): Promise<VideoGenerationResponse> {\n const { value: file } = await withTransientRetry(this.maxAttempts, async () => {\n try {\n return await this.client.uploadFile({ filePath: request.localPath, mimeType: request.localMime, fps: request.fps });\n } catch (error) {\n throw toArkError(error, request.signal, \"upload\", this.model);\n }\n });\n if (!file.id) throw new LlmTransportError(\"invalid_response\", \"Doubao upload returned no file id.\");\n const active = await this.pollActive(file.id, request.signal);\n try {\n return await this.generateOnce(active, request);\n } finally {\n await this.client.deleteFile({ id: active }).catch(() => {}); // cleanup is best-effort\n }\n }\n\n private async pollActive(id: string, signal?: AbortSignal): Promise<string> {\n const deadline = Date.now() + this.timeoutMs;\n let status = \"processing\";\n while (status === \"processing\" || status === \"\") {\n if (signal?.aborted) {\n throw new LlmTransportError(\"cancelled\", \"Doubao upload aborted.\", {\n context: { provider: \"doubao\", model: this.model, operation: \"file_poll\" },\n });\n }\n if (Date.now() >= deadline) {\n throw new LlmTransportError(\"timeout\", \"Doubao file processing timed out.\", {\n retryable: true,\n classification: { failure_type: \"timeout\", failure_code: \"media_processing_timeout\" },\n context: { provider: \"doubao\", model: this.model, operation: \"file_poll\" },\n });\n }\n await delay(POLL_INTERVAL_MS);\n let file: ArkFile;\n try {\n file = await this.client.getFile({ id });\n } catch (error) {\n throw toArkError(error, signal, \"file_poll\", this.model);\n }\n status = (file.status ?? \"\").toLowerCase();\n }\n if (status === \"failed\" || status === \"error\") {\n throw new LlmTransportError(\"invalid_response\", \"Doubao file processing failed.\", {\n classification: { failure_type: \"media\", failure_code: \"media_processing_failed\" },\n context: { provider: \"doubao\", model: this.model, operation: \"file_poll\" },\n });\n }\n return id;\n }\n\n private async generateOnce(fileId: string, request: DoubaoRunRequest): Promise<VideoGenerationResponse> {\n const params: Record<string, unknown> = {\n model: this.model,\n max_output_tokens: request.maxOutputTokens,\n input: [{ role: \"user\", content: [\n { type: \"input_video\", file_id: fileId },\n { type: \"input_text\", text: request.user },\n ] }],\n };\n if (request.system?.trim()) params[\"instructions\"] = request.system;\n if (request.responseJsonSchema) {\n params[\"text\"] = { format: { type: \"json_schema\", name: \"video_serial\", schema: request.responseJsonSchema } };\n }\n const { value, attempts, failedUsage } = await withTransientRetry(this.maxAttempts, async () => {\n let res: ArkResponse;\n try {\n res = await this.client.createResponse(params, request.signal);\n } catch (error) {\n throw toArkError(error, request.signal, \"generate\", this.model);\n }\n const status = (res.status ?? \"\").toLowerCase();\n const usage = arkUsage(res.usage);\n if (status === \"incomplete\") {\n const reason = res.incomplete_details?.reason ?? \"unknown\";\n if (reason === \"max_output_tokens\") throw new LlmTransportError(\"truncated\", \"Doubao output was truncated.\", { usage });\n throw new LlmTransportError(\"content_filtered\", `Doubao response incomplete (reason=${reason}).`, { usage });\n }\n const text = extractText(res);\n if (!text) throw new LlmTransportError(\"empty_response\", \"Doubao returned an empty response.\", { retryable: true, usage });\n if (request.responseJsonSchema) {\n try {\n JSON.parse(text);\n } catch {\n throw new LlmTransportError(\"invalid_response\", \"Doubao returned malformed JSON for a structured video response.\", {\n retryable: true,\n usage,\n context: { provider: \"doubao\", model: this.model, operation: \"generate\" },\n });\n }\n }\n return { text, usage, raw: res };\n });\n return { text: value.text, finishReason: \"STOP\", attempts, usage: addTokenUsage(failedUsage, value.usage), raw: value.raw };\n }\n}\n\n// Real HTTP client over the Ark REST API using global fetch (Node 18+). No SDK\n// dependency \u2014 the surface is tiny (4 calls) and multipart upload is trivial.\nclass HttpError extends Error {\n constructor(readonly status: number, message: string) { super(message); this.name = \"HttpError\"; }\n}\n\nfunction createArkClient(apiKey: string, baseUrl: string, timeoutMs: number): ArkClient {\n const root = baseUrl.replace(/\\/$/, \"\");\n const auth = { Authorization: `Bearer ${apiKey}` };\n // Node's global fetch uses Undici's 5-minute response-header timeout even\n // when the AbortSignal allows a longer model request. Ark video responses\n // can legitimately take longer, so keep the transport deadline aligned with\n // the provider timeout instead of failing every retry at exactly 5 minutes.\n const dispatcher = new Agent({ headersTimeout: timeoutMs, bodyTimeout: timeoutMs });\n\n function signalFor(extra?: AbortSignal): AbortSignal {\n const timeout = AbortSignal.timeout(timeoutMs);\n return extra ? AbortSignal.any([extra, timeout]) : timeout;\n }\n\n async function readError(res: Response): Promise<never> {\n const body = await res.text().catch(() => \"\");\n throw new HttpError(res.status, body.slice(0, 500));\n }\n\n return {\n async uploadFile({ filePath, mimeType, fps }) {\n const form = new FormData();\n const bytes = fs.readFileSync(filePath);\n form.append(\"file\", new File([bytes], path.basename(filePath), { type: mimeType }));\n form.append(\"purpose\", \"user_data\");\n form.append(\"preprocess_configs[video][fps]\", String(fps));\n const res = await fetch(`${root}/files`, { method: \"POST\", headers: auth, body: form, signal: signalFor(), dispatcher });\n if (!res.ok) await readError(res);\n return (await res.json()) as ArkFile;\n },\n async getFile({ id }) {\n const res = await fetch(`${root}/files/${id}`, { headers: auth, signal: signalFor(), dispatcher });\n if (!res.ok) await readError(res);\n return (await res.json()) as ArkFile;\n },\n async createResponse(params, signal) {\n const res = await fetch(`${root}/responses`, {\n method: \"POST\",\n headers: { ...auth, \"Content-Type\": \"application/json\" },\n body: JSON.stringify(params),\n signal: signalFor(signal),\n dispatcher,\n });\n if (!res.ok) await readError(res);\n return (await res.json()) as ArkResponse;\n },\n async deleteFile({ id }) {\n const res = await fetch(`${root}/files/${id}`, { method: \"DELETE\", headers: auth, signal: signalFor(), dispatcher });\n if (!res.ok) await readError(res);\n },\n };\n}\n", "import {\n type FailureClassification,\n type FailureContext,\n} from \"../../failures.js\";\nimport { LlmTransportError, type LlmErrorCode } from \"../../llm/types.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction errorChain(error: unknown): UnknownRecord[] {\n const chain: UnknownRecord[] = [];\n const seen = new Set<unknown>();\n let current: unknown = error;\n while (isRecord(current) && !seen.has(current)) {\n seen.add(current);\n chain.push(current);\n current = current[\"cause\"];\n }\n return chain;\n}\n\nexport function httpStatusOf(error: unknown): number | null {\n for (const item of errorChain(error)) {\n if (typeof item[\"status\"] === \"number\") return item[\"status\"];\n if (typeof item[\"statusCode\"] === \"number\") return item[\"statusCode\"];\n }\n return null;\n}\n\nexport function systemCodeOf(error: unknown): string | undefined {\n for (const item of errorChain(error)) {\n if (typeof item[\"code\"] === \"string\") return item[\"code\"];\n }\n return undefined;\n}\n\nfunction errorNameOf(error: unknown): string | undefined {\n for (const item of errorChain(error)) {\n if (typeof item[\"name\"] === \"string\") return item[\"name\"];\n }\n return undefined;\n}\n\nfunction isRequestTimeout(error: unknown): boolean {\n const name = errorNameOf(error);\n return name === \"AbortError\"\n || name === \"TimeoutError\"\n || name === \"RequestTimeoutError\"\n || name === \"APIConnectionTimeoutError\";\n}\n\nfunction networkClassification(systemCode: string | undefined): FailureClassification {\n if (!systemCode) return { failure_type: \"network\", failure_code: \"network_failed\" };\n if ([\"ENOTFOUND\", \"EAI_AGAIN\"].includes(systemCode)) {\n return { failure_type: \"network\", failure_code: \"dns_failed\" };\n }\n if (systemCode === \"ECONNREFUSED\") {\n return { failure_type: \"network\", failure_code: \"connection_refused\" };\n }\n if ([\"ECONNRESET\", \"EPIPE\", \"UND_ERR_SOCKET\"].includes(systemCode)) {\n return { failure_type: \"network\", failure_code: \"connection_reset\" };\n }\n if ([\"ENETUNREACH\", \"EHOSTUNREACH\"].includes(systemCode)) {\n return { failure_type: \"network\", failure_code: \"network_unreachable\" };\n }\n if (\n systemCode.startsWith(\"ERR_TLS_\")\n || systemCode.startsWith(\"ERR_SSL_\")\n || systemCode.startsWith(\"CERT_\")\n || [\"DEPTH_ZERO_SELF_SIGNED_CERT\", \"SELF_SIGNED_CERT_IN_CHAIN\", \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\"].includes(systemCode)\n ) {\n return { failure_type: \"network\", failure_code: \"tls_failed\" };\n }\n if ([\"ETIMEDOUT\", \"UND_ERR_CONNECT_TIMEOUT\"].includes(systemCode)) {\n return { failure_type: \"timeout\", failure_code: \"connect_timeout\" };\n }\n return { failure_type: \"network\", failure_code: \"network_failed\" };\n}\n\nexport function networkError(\n error: unknown,\n signal: AbortSignal | undefined,\n message: string,\n detail: string,\n context: FailureContext = {},\n): LlmTransportError {\n if (signal?.aborted) {\n return new LlmTransportError(\"cancelled\", message, {\n details: [detail],\n classification: { failure_type: \"cancelled\", failure_code: \"cancelled\" },\n context,\n });\n }\n const systemCode = systemCodeOf(error);\n const classification: FailureClassification = isRequestTimeout(error)\n ? { failure_type: \"timeout\", failure_code: \"request_timeout\" }\n : networkClassification(systemCode);\n const code: LlmErrorCode = classification.failure_type === \"timeout\" ? \"timeout\" : \"network\";\n return new LlmTransportError(code, message, {\n retryable: true,\n details: [detail],\n classification,\n context: { ...context, ...(systemCode ? { system_code: systemCode } : {}) },\n });\n}\n\nexport function httpError(\n status: number,\n message: string,\n detail: string,\n context: FailureContext = {},\n): LlmTransportError {\n let code: LlmErrorCode;\n let classification: FailureClassification;\n let retryable = false;\n if (status === 401) {\n code = \"auth\";\n classification = { failure_type: \"authentication\", failure_code: \"authentication_failed\" };\n } else if (status === 403) {\n code = \"permission_denied\";\n classification = { failure_type: \"authorization\", failure_code: \"permission_denied\" };\n } else if (status === 404) {\n code = \"endpoint\";\n classification = { failure_type: \"provider\", failure_code: \"resource_not_found\" };\n } else if (status === 408) {\n code = \"timeout\";\n classification = { failure_type: \"timeout\", failure_code: \"request_timeout\" };\n retryable = true;\n } else if (status === 413 && context.operation === \"upload\") {\n code = \"request_failed\";\n classification = { failure_type: \"media\", failure_code: \"media_too_large\" };\n } else if (status === 415 && context.operation === \"upload\") {\n code = \"request_failed\";\n classification = { failure_type: \"media\", failure_code: \"unsupported_media\" };\n } else if (status === 429) {\n code = \"rate_limited\";\n classification = { failure_type: \"rate_limit\", failure_code: \"rate_limited\" };\n retryable = true;\n } else if (status >= 500) {\n code = \"request_failed\";\n classification = { failure_type: \"provider\", failure_code: \"provider_unavailable\" };\n retryable = true;\n } else if (context.operation === \"upload\") {\n code = \"request_failed\";\n classification = { failure_type: \"media\", failure_code: \"media_upload_failed\" };\n } else {\n code = \"request_failed\";\n classification = { failure_type: \"provider\", failure_code: \"request_rejected\" };\n }\n return new LlmTransportError(code, message, {\n retryable,\n details: [`status: ${status}`, detail],\n classification,\n context: { ...context, http_status: status },\n });\n}\n", "// Gemini video-understanding adapter (\u00A710.5). Implements VideoUnderstandingPort\n// over the Files API: upload a media file once, poll to ACTIVE, generate against\n// the file reference (fps at the media-part level), and delete when done. The\n// adapter owns transport only \u2014 it never builds business prompts or imports the\n// ingest domain. The Google SDK is reached through a narrow structural client so\n// tests inject a fake and never hit the network.\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport type {\n Candidate,\n GenerateContentResponsePromptFeedback,\n GenerateContentResponseUsageMetadata,\n} from \"@google/genai\";\n\nimport {\n classificationOf,\n contextOf,\n type GeminiPolicyReason,\n type ProviderSafetyRating,\n} from \"../../failures.js\";\nimport type { LlmModelConfig, LlmProviderConfig } from \"../../llm/config.js\";\nimport {\n LlmTransportError,\n type VideoFileHandle,\n type VideoMediaInput,\n type VideoGenerationRequest,\n type VideoGenerationResponse,\n type VideoUnderstandingPort,\n type TokenUsage,\n} from \"../../llm/types.js\";\nimport { redactCredential, resumableUpload } from \"./gemini-upload.js\";\nimport { httpError, httpStatusOf, networkError } from \"./failure-mapping.js\";\nimport { addTokenUsage, withTransientRetry } from \"./retry.js\";\n\n// The subset of @google/genai we use. Kept structural so a fake client satisfies\n// it in tests without importing the SDK.\nexport interface GeminiFile {\n name?: string;\n uri?: string;\n mimeType?: string;\n state?: string;\n error?: { message?: string } | undefined;\n}\n\nexport interface GeminiGenerateResponse {\n text?: string;\n candidates?: Candidate[];\n promptFeedback?: GenerateContentResponsePromptFeedback;\n usageMetadata?: GenerateContentResponseUsageMetadata;\n}\n\n// finishReasons that yield empty text but are terminal: retry/resume never clears them.\nconst FILTERED_FINISH = new Set([\n \"SAFETY\",\n \"PROHIBITED_CONTENT\",\n \"RECITATION\",\n \"BLOCKLIST\",\n \"SPII\",\n \"IMAGE_SAFETY\",\n \"IMAGE_PROHIBITED_CONTENT\",\n \"IMAGE_RECITATION\",\n \"ESCALATION\",\n]);\n\nconst TERMINAL_RESPONSE_FINISH = new Set([\n \"LANGUAGE\",\n \"OTHER\",\n \"MALFORMED_FUNCTION_CALL\",\n \"IMAGE_OTHER\",\n \"NO_IMAGE\",\n \"UNEXPECTED_TOOL_CALL\",\n \"TOO_MANY_TOOL_CALLS\",\n \"MISSING_THOUGHT_SIGNATURE\",\n \"MALFORMED_RESPONSE\",\n]);\n\nfunction policyReason(raw: string): GeminiPolicyReason {\n switch (raw) {\n case \"SAFETY\":\n case \"PROHIBITED_CONTENT\":\n case \"BLOCKLIST\":\n case \"SPII\":\n case \"RECITATION\":\n case \"IMAGE_SAFETY\":\n case \"IMAGE_PROHIBITED_CONTENT\":\n case \"IMAGE_RECITATION\":\n case \"ESCALATION\":\n case \"OTHER\":\n return raw;\n case \"\":\n case \"BLOCK_REASON_UNSPECIFIED\":\n case \"FINISH_REASON_UNSPECIFIED\":\n return \"UNSPECIFIED\";\n default:\n return \"UNKNOWN\";\n }\n}\n\nfunction safetyRatings(\n values: Array<{ category?: string; probability?: string; blocked?: boolean }> | undefined,\n): ProviderSafetyRating[] | undefined {\n if (!values?.length) return undefined;\n return values.map((rating) => ({\n category: rating.category ?? \"UNSPECIFIED\",\n probability: rating.probability ?? \"UNSPECIFIED\",\n blocked: rating.blocked ?? false,\n }));\n}\n\n// Gemini reports usageMetadata.{promptTokenCount,candidatesTokenCount}. promptTokenCount\n// already includes the (large) video token count. Missing \u2192 undefined \u2192 counted as zero.\nfunction geminiUsage(meta: unknown): TokenUsage {\n if (typeof meta !== \"object\" || meta === null) return {};\n const m = meta as Record<string, unknown>;\n const num = (v: unknown): number | undefined => (typeof v === \"number\" ? v : undefined);\n return { inputTokens: num(m[\"promptTokenCount\"]), outputTokens: num(m[\"candidatesTokenCount\"]) };\n}\n\nexport interface GeminiClient {\n files: {\n upload(params: { file: string; config?: { mimeType?: string } }): Promise<GeminiFile>;\n get(params: { name: string }): Promise<GeminiFile>;\n delete(params: { name: string }): Promise<unknown>;\n };\n models: {\n generateContent(params: Record<string, unknown>): Promise<GeminiGenerateResponse>;\n generateContentStream?(params: Record<string, unknown>): Promise<AsyncIterable<GeminiGenerateResponse>>;\n };\n}\n\n// Poll cadence while an uploaded file is still PROCESSING. Overall budget is the\n// provider timeout; tests inject clients that return ACTIVE immediately.\nconst POLL_INTERVAL_MS = 2000;\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// Map an SDK/network error to a transport error with the same retry policy as\n// the other adapters: retry only transient network/timeout/408/429/5xx.\nfunction toTransportError(\n error: unknown,\n signal: AbortSignal | undefined,\n what: string,\n credential: string,\n provider: string,\n model: string,\n): LlmTransportError {\n if (error instanceof LlmTransportError) {\n return new LlmTransportError(error.code, redactCredential(error.message, credential), {\n retryable: error.retryable,\n details: error.details.map((detail) => redactCredential(detail, credential)),\n attempts: error.attempts,\n usage: error.usage,\n classification: classificationOf(error.failure),\n context: { ...contextOf(error.failure), provider, model, operation: what },\n modelFailures: error.modelFailures,\n });\n }\n const message = redactCredential(error instanceof Error ? error.message : String(error), credential);\n const status = httpStatusOf(error);\n const context = { provider, model, operation: what };\n if (status !== null) {\n return httpError(status, `Gemini ${what} failed.`, message.slice(0, 500), context);\n }\n return networkError(error, signal, `Gemini ${what} failed.`, message.slice(0, 500), context);\n}\n\nexport class GeminiVideoModel implements VideoUnderstandingPort {\n private readonly client: GeminiClient;\n\n constructor(\n private readonly provider: LlmProviderConfig,\n private readonly model: LlmModelConfig,\n private readonly apiKey: string,\n client?: GeminiClient,\n ) {\n this.client = client ?? createGoogleClient(apiKey, provider.timeoutMs, provider.baseUrl);\n }\n\n async prepare(\n localPath: string,\n mimeType: string,\n mode: \"file-api\" | \"base64\",\n signal?: AbortSignal,\n ): Promise<VideoMediaInput> {\n if (mode === \"base64\") {\n return { kind: \"base64\", data: fs.readFileSync(localPath, \"base64\"), mimeType };\n }\n const file = await this.uploadFile(localPath, mimeType, signal);\n return { kind: \"file-api\", file };\n }\n\n private async uploadFile(localPath: string, mimeType: string, signal?: AbortSignal): Promise<VideoFileHandle> {\n const { value: file } = await withTransientRetry(this.provider.maxAttempts, async () => {\n try {\n return await this.client.files.upload({ file: localPath, config: { mimeType } });\n } catch (error) {\n throw toTransportError(error, signal, \"upload\", this.apiKey, this.model.provider, this.model.model);\n }\n });\n const active = await this.pollActive(file, signal);\n if (!active.name || !active.uri) {\n throw new LlmTransportError(\"invalid_response\", \"Gemini upload returned no file reference.\", {\n context: { provider: this.model.provider, model: this.model.model, operation: \"upload\" },\n });\n }\n return { name: active.name, uri: active.uri, mimeType: active.mimeType ?? mimeType };\n }\n\n private async pollActive(initial: GeminiFile, signal?: AbortSignal): Promise<GeminiFile> {\n let file = initial;\n const deadline = Date.now() + this.provider.timeoutMs;\n // Media-processing failure is terminal \u2014 never retried (\u00A712.3).\n while ((file.state ?? \"\").toUpperCase() === \"PROCESSING\") {\n if (signal?.aborted) {\n throw new LlmTransportError(\"cancelled\", \"Gemini upload aborted.\", {\n context: { provider: this.model.provider, model: this.model.model, operation: \"file_poll\" },\n });\n }\n if (Date.now() >= deadline) {\n throw new LlmTransportError(\"timeout\", \"Gemini file processing timed out.\", {\n retryable: true,\n classification: { failure_type: \"timeout\", failure_code: \"media_processing_timeout\" },\n context: { provider: this.model.provider, model: this.model.model, operation: \"file_poll\" },\n });\n }\n await delay(POLL_INTERVAL_MS);\n if (!file.name) {\n throw new LlmTransportError(\"invalid_response\", \"Gemini upload returned no file name to poll.\", {\n context: { provider: this.model.provider, model: this.model.model, operation: \"file_poll\" },\n });\n }\n try {\n file = await this.client.files.get({ name: file.name });\n } catch (error) {\n throw toTransportError(error, signal, \"file_poll\", this.apiKey, this.model.provider, this.model.model);\n }\n }\n if ((file.state ?? \"\").toUpperCase() === \"FAILED\") {\n throw new LlmTransportError(\"invalid_response\", \"Gemini file processing failed.\", {\n details: [redactCredential(file.error?.message ?? \"unknown media error\", this.apiKey)],\n classification: { failure_type: \"media\", failure_code: \"media_processing_failed\" },\n context: { provider: this.model.provider, model: this.model.model, operation: \"file_poll\" },\n });\n }\n return file;\n }\n\n async generate(request: VideoGenerationRequest): Promise<VideoGenerationResponse> {\n if (request.media.kind === \"local-fallback\") {\n throw new LlmTransportError(\"invalid_response\", \"A local fallback video cannot be sent to Gemini.\");\n }\n const config: Record<string, unknown> = {\n // High media resolution reads small on-screen text (subtitles, name cards)\n // and fine visual anchors (\u00A710.3).\n mediaResolution: \"MEDIA_RESOLUTION_HIGH\",\n maxOutputTokens: request.maxOutputTokens,\n };\n if (request.system?.trim()) config[\"systemInstruction\"] = request.system;\n if (request.responseJsonSchema) {\n config[\"responseMimeType\"] = \"application/json\";\n config[\"responseJsonSchema\"] = request.responseJsonSchema;\n }\n const params: Record<string, unknown> = {\n model: this.model.model,\n contents: [{\n role: \"user\",\n parts: [\n request.media.kind === \"file-api\"\n ? { fileData: { fileUri: request.media.file.uri, mimeType: request.media.file.mimeType }, videoMetadata: { fps: request.fps } }\n : { inlineData: { data: request.media.data, mimeType: request.media.mimeType }, videoMetadata: { fps: request.fps } },\n { text: request.user },\n ],\n }],\n config,\n };\n\n const { value, attempts, failedUsage } = await withTransientRetry(this.provider.maxAttempts, async () => {\n let response: GeminiGenerateResponse;\n try {\n if (this.client.models.generateContentStream) {\n let text = \"\";\n let latest: GeminiGenerateResponse = {};\n const stream = await this.client.models.generateContentStream(params);\n for await (const chunk of stream) {\n if (chunk.text) text += chunk.text;\n latest = {\n ...latest,\n ...chunk,\n usageMetadata: chunk.usageMetadata ?? latest.usageMetadata,\n promptFeedback: chunk.promptFeedback ?? latest.promptFeedback,\n candidates: chunk.candidates ?? latest.candidates,\n };\n }\n response = { ...latest, text };\n } else {\n response = await this.client.models.generateContent(params);\n }\n } catch (error) {\n throw toTransportError(error, request.signal, \"generate\", this.apiKey, this.model.provider, this.model.model);\n }\n const candidate = response.candidates?.[0];\n const finishReason = candidate?.finishReason ?? \"\";\n const blockReason = response.promptFeedback?.blockReason ?? \"\";\n const usage = geminiUsage(response.usageMetadata);\n const baseContext = { provider: this.model.provider, model: this.model.model, operation: \"generate\" };\n if (finishReason === \"MAX_TOKENS\") {\n throw new LlmTransportError(\"truncated\", \"Gemini output was truncated.\", { usage, context: baseContext });\n }\n if (blockReason) {\n throw new LlmTransportError(\"content_filtered\", `Gemini blocked the prompt (blockReason=${blockReason}).`, {\n usage,\n classification: { failure_type: \"policy\", failure_code: \"content_blocked\" },\n context: {\n ...baseContext,\n provider_source: \"prompt\",\n provider_reason: policyReason(blockReason),\n ...(policyReason(blockReason) === \"UNKNOWN\" ? { provider_reason_raw: blockReason } : {}),\n safety_ratings: safetyRatings(response.promptFeedback?.safetyRatings),\n },\n });\n }\n if (FILTERED_FINISH.has(finishReason)) {\n throw new LlmTransportError(\"content_filtered\", `Gemini filtered the response (finishReason=${finishReason}).`, {\n usage,\n classification: { failure_type: \"policy\", failure_code: \"content_blocked\" },\n context: {\n ...baseContext,\n provider_source: \"candidate\",\n provider_reason: policyReason(finishReason),\n finish_message: candidate?.finishMessage,\n safety_ratings: safetyRatings(candidate?.safetyRatings),\n },\n });\n }\n const text = (response.text ?? \"\").trim();\n if (!text) {\n if (TERMINAL_RESPONSE_FINISH.has(finishReason)) {\n throw new LlmTransportError(\"invalid_response\", `Gemini returned no usable response (finishReason=${finishReason}).`, {\n usage,\n context: { ...baseContext, provider_reason_raw: finishReason, finish_message: candidate?.finishMessage },\n });\n }\n // Empty body with a normal/blank finishReason is a transient generation hiccup\n // (observed ~1/15 episodes); retry it \u2014 a resume of the same episode succeeds.\n throw new LlmTransportError(\"empty_response\", `Gemini returned an empty response (finishReason=${finishReason || \"none\"}).`, {\n retryable: true,\n usage,\n context: baseContext,\n });\n }\n if (request.responseJsonSchema) {\n try {\n JSON.parse(text);\n } catch {\n throw new LlmTransportError(\"invalid_response\", \"Gemini returned malformed JSON for a structured video response.\", {\n retryable: true,\n usage,\n context: baseContext,\n });\n }\n }\n return { text, finishReason, usage, raw: response };\n });\n return { text: value.text, finishReason: value.finishReason, attempts, usage: addTokenUsage(failedUsage, value.usage), raw: value.raw };\n }\n\n async release(media: VideoMediaInput, signal?: AbortSignal): Promise<void> {\n if (media.kind === \"base64\" || media.kind === \"local-fallback\") return;\n try {\n await this.client.files.delete({ name: media.file.name });\n } catch (error) {\n // Cleanup is best-effort (\u00A710.5); a failed delete must not fail the run.\n void error;\n void signal;\n }\n }\n}\n\n// Lazily import the SDK so the dependency is only loaded when a video route is\n// actually exercised (keeps text-only runs free of @google/genai).\nconst require = createRequire(import.meta.url);\nfunction createGoogleClient(apiKey: string, timeoutMs: number, baseUrl: string | null): GeminiClient {\n const { GoogleGenAI } = require(\"@google/genai\") as typeof import(\"@google/genai\");\n const sdk = new GoogleGenAI({\n apiKey,\n ...(baseUrl ? { httpOptions: { baseUrl, timeout: timeoutMs } } : {}),\n }) as unknown as {\n files: { get(p: { name: string }): Promise<GeminiFile>; delete(p: { name: string }): Promise<unknown> };\n models: {\n generateContent(p: Record<string, unknown>): Promise<GeminiGenerateResponse>;\n generateContentStream(p: Record<string, unknown>): Promise<AsyncIterable<GeminiGenerateResponse>>;\n };\n };\n const proxyUrl = (process.env.https_proxy ?? process.env.HTTPS_PROXY ?? process.env.http_proxy ?? process.env.HTTP_PROXY ?? \"\").trim();\n // A proxy is set but Node's built-in fetch (which the SDK's get/delete/generate\n // use) ignores https_proxy unless NODE_USE_ENV_PROXY=1 \u2014 so upload (our proxied\n // https) succeeds and the very next poll fails with \"file poll failed\". Warn\n // once with the exact fix rather than let it look like a network error.\n if (proxyUrl && !(process.env.NODE_USE_ENV_PROXY ?? \"\").trim()) {\n process.stderr.write(\n `\u26A0\uFE0F \u68C0\u6D4B\u5230\u4EE3\u7406 ${proxyUrl}\uFF0C\u4F46\u672A\u8BBE NODE_USE_ENV_PROXY=1\u3002\\n` +\n ` Gemini \u4E0A\u4F20\u4F1A\u6210\u529F\u3001\u968F\u540E\u7684\u6587\u4EF6\u8F6E\u8BE2/\u751F\u6210\u4F1A\u6302\uFF08Node \u5185\u7F6E fetch \u9ED8\u8BA4\u4E0D\u8D70\u4EE3\u7406\uFF09\u3002\\n` +\n ` \u8BF7\u5728\u547D\u4EE4\u524D\u52A0 NODE_USE_ENV_PROXY=1 \u91CD\u8DD1\u3002\\n`,\n );\n }\n // upload goes through Node https (undici rejects the resumable response's\n // content-length behind a proxy); get/delete/generateContent use the SDK.\n return {\n files: {\n upload: (p) => resumableUpload({\n apiKey,\n filePath: p.file,\n mimeType: p.config?.mimeType ?? \"video/mp4\",\n timeoutMs,\n proxyUrl,\n baseUrl,\n }),\n get: (p) => sdk.files.get(p),\n delete: (p) => sdk.files.delete(p),\n },\n models: {\n generateContent: (p) => sdk.models.generateContent(p),\n generateContentStream: (p) => sdk.models.generateContentStream(p),\n },\n };\n}\n", "// Gemini Files API resumable upload over Node's built-in https (not undici).\n// undici's strict content-length parser rejects the resumable-upload response\n// when it traverses a local HTTP proxy (Clash) with \"invalid content-length\n// header\"; Node's https parser is lenient and works. Only the upload step needs\n// this \u2014 files.get/delete and generateContent are plain requests the SDK's fetch\n// handles fine. The file body is streamed (never fully buffered).\n\nimport * as fs from \"node:fs\";\nimport * as http from \"node:http\";\nimport * as https from \"node:https\";\n\nimport { HttpsProxyAgent } from \"https-proxy-agent\";\n\nimport { LlmTransportError } from \"../../llm/types.js\";\nimport { httpError, networkError } from \"./failure-mapping.js\";\nimport type { GeminiFile } from \"./gemini-video-model.js\";\n\nconst DEFAULT_BASE_URL = \"https://generativelanguage.googleapis.com\";\n\nexport function geminiUploadStartUrl(baseUrl: string | null | undefined, apiKey: string): URL {\n const root = new URL(baseUrl ?? DEFAULT_BASE_URL);\n root.pathname = `${root.pathname.replace(/\\/+$/, \"\")}/upload/v1beta/files`;\n root.searchParams.set(\"key\", apiKey);\n return root;\n}\n\nexport function geminiUploadTransferUrl(uploadUrl: string, baseUrl: string | null | undefined): URL {\n const root = new URL(baseUrl ?? DEFAULT_BASE_URL);\n const transfer = new URL(uploadUrl, root);\n if (!baseUrl) return transfer;\n\n transfer.protocol = root.protocol;\n transfer.host = root.host;\n const rootPath = root.pathname.replace(/\\/+$/, \"\");\n if (rootPath && transfer.pathname !== rootPath && !transfer.pathname.startsWith(`${rootPath}/`)) {\n transfer.pathname = `${rootPath}/${transfer.pathname.replace(/^\\/+/, \"\")}`;\n }\n return transfer;\n}\n\nexport function redactCredential(value: string, credential: string): string {\n if (!credential) return value;\n let redacted = value.split(credential).join(\"[REDACTED]\");\n const encoded = encodeURIComponent(credential);\n if (encoded !== credential) redacted = redacted.split(encoded).join(\"[REDACTED]\");\n return redacted;\n}\n\nfunction proxyAgent(proxyUrl: string): https.Agent | undefined {\n return proxyUrl ? (new HttpsProxyAgent(proxyUrl) as unknown as https.Agent) : undefined;\n}\n\ninterface RawResponse { status: number; headers: Record<string, string | string[] | undefined>; body: string }\n\nfunction request(\n target: URL,\n opts: Omit<https.RequestOptions, \"host\" | \"path\" | \"protocol\">,\n body: Buffer | fs.ReadStream | string | null,\n signal?: AbortSignal,\n): Promise<RawResponse> {\n return new Promise((resolve, reject) => {\n const transport = target.protocol === \"http:\" ? http : https;\n const req = transport.request({\n ...opts,\n agent: target.protocol === \"https:\" ? opts.agent : undefined,\n protocol: target.protocol,\n hostname: target.hostname,\n port: target.port || undefined,\n path: `${target.pathname}${target.search}`,\n }, (res) => {\n let data = \"\";\n res.on(\"data\", (c) => (data += c));\n res.on(\"end\", () => resolve({ status: res.statusCode ?? 0, headers: res.headers, body: data }));\n });\n req.on(\"error\", reject);\n if (signal) {\n if (signal.aborted) { req.destroy(new Error(\"aborted\")); return; }\n signal.addEventListener(\"abort\", () => req.destroy(new Error(\"aborted\")), { once: true });\n }\n if (body && typeof (body as fs.ReadStream).pipe === \"function\") (body as fs.ReadStream).pipe(req);\n else { if (body) req.write(body); req.end(); }\n });\n}\n\nfunction header(h: RawResponse[\"headers\"], name: string): string {\n const v = h[name];\n return Array.isArray(v) ? (v[0] ?? \"\") : (v ?? \"\");\n}\n\nexport async function resumableUpload(params: {\n apiKey: string;\n filePath: string;\n mimeType: string;\n timeoutMs: number;\n proxyUrl?: string;\n baseUrl?: string | null;\n signal?: AbortSignal;\n}): Promise<GeminiFile> {\n const size = fs.statSync(params.filePath).size;\n const agent = proxyAgent(params.proxyUrl ?? \"\");\n const common = { agent, timeout: params.timeoutMs } as const;\n const root = geminiUploadStartUrl(params.baseUrl, params.apiKey);\n const safe = (value: string): string => redactCredential(value, params.apiKey);\n\n let start: RawResponse;\n try {\n start = await request(root, {\n ...common, method: \"POST\",\n headers: {\n \"X-Goog-Upload-Protocol\": \"resumable\", \"X-Goog-Upload-Command\": \"start\",\n \"X-Goog-Upload-Header-Content-Length\": String(size), \"X-Goog-Upload-Header-Content-Type\": params.mimeType,\n \"Content-Type\": \"application/json\",\n },\n }, JSON.stringify({ file: {} }), params.signal);\n } catch (e) {\n const detail = safe(e instanceof Error ? e.message : String(e));\n throw networkError(e, params.signal, \"Gemini upload start failed.\", detail, { operation: \"upload\" });\n }\n const uploadUrl = header(start.headers, \"x-goog-upload-url\");\n if (start.status < 200 || start.status >= 300) {\n throw httpError(start.status, \"Gemini upload start failed.\", safe(start.body).slice(0, 300), { operation: \"upload\" });\n }\n if (!uploadUrl) {\n throw new LlmTransportError(\"invalid_response\", \"Gemini upload start returned no upload URL.\", {\n details: [safe(start.body).slice(0, 300)],\n context: { operation: \"upload\", http_status: start.status },\n });\n }\n\n const u = geminiUploadTransferUrl(uploadUrl, params.baseUrl);\n let up: RawResponse;\n try {\n up = await request(u, {\n ...common, method: \"POST\",\n headers: { \"Content-Length\": String(size), \"X-Goog-Upload-Offset\": \"0\", \"X-Goog-Upload-Command\": \"upload, finalize\" },\n }, fs.createReadStream(params.filePath), params.signal);\n } catch (e) {\n const detail = safe(e instanceof Error ? e.message : String(e));\n throw networkError(e, params.signal, \"Gemini upload transfer failed.\", detail, { operation: \"upload\" });\n }\n if (up.status < 200 || up.status >= 300) {\n throw httpError(up.status, \"Gemini upload transfer failed.\", safe(up.body).slice(0, 300), { operation: \"upload\" });\n }\n let parsed: { file?: GeminiFile };\n try { parsed = JSON.parse(up.body) as { file?: GeminiFile }; } catch { throw new LlmTransportError(\"invalid_response\", \"Gemini upload returned invalid JSON.\", { details: [safe(up.body).slice(0, 300)] }); }\n if (!parsed.file) throw new LlmTransportError(\"invalid_response\", \"Gemini upload returned no file.\", { details: [safe(up.body).slice(0, 300)] });\n return parsed.file;\n}\n", "import type { LlmModelConfig, LlmProviderConfig } from \"../../llm/config.js\";\nimport {\n LlmTransportError,\n type LlmAdapter,\n type TextGenerationRequest,\n type TextGenerationResponse,\n type ToolGenerationRequest,\n type ToolGenerationResponse,\n type TokenUsage,\n} from \"../../llm/types.js\";\nimport { addTokenUsage, withTransientRetry } from \"./retry.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\n// Token accounting from an OpenAI-shaped usage object. IMPORTANT: our gateway\n// (LiteLLM/aihubmix fronting Anthropic) reports Anthropic-style semantics through\n// OpenAI-shaped fields \u2014 prompt_tokens is FRESH (non-cached) input only, and\n// cached_tokens / cache_creation_tokens are SEPARATE additive buckets (verified: a\n// response with prompt_tokens=48 carried cached_tokens=640, impossible under a subset\n// model). So total input = prompt_tokens + cached + creation. cached/creation are then\n// reported as subsets of that total (matching TokenUsage's contract), so downstream\n// can price the cheap cache-read and pricey cache-creation portions separately.\n// (A true OpenAI endpoint folds cached into prompt_tokens; if we ever add one, gate on\n// provider protocol here. Today every profile routes through the Anthropic-style gateway.)\nfunction usageOf(payload: unknown): TokenUsage {\n if (!isRecord(payload) || !isRecord(payload[\"usage\"])) return {};\n const u = payload[\"usage\"];\n const num = (v: unknown): number => {\n const n = typeof v === \"number\" ? v : 0;\n return Number.isFinite(n) ? n : 0;\n };\n const details = isRecord(u[\"prompt_tokens_details\"]) ? u[\"prompt_tokens_details\"] : {};\n const fresh = num(u[\"prompt_tokens\"]);\n const cached = num(details[\"cached_tokens\"]) || num(u[\"cache_read_input_tokens\"]);\n const created = num(details[\"cache_creation_tokens\"]) || num(u[\"cache_creation_input_tokens\"]);\n return {\n inputTokens: fresh + cached + created,\n outputTokens: num(u[\"completion_tokens\"]),\n cachedInputTokens: cached,\n cacheCreationTokens: created,\n };\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction endpoint(baseUrl: string): string {\n const base = baseUrl.trim().replace(/\\/+$/, \"\");\n if (base.endsWith(\"/chat/completions\")) return base;\n if (base.endsWith(\"/v1\")) return `${base}/chat/completions`;\n return `${base}/v1/chat/completions`;\n}\n\nfunction firstChoice(payload: unknown): UnknownRecord | null {\n if (!isRecord(payload) || !Array.isArray(payload[\"choices\"])) return null;\n return payload[\"choices\"].find(isRecord) ?? null;\n}\n\nfunction finishReason(choice: UnknownRecord | null): string {\n return choice && typeof choice[\"finish_reason\"] === \"string\" ? choice[\"finish_reason\"] : \"\";\n}\n\nfunction message(choice: UnknownRecord | null): UnknownRecord | null {\n return choice && isRecord(choice[\"message\"]) ? choice[\"message\"] : null;\n}\n\nfunction messageText(choice: UnknownRecord | null): string {\n const content = message(choice)?.[\"content\"];\n if (typeof content === \"string\") return content.trim();\n if (!Array.isArray(content)) return \"\";\n return content.flatMap((part) => isRecord(part) && typeof part[\"text\"] === \"string\" ? [part[\"text\"]] : []).join(\"\\n\").trim();\n}\n\nfunction parseJson(raw: string): unknown {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new LlmTransportError(\"invalid_response\", \"Provider returned invalid JSON.\", { details: [raw.slice(0, 500)] });\n }\n}\n\nexport class OpenAiCompatibleModel implements LlmAdapter {\n private readonly url: string;\n private readonly host: string;\n\n constructor(\n private readonly provider: LlmProviderConfig,\n private readonly model: LlmModelConfig,\n private readonly apiKey: string,\n ) {\n // A null baseUrl means the endpoint env var never resolved (the built-in\n // `gw` provider reads PROJECT_LITELLM_GATEWAY_BASE_URL). Name it so the\n // failure is self-diagnosing instead of a generic \"request failed\".\n if (!provider.baseUrl) {\n throw new LlmTransportError(\"endpoint\", \"OpenAI-compatible provider endpoint (baseUrl) is not set \u2014 the built-in gateway reads PROJECT_LITELLM_GATEWAY_BASE_URL.\");\n }\n this.url = endpoint(provider.baseUrl);\n try {\n this.host = new URL(this.url).host;\n } catch {\n this.host = this.url;\n }\n }\n\n private async post(body: UnknownRecord, signal?: AbortSignal): Promise<{ payload: unknown; attempts: number; failedUsage: TokenUsage }> {\n const result = await withTransientRetry(this.provider.maxAttempts, async () => {\n const timeoutSignal = AbortSignal.timeout(this.provider.timeoutMs);\n const combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;\n let response: Response;\n try {\n response = await fetch(this.url, {\n method: \"POST\",\n headers: { authorization: `Bearer ${this.apiKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: combinedSignal,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const timeout = combinedSignal.aborted && !signal?.aborted;\n // Put the transport cause + endpoint host in the MESSAGE (not just\n // redacted details) so it survives into the per-unit error sidecar and\n // the agent can tell \"host unreachable\" from \"auth\" without debug mode.\n // The network message and host are not secrets; the api key never is.\n throw new LlmTransportError(\n timeout ? \"timeout\" : \"request_failed\",\n timeout\n ? `OpenAI-compatible request timed out reaching ${this.host}.`\n : `OpenAI-compatible request could not reach ${this.host}: ${message}`,\n { retryable: !signal?.aborted, details: [message.slice(0, 500)] },\n );\n }\n const raw = await response.text();\n if (!response.ok) {\n const retryable = response.status === 408 || response.status === 429 || response.status >= 500;\n const code = response.status === 401 || response.status === 403 ? \"auth\" : response.status === 429 ? \"rate_limited\" : \"request_failed\";\n throw new LlmTransportError(code, `OpenAI-compatible request to ${this.host} failed (status ${response.status}).`, {\n retryable,\n details: [`status: ${response.status}`, raw.slice(0, 500)],\n });\n }\n return parseJson(raw);\n });\n return { payload: result.value, attempts: result.attempts, failedUsage: result.failedUsage };\n }\n\n private baseBody(request: TextGenerationRequest): UnknownRecord {\n const messages: Array<{ role: \"system\" | \"user\"; content: string }> = [];\n if (request.system.trim()) messages.push({ role: \"system\", content: request.system });\n messages.push({ role: \"user\", content: request.user });\n return {\n model: this.model.model,\n messages,\n ...(request.responseFormat === \"json_object\" ? { response_format: { type: \"json_object\" } } : {}),\n ...(this.model.reasoning ? { reasoning_effort: this.model.reasoning } : {}),\n ...(this.model.temperature !== undefined ? { temperature: this.model.temperature } : {}),\n };\n }\n\n async generateText(request: TextGenerationRequest): Promise<TextGenerationResponse> {\n const { payload, attempts, failedUsage } = await this.post(this.baseBody(request), request.signal);\n const usage = addTokenUsage(failedUsage, usageOf(payload));\n try {\n const choice = firstChoice(payload);\n const reason = finishReason(choice);\n if (reason === \"length\") throw new LlmTransportError(\"truncated\", \"Provider output was truncated.\");\n if (reason === \"content_filter\") throw new LlmTransportError(\"content_filtered\", \"Provider filtered the response.\");\n const text = messageText(choice);\n if (!text) throw new LlmTransportError(\"empty_response\", \"Provider returned an empty text response.\");\n return { text, finishReason: reason, attempts, usage, raw: payload };\n } catch (error) {\n if (error instanceof LlmTransportError) {\n error.attempts = attempts;\n error.usage = usage;\n }\n throw error;\n }\n }\n\n async generateTool(request: ToolGenerationRequest): Promise<ToolGenerationResponse> {\n const { payload, attempts, failedUsage } = await this.post({\n ...this.baseBody(request),\n tools: [{\n type: \"function\",\n function: { name: request.tool.name, description: request.tool.description, parameters: request.tool.inputSchema },\n }],\n tool_choice: { type: \"function\", function: { name: request.tool.name } },\n parallel_tool_calls: false,\n }, request.signal);\n const usage = addTokenUsage(failedUsage, usageOf(payload));\n try {\n const choice = firstChoice(payload);\n const reason = finishReason(choice);\n if (reason === \"length\") throw new LlmTransportError(\"truncated\", \"Provider tool output was truncated.\");\n if (reason === \"content_filter\") throw new LlmTransportError(\"content_filtered\", \"Provider filtered the response.\");\n const calls = message(choice)?.[\"tool_calls\"];\n if (!Array.isArray(calls)) throw new LlmTransportError(\"invalid_response\", \"Provider did not return a tool call.\");\n for (const call of calls) {\n if (!isRecord(call) || !isRecord(call[\"function\"])) continue;\n const fn = call[\"function\"];\n if (fn[\"name\"] !== request.tool.name || typeof fn[\"arguments\"] !== \"string\") continue;\n return { input: parseJson(fn[\"arguments\"]), finishReason: reason, attempts, usage, raw: payload };\n }\n throw new LlmTransportError(\"invalid_response\", \"Provider did not return the required tool call.\");\n } catch (error) {\n if (error instanceof LlmTransportError) {\n error.attempts = attempts;\n error.usage = usage;\n }\n throw error;\n }\n }\n}\n", "import { spawn } from \"node:child_process\";\n\nimport { CliError, EXIT_OK, EXIT_RUNTIME, type CommandOutput } from \"../common.js\";\nimport { packageVersion } from \"../package-root.js\";\n\nconst UPDATE_PACKAGE = \"@lingjingai/scriptctl\";\nconst UPDATE_LATEST_SPEC = `${UPDATE_PACKAGE}@latest`;\nconst UPDATE_COMMAND = \"npm\";\n\nfunction readInstalledVersion(): string {\n return packageVersion();\n}\n\nexport function patchPackageSpec(version: string): string | null {\n const match = /^(\\d+)\\.(\\d+)\\.\\d+/.exec(version);\n if (!match) return null;\n return `${UPDATE_PACKAGE}@~${match[1]}.${match[2]}.0`;\n}\n\nfunction updateArgs(packageSpec: string): readonly string[] {\n return [\"install\", \"-g\", packageSpec];\n}\n\nexport interface UpdateRunResult {\n exitCode: number | null;\n signal: NodeJS.Signals | null;\n stdout: string;\n stderr: string;\n error?: Error;\n}\n\nexport type UpdateRunner = (\n command: string,\n args: readonly string[],\n) => Promise<UpdateRunResult>;\n\nexport type InstalledVersionReader = () => string;\n\nfunction commandLine(command: string, args: readonly string[]): string {\n return [command, ...args].join(\" \");\n}\n\nfunction nonEmptyTail(text: string, count: number): string[] {\n const lines = text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n return lines.slice(-count);\n}\n\nexport function runUpdateCommand(command: string, args: readonly string[]): Promise<UpdateRunResult> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const stdout: string[] = [];\n const stderr: string[] = [];\n child.stdout.setEncoding(\"utf-8\");\n child.stderr.setEncoding(\"utf-8\");\n child.stdout.on(\"data\", (chunk: string) => stdout.push(chunk));\n child.stderr.on(\"data\", (chunk: string) => stderr.push(chunk));\n child.once(\"error\", (error) => {\n resolve({\n exitCode: null,\n signal: null,\n stdout: stdout.join(\"\"),\n stderr: stderr.join(\"\"),\n error,\n });\n });\n child.once(\"close\", (exitCode, signal) => {\n resolve({\n exitCode,\n signal,\n stdout: stdout.join(\"\"),\n stderr: stderr.join(\"\"),\n });\n });\n });\n}\n\nexport async function commandUpdate(\n opts: Record<string, unknown>,\n runner: UpdateRunner = runUpdateCommand,\n readVersion: InstalledVersionReader = readInstalledVersion,\n): Promise<[CommandOutput, number]> {\n const patch = Boolean(opts[\"patch\"]);\n const currentVersion = readVersion();\n const packageSpec = patch\n ? patchPackageSpec(currentVersion)\n : UPDATE_LATEST_SPEC;\n if (!packageSpec) {\n throw new CliError(`Cannot compute a patch update range from version ${currentVersion}.`, {\n exitCode: EXIT_RUNTIME,\n errorCode: \"UPDATE_VERSION_INVALID\",\n hint: \"Run `scriptctl update` without --patch to install the latest version.\",\n data: { version: currentVersion },\n });\n }\n const args = [...updateArgs(packageSpec)];\n const line = commandLine(UPDATE_COMMAND, args);\n const update = {\n package: UPDATE_PACKAGE,\n package_spec: packageSpec,\n command: UPDATE_COMMAND,\n args,\n command_line: line,\n };\n\n if (Boolean(opts[\"dry_run\"])) {\n return [{\n text: [\n `package: ${UPDATE_PACKAGE}`,\n `command: ${line}`,\n \"dry-run: no update performed\",\n ].join(\"\\n\"),\n data: { op: \"update\", changed: false, update },\n }, EXIT_OK];\n }\n\n const result = await runner(UPDATE_COMMAND, args);\n if (result.error) {\n throw new CliError(`Failed to start npm: ${result.error.message}`, {\n exitCode: EXIT_RUNTIME,\n errorCode: \"UPDATE_SPAWN_FAILED\",\n hint: `Run '${line}' after fixing the npm installation.`,\n data: { update, cause: result.error.message },\n });\n }\n\n if (result.exitCode !== EXIT_OK) {\n const issues = [\n `exit: ${result.exitCode === null ? `signal ${result.signal ?? \"unknown\"}` : String(result.exitCode)}`,\n ...nonEmptyTail(result.stderr, 5).map((line) => `stderr: ${line}`),\n ];\n throw new CliError(\"npm could not update scriptctl.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"UPDATE_COMMAND_FAILED\",\n hint: `Run '${line}' after resolving the npm error.`,\n data: { update, actual: issues },\n });\n }\n\n const installedVersion = readVersion();\n const changed = installedVersion !== currentVersion;\n return [{\n text: changed\n ? `Updated ${currentVersion} \u2192 ${installedVersion}.`\n : `Already up to date (${installedVersion}).`,\n data: {\n op: \"update\",\n changed,\n status: changed ? \"updated\" : \"already_latest\",\n previous_version: currentVersion,\n version: installedVersion,\n },\n }, EXIT_OK];\n}\n", "import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport lockfile from \"proper-lockfile\";\n\nimport { CliError, EXIT_INPUT, EXIT_RUNTIME } from \"../common.js\";\n\nexport interface WorkingCopyMetadata {\n schemaVersion: 1;\n projectGroupNo: string;\n apiBaseUrl: string;\n baseRevision: number;\n baseContentHash: string;\n}\n\nexport interface WorkingCopyPaths {\n scriptPath: string;\n stateDir: string;\n metadataPath: string;\n lockPath: string;\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalize);\n if (value !== null && typeof value === \"object\") {\n const source = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(source).sort()) result[key] = canonicalize(source[key]);\n return result;\n }\n return value;\n}\n\nexport function semanticScriptHash(script: unknown): string {\n const canonical = JSON.stringify(canonicalize(script));\n return `sha256:${crypto.createHash(\"sha256\").update(canonical).digest(\"hex\")}`;\n}\n\nexport function localFileFingerprint(filePath: string): string | null {\n if (!fs.existsSync(filePath)) return null;\n return `sha256:${crypto.createHash(\"sha256\").update(fs.readFileSync(filePath)).digest(\"hex\")}`;\n}\n\nexport function assertLocalFileFingerprint(filePath: string, expected: string | null): void {\n const current = localFileFingerprint(filePath);\n if (current === expected) return;\n throw new CliError(\"The local script changed while the command was running.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"LOCAL_SCRIPT_CHANGED\",\n hint: \"Read the latest local script and retry the command.\",\n data: { actual: [`loadedFingerprint=${expected ?? \"<missing>\"}`, `currentFingerprint=${current ?? \"<missing>\"}`, filePath] },\n });\n}\n\nexport function workingCopyPaths(rawScriptPath: string): WorkingCopyPaths {\n const scriptPath = path.resolve(rawScriptPath);\n const stateDir = path.join(path.dirname(scriptPath), \".scriptctl\");\n const name = path.basename(scriptPath);\n return {\n scriptPath,\n stateDir,\n metadataPath: path.join(stateDir, `${name}.working-copy.json`),\n lockPath: path.join(stateDir, name),\n };\n}\n\nexport async function withScriptFileLock<T>(rawScriptPath: string, operation: () => Promise<T>): Promise<T> {\n const paths = workingCopyPaths(rawScriptPath);\n fs.mkdirSync(paths.stateDir, { recursive: true });\n let release: (() => Promise<void>) | null = null;\n try {\n release = await lockfile.lock(paths.lockPath, {\n realpath: false,\n stale: 120_000,\n update: 10_000,\n retries: { retries: 60, factor: 1, minTimeout: 500, maxTimeout: 500 },\n });\n } catch (error) {\n throw new CliError(\"Timed out waiting for the script file lock.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"WORKING_COPY_LOCK_TIMEOUT\",\n hint: \"Wait for the other scriptctl command to finish, then retry.\",\n data: { actual: [paths.scriptPath, error instanceof Error ? error.message : String(error)] },\n });\n }\n try {\n return await operation();\n } finally {\n await release();\n }\n}\n\nexport function atomicWriteJson(filePath: string, value: unknown): void {\n atomicWriteText(filePath, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function atomicWriteText(filePath: string, content: string): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n const tempPath = path.join(dir, `.${path.basename(filePath)}.${process.pid}.${crypto.randomUUID()}.tmp`);\n const descriptor = fs.openSync(tempPath, \"wx\");\n try {\n fs.writeFileSync(descriptor, content, \"utf-8\");\n fs.fsyncSync(descriptor);\n } finally {\n fs.closeSync(descriptor);\n }\n fs.renameSync(tempPath, filePath);\n}\n\nexport function readWorkingCopyMetadata(rawScriptPath: string): WorkingCopyMetadata | null {\n const metadataPath = workingCopyPaths(rawScriptPath).metadataPath;\n if (!fs.existsSync(metadataPath)) return null;\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(metadataPath, \"utf-8\"));\n } catch (error) {\n throw invalidMetadata(metadataPath, error instanceof Error ? error.message : String(error));\n }\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw invalidMetadata(metadataPath, \"metadata root must be an object\");\n }\n const record = value as Record<string, unknown>;\n if (record.schemaVersion !== 1\n || typeof record.projectGroupNo !== \"string\" || record.projectGroupNo.length === 0\n || typeof record.apiBaseUrl !== \"string\" || record.apiBaseUrl.length === 0\n || !Number.isInteger(record.baseRevision) || Number(record.baseRevision) < 0\n || typeof record.baseContentHash !== \"string\" || !record.baseContentHash.startsWith(\"sha256:\")) {\n throw invalidMetadata(metadataPath, \"required fields are missing or invalid\");\n }\n return {\n schemaVersion: 1,\n projectGroupNo: record.projectGroupNo,\n apiBaseUrl: record.apiBaseUrl,\n baseRevision: Number(record.baseRevision),\n baseContentHash: record.baseContentHash,\n };\n}\n\nexport function writeWorkingCopyMetadata(rawScriptPath: string, metadata: WorkingCopyMetadata): void {\n atomicWriteJson(workingCopyPaths(rawScriptPath).metadataPath, metadata);\n}\n\nfunction invalidMetadata(metadataPath: string, reason: string): CliError {\n return new CliError(\"Working copy metadata is invalid.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"WORKING_COPY_METADATA_INVALID\",\n hint: \"Run `scriptctl checkout --discard-local` to recreate the working copy metadata.\",\n data: { expected: [\"valid scriptctl working-copy metadata\"], actual: [metadataPath, reason] },\n });\n}\n\nexport function assertScriptUnchanged(scriptPath: string, expectedHash: string): void {\n let current: unknown;\n try {\n current = JSON.parse(fs.readFileSync(scriptPath, \"utf-8\"));\n } catch (error) {\n throw new CliError(\"The local script changed while the command was running.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"LOCAL_SCRIPT_CHANGED\",\n hint: \"Read the latest local script and re-apply the operation.\",\n data: { actual: [scriptPath, error instanceof Error ? error.message : String(error)] },\n });\n }\n const currentHash = semanticScriptHash(current);\n if (currentHash !== expectedHash) {\n throw new CliError(\"The local script changed while the command was running.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"LOCAL_SCRIPT_CHANGED\",\n hint: \"Read the latest local script and re-apply the operation.\",\n data: { actual: [`loadedHash=${expectedHash}`, `currentHash=${currentHash}`, scriptPath] },\n });\n }\n}\n", "import { EXIT_OK, CliError, type CommandOutput } from \"./common.js\";\n\nfunction hasRows(data: Record<string, unknown>): data is Record<string, unknown> & {\n rows: Array<Record<string, unknown>>;\n} {\n return Array.isArray(data[\"rows\"]);\n}\n\nfunction withNewline(text: string): string {\n return text.endsWith(\"\\n\") ? text : `${text}\\n`;\n}\n\nfunction diagnosticItems(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.map((item) => String(item).replace(/[\\r\\n]+/g, \" \"));\n}\n\nfunction tsvCell(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n const text = typeof value === \"string\" ? value : JSON.stringify(value);\n return text.replace(/\\t/g, \" \").replace(/\\r?\\n/g, \" \");\n}\n\nfunction tableText(data: Record<string, unknown>): string | null {\n if (!hasRows(data) || data.rows.length === 0 || !Array.isArray(data[\"row_columns\"])) return null;\n const columns = data[\"row_columns\"].filter((column): column is string => typeof column === \"string\");\n if (columns.length === 0) return null;\n return [\n columns.join(\"\\t\"),\n ...data.rows.map((row) => columns.map((column) => tsvCell(row[column])).join(\"\\t\")),\n ].join(\"\\n\");\n}\n\nexport function emit(output: CommandOutput, exitCode: number, jsonMode: boolean, format?: string): void {\n if (format === \"addr\" && hasRows(output.data)) {\n if (output.data.rows.length === 0) {\n process.stdout.write(\"\");\n return;\n }\n const addrs = output.data.rows.map((row) => String(row[\"addr\"] ?? \"\"));\n if (addrs.every((address) => address.length > 0)) {\n process.stdout.write(addrs.join(\"\\n\") + \"\\n\");\n return;\n }\n }\n if (jsonMode) {\n const payload: Record<string, unknown> = {\n ok: exitCode === EXIT_OK,\n exit_code: exitCode,\n ...output.data,\n };\n payload[\"ok\"] = exitCode === EXIT_OK;\n payload[\"exit_code\"] = exitCode;\n process.stdout.write(JSON.stringify(payload, null, 2) + \"\\n\");\n } else {\n // A command that already wrote its own stream output (`review` emits\n // NDJSON) returns nothing to print; an envelope newline would be a junk\n // line inside its protocol.\n if (output.text === \"\" && Object.keys(output.data).length === 0) return;\n process.stdout.write(withNewline(tableText(output.data) ?? output.text));\n }\n}\n\nexport function emitError(error: CliError, jsonMode: boolean): number {\n if (jsonMode) {\n const payload: Record<string, unknown> = {\n ok: false,\n exit_code: error.exitCode,\n error_code: error.errorCode,\n message: error.message,\n ...(error.hint ? { hint: error.hint } : {}),\n ...error.data,\n };\n payload[\"ok\"] = false;\n payload[\"exit_code\"] = error.exitCode;\n payload[\"error_code\"] = error.errorCode;\n payload[\"message\"] = error.message;\n if (error.hint) payload[\"hint\"] = error.hint;\n process.stdout.write(JSON.stringify(payload, null, 2) + \"\\n\");\n } else {\n const actual = diagnosticItems(error.data[\"actual\"]);\n const expected = diagnosticItems(error.data[\"expected\"]);\n const message = actual.length > 0\n ? `${error.message.replace(/\\.$/, \"\")}: ${actual[0]}`\n : error.message;\n const lines = [`error: ${message}`];\n if (actual.length > 1) lines.push(`actual: ${actual.slice(1).join(\"; \")}`);\n if (expected.length > 0) lines.push(`expected: ${expected.join(\"; \")}`);\n if (error.hint) lines.push(error.hint);\n process.stderr.write(`${lines.join(\"\\n\")}\\n`);\n }\n return error.exitCode;\n}\n", "import { Command } from \"commander\";\n\nimport { scriptJsonPath, type CommandOutput } from \"../common.js\";\nimport { withScriptFileLock } from \"../infra/script-working-copy.js\";\nimport { emit } from \"../output.js\";\n\nexport type Handler = (\n opts: Record<string, unknown>,\n) => Promise<[CommandOutput, number]> | [CommandOutput, number];\n\nexport interface RunState {\n jsonMode: boolean;\n exitCode: number;\n format?: string;\n}\n\nconst scriptAccess = new WeakMap<Command, \"read\" | \"write\">();\n\nfunction camelToSnake(value: string): string {\n return value.replace(/([A-Z])/g, \"_$1\").toLowerCase();\n}\n\nfunction normalizeOpts(opts: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(opts).map(([key, value]) => [camelToSnake(key), value]));\n}\n\nfunction mergedCommandOpts(command: Command): Record<string, unknown> {\n const chain: Command[] = [];\n let current: Command | null | undefined = command;\n while (current) {\n chain.unshift(current);\n current = current.parent;\n }\n return Object.assign({}, ...chain.map((item) => item.opts()));\n}\n\nexport function dispatch(handler: Handler, state: RunState) {\n return async (...args: unknown[]) => {\n const command = args[args.length - 1] as Command;\n const positionals = args.slice(0, -2).filter((value) => value !== undefined) as string[];\n const normalized = normalizeOpts(mergedCommandOpts(command));\n if (positionals.length > 0) normalized[\"_args\"] = positionals;\n state.jsonMode = Boolean(normalized[\"json\"]);\n state.format = typeof normalized[\"format\"] === \"string\" ? normalized[\"format\"] : undefined;\n\n const invoke = async () => handler(normalized);\n const [output, exitCode] = scriptAccess.get(command) === \"write\"\n ? await withScriptFileLock(scriptJsonPath(normalized), invoke)\n : await invoke();\n emit(output, exitCode, state.jsonMode, state.format);\n state.exitCode = exitCode;\n };\n}\n\nexport function describeArguments(command: Command, descriptions: readonly string[]): Command {\n command.registeredArguments.forEach((argument, index) => {\n argument.description = descriptions[index] ?? \"\";\n });\n return command;\n}\n\nexport function withScriptOpts(command: Command, access: \"read\" | \"write\" = \"write\"): Command {\n scriptAccess.set(command, access);\n return command.option(\"-p, --script-path <path>\", \"Script JSON file (default: ./workspace/script.json)\");\n}\n\nexport function withWorkingCopyOpts(command: Command): Command {\n scriptAccess.set(command, \"write\");\n return command\n .option(\"-p, --script-path <path>\", \"Local script JSON file (default: ./workspace/script.json)\")\n .option(\"--project-group-no <no>\", \"Remote project group number\");\n}\n\nexport function withSelection(command: Command): Command {\n return command\n .option(\"-i, --in <selector>\", \"Address or address range to select\")\n .option(\"-t, --type <type>\", \"Action type to match\")\n .option(\"-a, --actor <id>\", \"Actor ID to match\")\n .option(\"-g, --grep <pattern>\", \"Text or regular expression to match\")\n .option(\"--has <facet>\", \"Require a populated action facet\")\n .option(\"--apply\", \"Apply the planned changes\")\n .option(\"--plan <digest>\", \"Exact plan digest to apply\")\n .option(\"-n, --dry-run\", \"Preview changes without writing\");\n}\n\nexport const appendString = (value: string, previous: string[]): string[] => [...previous, value];\n", "import { Command } from \"commander\";\n\nimport { commandChangelog } from \"../usecases/changelog.js\";\nimport { commandDoctor } from \"../usecases/doctor.js\";\nimport { commandUpdate } from \"../usecases/update.js\";\nimport { describeArguments, dispatch, type RunState } from \"./registry.js\";\n\nexport function registerToolCommands(program: Command, state: RunState): void {\n program.command(\"doctor\")\n .description(\"Check configuration and runtime dependencies\")\n .option(\"--llm-config <path>\", \"LLM configuration file\")\n .action(dispatch(commandDoctor, state));\n\n program.command(\"update\")\n .description(\"Update scriptctl to the latest release\")\n .option(\"-n, --dry-run\", \"Show the update without installing\")\n .option(\"--patch\", \"Allow a patch-level update\")\n .action(dispatch(commandUpdate, state));\n\n const changelog = program.command(\"changelog [version]\")\n .description(\"Show release notes\")\n .option(\"--from <version>\", \"Start version\")\n .option(\"--to <version>\", \"End version\")\n .option(\"--unreleased\", \"Show unreleased changes\")\n .action(dispatch(commandChangelog, state));\n describeArguments(changelog, [\"Release version\"]);\n}\n", "// `scriptctl review`: one process reviews a whole script against its original\n// video. The agent itself lives in @lingjingai/review-agent and is loaded by a\n// dynamic import so that every other command keeps its ~0.09s start-up.\n//\n// Progress is NDJSON on stdout, one line per episode as it finishes, because\n// the caller persists per-episode results and must not lose them if the run\n// is interrupted.\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { CliError, EXIT_INPUT, EXIT_OK, EXIT_RUNTIME, type CommandOutput } from \"../../common.js\";\nimport { scriptJsonPath } from \"../../common.js\";\nimport { loadLlmConfig, type ResolvedLlmConfig } from \"../../llm/config.js\";\nimport { type Dict, strOf } from \"../../domain/script/shared.js\";\n\ninterface Profile {\n provider: string;\n model: string;\n baseUrl: string | null;\n apiKey: string;\n}\n\nconst DEFAULT_PROFILE = \"review-agent\";\n\nfunction resolveProfile(llm: ResolvedLlmConfig, override: string): Profile {\n const name = override || DEFAULT_PROFILE;\n const model = llm.models[name];\n if (!model) {\n throw new CliError(`LLM profile \"${name}\" is not defined.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_PROFILE_UNKNOWN\",\n hint: `Define it under models, or pick one of: ${Object.keys(llm.models).join(\", \")}.`,\n data: { expected: [\"a defined models entry\"], actual: [name] },\n });\n }\n const provider = llm.providers[model.provider];\n if (!provider) {\n throw new CliError(`Provider \"${model.provider}\" is not defined.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_PROVIDER_UNKNOWN\",\n hint: `Available providers: ${Object.keys(llm.providers).join(\", \")}.`,\n data: { expected: [\"a defined providers entry\"], actual: [model.provider] },\n });\n }\n const apiKey = (process.env[provider.apiKeyEnv] ?? \"\").trim();\n if (!apiKey) {\n throw new CliError(`${provider.apiKeyEnv} is not set.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_API_KEY_MISSING\",\n hint: `Export ${provider.apiKeyEnv} for provider ${model.provider}.`,\n data: { expected: [provider.apiKeyEnv], actual: [\"<empty>\"] },\n });\n }\n return { provider: model.provider, model: model.model, baseUrl: provider.baseUrl, apiKey };\n}\n\n/**\n * The agent bundle sits next to this file in dist. It is loaded by path rather\n * than by package name so that a published scriptctl needs no resolvable\n * `@lingjingai/review-agent` \u2014 the bundle IS the package.\n */\nasync function loadAgent(): Promise<typeof import(\"@lingjingai/review-agent\")> {\n const here = path.dirname(fileURLToPath(import.meta.url));\n // In the shipped bundle this module is dist/bin.js, so the sibling is\n // dist/review-agent.js; under tsc output it is dist/usecases/script/, so the\n // package name resolves through node_modules instead.\n const bundled = path.join(here, \"review-agent.js\");\n const specifier = fs.existsSync(bundled) ? bundled : \"@lingjingai/review-agent\";\n try {\n return await import(specifier) as typeof import(\"@lingjingai/review-agent\");\n } catch (error) {\n throw new CliError(\"The review agent is not installed.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"REVIEW_AGENT_MISSING\",\n hint: \"Reinstall scriptctl without --omit=optional, or install @mastra/core and @ai-sdk/google.\",\n data: { expected: [\"@lingjingai/review-agent\"], actual: [String((error as Error).message).slice(0, 200)] },\n });\n }\n}\n\nfunction episodeList(raw: string): number[] | undefined {\n const trimmed = raw.trim();\n if (!trimmed) return undefined;\n const numbers = trimmed.split(\",\").map((part) => Number(part.trim()));\n if (numbers.some((value) => !Number.isInteger(value) || value < 1)) {\n throw new CliError(\"--episodes takes a comma-separated list of 1-based episode numbers.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_EPISODES_INVALID\",\n hint: \"For example: --episodes 1,2,5\",\n data: { expected: [\"1-based episode numbers\"], actual: [trimmed] },\n });\n }\n return numbers;\n}\n\nfunction positive(opts: Dict, key: string, fallback: number): number {\n const raw = opts[key];\n if (raw === undefined) return fallback;\n const value = Number(raw);\n if (!Number.isFinite(value) || value <= 0) {\n throw new CliError(`--${key.replace(/_/g, \"-\")} must be a positive number.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_OPTION_INVALID\",\n hint: `Pass a positive number for --${key.replace(/_/g, \"-\")}.`,\n data: { expected: [\"a positive number\"], actual: [String(raw)] },\n });\n }\n return value;\n}\n\nexport async function commandReview(opts: Dict): Promise<[CommandOutput, number]> {\n const llm = loadLlmConfig(strOf(opts[\"llm_config\"]).trim() || undefined);\n const override = strOf(opts[\"model\"]).trim();\n const profile = resolveProfile(llm, override);\n\n // --check answers \"can this run at all\" without spending a token: it is what\n // replaces `codex login status` in the caller's preflight.\n if (opts[\"check\"]) {\n const agent = await loadAgent();\n const ok = typeof agent.reviewScript === \"function\";\n return [{\n text: ok\n ? `ready: ${profile.provider}/${profile.model}`\n : \"the review agent bundle is present but exports no reviewScript\",\n data: {\n ready: ok,\n provider: profile.provider,\n model: profile.model,\n llm_config: llm.sourcePath ?? \"builtin\",\n },\n }, ok ? EXIT_OK : EXIT_RUNTIME];\n }\n\n const scriptPath = scriptJsonPath(opts);\n if (!fs.existsSync(scriptPath)) {\n throw new CliError(\"Local script file not found.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_NOT_FOUND\",\n hint: \"Run `scriptctl checkout`, `scriptctl create`, or pass --script-path to an existing script.\",\n data: { expected: [\"existing local script JSON\"], actual: [scriptPath] },\n });\n }\n const videos = (Array.isArray(opts[\"video\"]) ? opts[\"video\"] as string[] : [])\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n const missing = videos.filter((value) => !fs.existsSync(value));\n if (missing.length > 0) {\n throw new CliError(\"A --video path does not exist.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_SOURCE_NOT_FOUND\",\n hint: \"Pass --video once per episode, in episode order.\",\n data: { expected: [\"existing video files\"], actual: missing.slice(0, 5) },\n });\n }\n const source = strOf(opts[\"source_path\"]).trim();\n if (source && !fs.existsSync(source)) {\n throw new CliError(\"Video source not found.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"REVIEW_SOURCE_NOT_FOUND\",\n hint: \"Pass -s to a video file or a directory of per-episode videos, or omit it for a script-only review.\",\n data: { expected: [\"existing video file or directory\"], actual: [source] },\n });\n }\n\n const { reviewScript } = await loadAgent();\n const write = (event: unknown) => process.stdout.write(JSON.stringify(event) + \"\\n\");\n\n try {\n await reviewScript({\n scriptPath,\n ...(source ? { source } : {}),\n ...(videos.length > 0 ? { videos } : {}),\n ...(episodeList(strOf(opts[\"episodes\"])) ? { episodes: episodeList(strOf(opts[\"episodes\"]))! } : {}),\n concurrency: positive(opts, \"concurrency\", 5),\n converge: opts[\"converge\"] !== false,\n apiKey: profile.apiKey,\n model: profile.model,\n mediaModel: profile.model,\n ...(profile.baseUrl ? { baseUrl: profile.baseUrl } : {}),\n maxSteps: positive(opts, \"max_steps\", 60),\n mediaBudget: positive(opts, \"media_budget\", 1),\n episodeTimeoutMs: positive(opts, \"episode_timeout_ms\", 8 * 60_000),\n onEvent: write,\n });\n } catch (error) {\n if (error instanceof CliError) throw error;\n throw new CliError(\"Review failed.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"REVIEW_FAILED\",\n hint: \"Read the last NDJSON lines on stdout for the episode that failed.\",\n data: { expected: [\"a completed review run\"], actual: [String((error as Error).message).slice(0, 300)] },\n });\n }\n\n // Every result already left as NDJSON; the envelope would only repeat it.\n return [{ text: \"\", data: {} }, EXIT_OK];\n}\n", "// Shared micro-utilities for the script domain modules.\n// Promoted here so script-core's split modules (selector / validate / patch /\n// ids / \u2026) and the usecase layer share one copy instead of each redefining\n// these generic JSON guards.\n\nimport { CliError, EXIT_USAGE } from \"../../common.js\";\n\nexport type Dict = Record<string, unknown>;\n\nexport function strOf(v: unknown): string {\n if (v === null || v === undefined) return \"\";\n return String(v);\n}\n\nexport function isDict(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nexport function isList(v: unknown): v is unknown[] {\n return Array.isArray(v);\n}\n\nexport function asList<T = unknown>(v: unknown): T[] {\n return Array.isArray(v) ? (v as T[]) : [];\n}\n\n// Parse the numeric tail of an id like `ep_007` / `scn_012` (\u2192 7 / 12).\n// Returns NaN when the id does not match `${prefix}_<digits>`.\nexport function idNum(id: string, prefix: string): number {\n const m = new RegExp(`^${prefix}_(\\\\d+)$`).exec(strOf(id).trim());\n return m ? parseInt(m[1]!, 10) : NaN;\n}\n\n// Error factory used throughout the patch op engine. Defaults to EXIT_USAGE.\nexport function opErr(\n title: string,\n message: string,\n opts: {\n exitCode?: number;\n required?: string[];\n received?: string[];\n nextSteps?: string[];\n op?: string;\n errorCode?: string;\n } = {},\n): CliError {\n return new CliError(message, {\n exitCode: opts.exitCode ?? EXIT_USAGE,\n errorCode: opts.errorCode ?? title.replace(/[^A-Za-z0-9]+/g, \"_\").replace(/^_|_$/g, \"\").toUpperCase(),\n hint: opts.nextSteps?.[0],\n data: { expected: opts.required, actual: opts.received, op: opts.op },\n });\n}\n", "// `scriptctl review` sits apart from both the script verbs and the workflow\n// commands: it is the one command that dispatches an agent.\nimport { Command } from \"commander\";\n\nimport { commandReview } from \"../usecases/script/review.js\";\nimport { dispatch, type RunState, withScriptOpts } from \"./registry.js\";\n\nexport function registerReviewCommand(program: Command, state: RunState): void {\n withScriptOpts(program.command(\"review\"), \"write\")\n .description(\"\u6D3E\u53D1 agent \u5BA1\u6838\u5267\u672C\uFF1A\u7ED9 -s \u5C31\u6309\u539F\u89C6\u9891\u62C9\u7247\u6838\u5BF9\uFF0C\u4E0D\u7ED9\u5C31\u7EAF\u5267\u672C\u5BA1\u6838\")\n .option(\"-s, --source-path <path>\", \"\u539F\u89C6\u9891\u6587\u4EF6\u6216\u6BCF\u96C6\u4E00\u4E2A\u89C6\u9891\u7684\u76EE\u5F55\")\n .option(\n \"--video <path>\",\n \"\u7B2C N \u96C6\u7684\u89C6\u9891\uFF1B\u6309\u96C6\u987A\u5E8F\u91CD\u590D\u4F20\uFF0C\u8986\u76D6 -s \u7684\u76EE\u5F55\u6392\u5E8F\",\n (value: string, previous: string[]) => [...previous, value],\n [] as string[],\n )\n .option(\"--episodes <list>\", \"\u53EA\u5BA1\u8FD9\u4E9B\u96C6\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u9ED8\u8BA4\u5168\u5267\uFF09\")\n .option(\"--concurrency <n>\", \"\u540C\u65F6\u5728\u98DE\u7684\u96C6\u6570\", Number)\n .option(\"--episode-timeout-ms <ms>\", \"\u5355\u96C6\u8D85\u65F6\uFF1B\u5230\u70B9\u6536\u5C3E\u5E76\u4FDD\u7559\u5DF2\u8BB0\u5F55\u7684\u7ED3\u8BBA\", Number)\n .option(\"--max-steps <n>\", \"\u5355\u96C6\u6700\u591A\u51E0\u6B65\u5DE5\u5177\u8C03\u7528\", Number)\n .option(\"--media-budget <n>\", \"\u5355\u96C6\u6700\u591A\u51E0\u6B21\u89C6\u9891\u6838\u5BF9\", Number)\n .option(\"--no-converge\", \"\u8DF3\u8FC7\u5168\u5267\u6536\u655B\u9636\u6BB5\")\n .option(\"--model <profile>\", \"\u8986\u76D6 LLM profile\uFF08\u9ED8\u8BA4 review-agent\uFF09\")\n .option(\"--llm-config <path>\", \"LLM configuration file\")\n .option(\"--check\", \"\u53EA\u68C0\u67E5\u6A21\u578B\u4E0E agent \u662F\u5426\u5C31\u7EEA\uFF0C\u4E0D\u5BA1\u6838\")\n .action(dispatch(commandReview, state));\n}\n", "// The agent-facing script surface: the verbs from @lingjingai/screenplay\n// plus scan/span, exposed as CLI commands. This replaces the previous 42\n// query/edit/batch commands.\n//\n// The point of the shape: every parameter is a scalar, the address is one\n// string, and the same address grammar works for read and write. The old\n// surface asked an agent to learn per-verb address dialects (`ep_001/scn_003#5`\n// vs `@ep:3/scn:2/ac:5` vs bare ids), plan digests for multi-point edits, and\n// TSV parsing for every read.\nimport * as fs from \"node:fs\";\n\nimport { Command } from \"commander\";\nimport * as sp from \"@lingjingai/screenplay\";\n\nimport { CliError, EXIT_INPUT, EXIT_OK, type CommandOutput } from \"../common.js\";\nimport { scriptJsonPath } from \"../common.js\";\nimport { dispatch, describeArguments, type RunState, withScriptOpts } from \"./registry.js\";\n\ntype Opts = Record<string, unknown>;\n\nconst ADDR = \"\u5730\u5740\uFF1A\u96C6 `3`\u3001\u573A `3-2`\u3001\u5355\u6761 `3-2-5`\u3001\u6B63\u5F0F ID\u3001\u8D44\u4EA7\u540D\u3001\u6216 `<\u8D44\u4EA7>/<\u72B6\u6001>`\";\n\nfunction doc(opts: Opts): sp.Doc {\n const path = scriptJsonPath(opts);\n if (!fs.existsSync(path)) {\n throw new CliError(\"Local script file not found.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_NOT_FOUND\",\n hint: \"Run `scriptctl checkout`, `scriptctl create`, or pass --script-path to an existing script.\",\n data: { expected: [\"existing local script JSON\"], actual: [path] },\n });\n }\n return sp.load(path);\n}\n\nfunction str(opts: Opts, key: string): string | undefined {\n const value = opts[key];\n // An empty string is a real value for --paren (set it to empty) and must not\n // be silently dropped; only a missing flag yields undefined.\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction num(opts: Opts, key: string): number | undefined {\n const value = opts[key];\n if (value === undefined || value === null || value === \"\") return undefined;\n const parsed = Number(value);\n if (!Number.isFinite(parsed)) {\n throw new CliError(`--${key} must be a number.`, {\n exitCode: EXIT_INPUT, errorCode: \"OPTION_NOT_NUMBER\",\n data: { actual: [String(value)] },\n });\n }\n return parsed;\n}\n\nfunction arg(opts: Opts, index = 0): string {\n const args = (opts[\"_args\"] as string[] | undefined) ?? [];\n return args[index] ?? \"\";\n}\n\nfunction list(value: unknown): string[] {\n if (Array.isArray(value)) return value.map(String);\n if (typeof value === \"string\") return value.split(\",\").map((v) => v.trim()).filter(Boolean);\n return [];\n}\n\n/** SDK errors carry a plain message; map them onto scriptctl's error model. */\nfunction text(run: () => string, op: string): [CommandOutput, number] {\n try {\n return [{ text: run(), data: { op, changed: false } }, EXIT_OK];\n } catch (error) {\n if (error instanceof CliError) throw error;\n throw new CliError(error instanceof Error ? error.message : String(error), {\n exitCode: EXIT_INPUT,\n errorCode: (error as { code?: string })?.code ?? \"SCRIPT_TOOL_FAILED\",\n });\n }\n}\n\nexport function registerScriptCommands(program: Command, state: RunState): void {\n // ---- read -------------------------------------------------------------\n const read = withScriptOpts(program.command(\"read [addr]\"), \"read\")\n .description(`\u8BFB\u4EFB\u610F\u8282\u70B9\uFF1B\u4E0D\u7ED9\u5730\u5740\u8FD4\u56DE\u5267\u672C\u5361\u3002${ADDR}`)\n .option(\"--outline\", \"\u53EA\u8981\u573A\u7ED3\u6784\uFF0C\u4E0D\u8981\u6B63\u6587\")\n .option(\"--context <n>\", \"\u5355\u6761 action \u524D\u540E\u5404\u5E26\u51E0\u6761\uFF08\u9ED8\u8BA4 3\uFF09\")\n .option(\"--plain\", \"\u53BB\u6389\u951A\u70B9\u4E0E\u65F6\u95F4\u6233\uFF08\u53EA\u8BFB\uFF0C\u4E0D\u53EF\u56DE\u5199\uFF09\")\n .action(dispatch((opts) => text(() => sp.read(doc(opts), arg(opts), {\n ...(opts[\"outline\"] ? { depth: \"outline\" as const } : {}),\n ...(opts[\"plain\"] ? { plain: true } : {}),\n ...(num(opts, \"context\") !== undefined ? { context: num(opts, \"context\")! } : {}),\n }), \"read\"), state));\n describeArguments(read, [ADDR]);\n\n const scan = withScriptOpts(program.command(\"scan <episode>\"), \"read\")\n .description(\"\u4E00\u6B21\u8FD4\u56DE\u67D0\u96C6\u7684\u5B8C\u6574\u4E0A\u4E0B\u6587\uFF1A\u573A\u7ED3\u6784 + \u5168\u90E8\u6B63\u6587 + \u5F53\u524D\u6821\u9A8C\u95EE\u9898\")\n .action(dispatch((opts) => text(() => {\n const d = doc(opts);\n const ep = arg(opts);\n return [\n `## \u573A\u7ED3\u6784\\n${sp.read(d, ep, { depth: \"outline\" })}`,\n `## \u6B63\u6587\\n${sp.read(d, ep)}`,\n `## \u5F53\u524D\u6821\u9A8C\u95EE\u9898\\n${sp.issues(d, {})}`,\n ].join(\"\\n\\n\");\n }, \"scan\"), state));\n describeArguments(scan, [\"\u96C6\u53F7\uFF0C\u4ECE 1 \u5F00\u59CB\"]);\n\n const find = withScriptOpts(program.command(\"find [query]\"), \"read\")\n .description(\"\u6309\u6B63\u6587\u6B63\u5219 / \u8BF4\u8BDD\u4EBA / \u7C7B\u578B\u5B9A\u4F4D action\uFF0C\u8FD4\u56DE\u951A\u70B9 + \u547D\u4E2D\u7A97\u53E3\")\n .option(\"-i, --in <addr>\", `\u9650\u5236\u8303\u56F4\uFF0C${ADDR}`)\n .option(\"-a, --speaker <name>\", \"\u4EBA\u7269\u540D\u6216 actor id\")\n .option(\"-t, --type <type>\", \"action | dialogue | inner_thought | transition\")\n .option(\"--limit <n>\", \"\u6700\u591A\u8FD4\u56DE\u51E0\u6761\uFF08\u9ED8\u8BA4 40\uFF09\")\n .option(\"--full\", \"\u8FD4\u56DE\u6574\u6761\u6B63\u6587\u800C\u4E0D\u662F\u547D\u4E2D\u7A97\u53E3\")\n .action(dispatch((opts) => text(() => sp.find(doc(opts), arg(opts), {\n ...(str(opts, \"in\") ? { in: str(opts, \"in\")! } : {}),\n ...(str(opts, \"speaker\") ? { speaker: str(opts, \"speaker\")! } : {}),\n ...(str(opts, \"type\") ? { type: str(opts, \"type\")! } : {}),\n ...(num(opts, \"limit\") !== undefined ? { limit: num(opts, \"limit\")! } : {}),\n ...(opts[\"full\"] ? { full: true } : {}),\n }), \"find\"), state));\n describeArguments(find, [\"\u6B63\u5219\uFF1B\u53EA\u6309 speaker/type \u8FC7\u6EE4\u65F6\u53EF\u7701\u7565\"]);\n\n const span = withScriptOpts(program.command(\"span <range>\"), \"read\")\n .description(\"\u628A\u4E00\u6BB5 action \u6362\u7B97\u6210\u96C6\u5185\u89C6\u9891\u65F6\u95F4\u7A97\u53E3\uFF08\u534A\u5F00\u533A\u95F4\uFF09\")\n .action(dispatch((opts) => text(() => sp.span(doc(opts), arg(opts)), \"span\"), state));\n describeArguments(span, [`${ADDR}\uFF0C\u6216 \\`\u8D77ID..\u6B62ID\\``]);\n\n withScriptOpts(program.command(\"validate\"), \"read\")\n .description(\"\u8DD1\u6574\u672C\u6821\u9A8C\")\n .action(dispatch((opts) => text(() => sp.validate(doc(opts)), \"validate\"), state));\n\n withScriptOpts(program.command(\"issues\"), \"read\")\n .description(\"\u5217\u5F53\u524D\u6821\u9A8C\u95EE\u9898\")\n .option(\"--severity <severity>\", \"error | warning\")\n .option(\"--code <code>\", \"\u6309 issue code \u8FC7\u6EE4\")\n .action(dispatch((opts) => text(() => sp.issues(doc(opts), {\n ...(str(opts, \"severity\") ? { severity: str(opts, \"severity\")! } : {}),\n ...(str(opts, \"code\") ? { code: str(opts, \"code\")! } : {}),\n }), \"issues\"), state));\n\n // ---- write ------------------------------------------------------------\n const edit = withScriptOpts(program.command(\"edit <addr>\"), \"write\")\n .description(`\u6539\u4E00\u4E2A\u8282\u70B9\u7684\u5B57\u6BB5\uFF1B\u5730\u5740\u51B3\u5B9A\u54EA\u4E9B\u5B57\u6BB5\u5408\u6CD5\u3002${ADDR}`)\n .option(\"--content <text>\", \"action \u6B63\u6587\")\n .option(\"--paren <text>\", \"\u8868\u6F14\u63D0\u793A\")\n .option(\"--no-paren\", \"\u5220\u9664\u8868\u6F14\u63D0\u793A\u5B57\u6BB5\")\n .option(\"--speaker <name>\", \"\u4EBA\u7269\u540D\u6216 `\u540D\u5B57\u00B7\u72B6\u6001`\uFF1B\u65C1\u767D/\u5E7F\u64AD/\u753B\u5916/\u7FA4\u58F0\u4EA6\u53EF\")\n .option(\"--ts <time>\", \"\u65F6\u95F4\u6233\")\n .option(\"--no-ts\", \"\u5220\u9664\u65F6\u95F4\u6233\")\n .option(\"--type <type>\", \"action | dialogue | inner_thought | transition\")\n .option(\"--transition <spec>\", \"\u8F6C\u573A\u63D0\u793A `\u76EE\u6807|\u8FC7\u7A0B|\u5BF9\u6BD4`\")\n .option(\"--no-transition\", \"\u5220\u9664\u8F6C\u573A\u63D0\u793A\")\n .option(\"--name <text>\", \"\u8D44\u4EA7 / \u72B6\u6001\u540D\")\n .option(\"--desc <text>\", \"\u8D44\u4EA7 / \u72B6\u6001\u63CF\u8FF0\")\n .option(\"--importance <tier>\", \"featured | background\")\n .option(\"--role <type>\", \"\u4E3B\u89D2 | \u914D\u89D2\")\n .option(\"--alias <list>\", \"\u8D44\u4EA7\u522B\u540D\uFF0C\u9017\u53F7\u5206\u9694\")\n .option(\"--space <space>\", \"\u573A\uFF1Ainterior | exterior\")\n .option(\"--time <time>\", \"\u573A\uFF1Aday | night | dawn | dusk\")\n .option(\"--title <text>\", \"\u96C6 / \u5267\u672C\u6807\u9898\")\n .option(\"--synopsis <text>\", \"\u96C6 / \u5267\u672C\u6897\u6982\")\n .option(\"--logline <text>\", \"\u5267\u672C logline\")\n .option(\"--theme <text>\", \"\u5267\u672C\u4E3B\u9898\")\n .option(\"--worldview <text>\", \"\u5267\u672C\u4E16\u754C\u89C2\")\n .option(\"--style <text>\", \"\u5267\u672C\u98CE\u683C\")\n .option(\"--main <list>\", \"\u4E3B\u8981\u4EBA\u7269 `\u540D\u5B57=\u5B9A\u4F4D,\u2026`\")\n .action(dispatch((opts) => {\n const fields: Record<string, unknown> = {};\n for (const key of [\"content\", \"speaker\", \"type\", \"name\", \"desc\", \"importance\",\n \"role\", \"space\", \"time\", \"title\", \"synopsis\", \"logline\", \"theme\",\n \"worldview\", \"style\", \"main\"]) {\n const value = str(opts, key);\n if (value !== undefined) fields[key] = value;\n }\n // commander turns --no-x into x === false; that is the \"remove\" signal.\n for (const key of [\"paren\", \"ts\", \"transition\"]) {\n if (opts[key] === false) fields[key] = null;\n else {\n const value = str(opts, key);\n if (value !== undefined) fields[key] = value;\n }\n }\n if (opts[\"alias\"] !== undefined) fields[\"aliases\"] = list(opts[\"alias\"]);\n return text(() => sp.edit(doc(opts), arg(opts), fields as never), \"edit\");\n }, state));\n describeArguments(edit, [ADDR]);\n\n const insert = withScriptOpts(program.command(\"insert <addr> <content>\"), \"write\")\n .description(\"\u5728\u67D0\u6761 action \u524D/\u540E\u63D2\u5165\u4E00\u6761\u65B0 action\")\n .requiredOption(\"-t, --type <type>\", \"action | dialogue | inner_thought | transition\")\n .option(\"--before\", \"\u63D2\u5230\u76EE\u6807\u4E4B\u524D\uFF08\u9ED8\u8BA4\u4E4B\u540E\uFF09\")\n .option(\"-a, --speaker <name>\", \"dialogue / inner_thought \u5FC5\u586B\")\n .option(\"--paren <text>\", \"\u8868\u6F14\u63D0\u793A\")\n .action(dispatch((opts) => text(() => sp.insert(\n doc(opts), arg(opts), opts[\"before\"] ? \"before\" : \"after\",\n str(opts, \"type\")!, arg(opts, 1), str(opts, \"speaker\"), str(opts, \"paren\"),\n ), \"insert\"), state));\n describeArguments(insert, [\"\u76F8\u90BB action \u7684\u5730\u5740\", \"\u65B0 action \u7684\u6B63\u6587\"]);\n\n const move = withScriptOpts(program.command(\"move <addr> <to>\"), \"write\")\n .description(\"\u628A\u4E00\u6761 action \u632A\u5230\u53E6\u4E00\u6761\u65C1\u8FB9\uFF1B\u8DE8\u573A\u4E5F\u4FDD\u6301 action_id\")\n .option(\"--before\", \"\u632A\u5230\u76EE\u6807\u4E4B\u524D\uFF08\u9ED8\u8BA4\u4E4B\u540E\uFF09\")\n .action(dispatch((opts) => text(() => sp.move(\n doc(opts), arg(opts), arg(opts, 1), opts[\"before\"] ? \"before\" : \"after\",\n ), \"move\"), state));\n describeArguments(move, [\"\u8981\u632A\u7684 action\", \"\u76EE\u6807\u90BB\u5C45 action\"]);\n\n const write = withScriptOpts(program.command(\"write <addr>\"), \"write\")\n .description(\"\u7528 read \u8F93\u51FA\u7684\u540C\u4E00\u4EFD\u6B63\u6587\u683C\u5F0F\u56DE\u5199\u6574\u573A / \u6574\u96C6 / \u65B0\u96C6\uFF08`+`\uFF09\")\n .option(\"-f, --file <path>\", \"\u6B63\u6587\u6587\u4EF6\uFF1B\u7701\u7565\u5219\u8BFB stdin\")\n .option(\"--allow-delete\", \"\u5141\u8BB8\u5220\u9664\u6587\u672C\u91CC\u6D88\u5931\u7684\u573A / action\")\n .action(dispatch(async (opts) => {\n const fs = await import(\"node:fs\");\n const file = str(opts, \"file\");\n const body = file ? fs.readFileSync(file, \"utf8\") : fs.readFileSync(0, \"utf8\");\n return text(() => sp.write(doc(opts), arg(opts), body, {\n allowDelete: Boolean(opts[\"allow_delete\"]),\n }), \"write\");\n }, state));\n describeArguments(write, [\"\u573A / \u96C6\u5730\u5740\uFF0C\u6216 `+` \u8FFD\u52A0\u65B0\u96C6\"]);\n\n const replace = withScriptOpts(program.command(\"replace <pattern> <to>\"), \"write\")\n .description(\"\u6279\u91CF\u66FF\u6362\u6B63\u6587\uFF1B\u9ED8\u8BA4\u53EA\u9884\u89C8\uFF0C--apply \u624D\u843D\u76D8\u3002\u8FC7\u6EE4\u53C2\u6570\u4E0E find \u76F8\u540C\")\n .option(\"-i, --in <addr>\", \"\u9650\u5236\u8303\u56F4\")\n .option(\"-a, --speaker <name>\", \"\u9650\u5B9A\u8BF4\u8BDD\u4EBA\")\n .option(\"-t, --type <type>\", \"\u9650\u5B9A action \u7C7B\u578B\")\n .option(\"--apply\", \"\u771F\u7684\u5199\u5165\")\n .action(dispatch((opts) => text(() => sp.replace(doc(opts), arg(opts), arg(opts, 1), {\n ...(str(opts, \"in\") ? { in: str(opts, \"in\")! } : {}),\n ...(str(opts, \"speaker\") ? { speaker: str(opts, \"speaker\")! } : {}),\n ...(str(opts, \"type\") ? { type: str(opts, \"type\")! } : {}),\n ...(opts[\"apply\"] ? { apply: true } : {}),\n }), \"replace\"), state));\n describeArguments(replace, [\"\u6B63\u5219\", \"\u66FF\u6362\u6210\u4EC0\u4E48\"]);\n\n const ref = withScriptOpts(program.command(\"ref <scene> <asset>\"), \"write\")\n .description(\"\u6539\u4E00\u4E2A\u573A\u5BF9\u67D0\u8D44\u4EA7\u7684\u5F15\u7528\uFF1B--state \u662F\u5B8C\u6574\u72B6\u6001\u96C6\u5408\u800C\u975E\u8FFD\u52A0\")\n .option(\"--state <list>\", \"\u5B8C\u6574\u72B6\u6001\u96C6\u5408\uFF08\u540D\u5B57\u6216 ID\uFF09\uFF0C\u9017\u53F7\u5206\u9694\u6216\u91CD\u590D\u7ED9\u51FA\", collect, [])\n .option(\"--remove\", \"\u5220\u9664\u6574\u6761\u5F15\u7528\")\n .action(dispatch((opts) => text(() => sp.ref(\n doc(opts), arg(opts), arg(opts, 1),\n list(opts[\"state\"]).flatMap((v) => v.split(\",\")).map((v) => v.trim()).filter(Boolean),\n Boolean(opts[\"remove\"]),\n ), \"ref\"), state));\n describeArguments(ref, [\"\u573A\u5730\u5740\", \"\u4EBA\u7269 / \u5730\u70B9 / \u9053\u5177\u7684\u540D\u5B57\u6216 ID\"]);\n\n const asset = withScriptOpts(program.command(\"asset <kind> <name>\"), \"write\")\n .description(\"\u767B\u8BB0\u4E00\u4E2A\u65B0\u7684 actor / location / prop\")\n .requiredOption(\"--desc <text>\", \"\u63CF\u8FF0\")\n .option(\"--importance <tier>\", \"featured | background\", \"featured\")\n .option(\"--alias <list>\", \"\u522B\u540D\uFF0C\u9017\u53F7\u5206\u9694\")\n .action(dispatch((opts) => text(() => sp.asset(\n doc(opts), arg(opts) as never, arg(opts, 1), str(opts, \"desc\") ?? \"\",\n str(opts, \"importance\") ?? \"featured\", list(opts[\"alias\"]),\n ), \"asset\"), state));\n describeArguments(asset, [\"actor | location | prop\", \"\u540D\u5B57\"]);\n\n const stateCmd = withScriptOpts(program.command(\"state <asset> <name>\"), \"write\")\n .description(\"\u7ED9\u5DF2\u6709\u8D44\u4EA7\u52A0\u4E00\u4E2A\u72B6\u6001\uFF08\u9020\u578B\u6863\u4F4D\uFF09\")\n .requiredOption(\"--desc <text>\", \"\u63CF\u8FF0\")\n .action(dispatch((opts) => text(() => sp.state(\n doc(opts), arg(opts), arg(opts, 1), str(opts, \"desc\") ?? \"\",\n ), \"state\"), state));\n describeArguments(stateCmd, [\"\u8D44\u4EA7\u540D\u6216 ID\", \"\u72B6\u6001\u540D\"]);\n\n const del = withScriptOpts(program.command(\"del <addr>\"), \"write\")\n .description(\"\u5220\u9664 action / \u573A / \u96C6 / \u8D44\u4EA7 / \u72B6\u6001\")\n .option(\"--replacement <state>\", \"\u5220\u72B6\u6001\u65F6\u628A\u5F15\u7528\u6539\u5199\u5230\u8FD9\u4E2A\u72B6\u6001\")\n .option(\"--force\", \"\u5BB9\u5668\u975E\u7A7A\u65F6\u4ECD\u7136\u5220\u9664\")\n .action(dispatch((opts) => text(() => sp.del(doc(opts), arg(opts), {\n ...(str(opts, \"replacement\") ? { replacement: str(opts, \"replacement\")! } : {}),\n ...(opts[\"force\"] ? { force: true } : {}),\n }), \"del\"), state));\n describeArguments(del, [ADDR]);\n\n const merge = withScriptOpts(program.command(\"merge <src> <dst>\"), \"write\")\n .description(\"\u628A\u4E00\u4E2A\u8D44\u4EA7\u5E76\u5165\u53E6\u4E00\u4E2A\uFF1A\u5168\u90E8\u573A\u666F\u5F15\u7528\u4E0E speaker \u6539\u5199\u8FC7\u53BB\")\n .action(dispatch((opts) => text(() => sp.merge(doc(opts), arg(opts), arg(opts, 1)),\n \"merge\"), state));\n describeArguments(merge, [\"\u88AB\u5E76\u5165\u7684\u8D44\u4EA7\", \"\u4FDD\u7559\u7684\u8D44\u4EA7\"]);\n\n const ext = withScriptOpts(program.command(\"ext <addr> [key] [value]\"), \"write\")\n .description(\"\u8BFB\u6216\u5199\u4EFB\u610F\u8282\u70B9\u7684 extend \u6570\u636E\")\n .option(\"--remove\", \"\u5220\u9664\u8BE5 key\")\n .action(dispatch((opts) => text(() => sp.ext(\n doc(opts), arg(opts), arg(opts, 1) || undefined, arg(opts, 2) || undefined,\n Boolean(opts[\"remove\"]),\n ), \"ext\"), state));\n describeArguments(ext, [ADDR, \"extend key\", \"\u503C\"]);\n}\n\nfunction collect(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n", "// Version-neutral in-memory view of script.json.\n//\n// v3 and v4 differ in identity (v3 has no action IDs, per-episode scene IDs;\n// v4 has global random IDs) but the *shape* an agent reads is identical. So we\n// normalize once here and every tool works on one model. The `anchor` field is\n// whatever string the agent can paste back for that node.\nimport * as fs from \"node:fs\";\nimport { step } from \"./trace.js\";\nimport { generateV4Id } from \"./schema/index.js\";\nconst KINDS = [\n [\"actor\", \"actors\", \"actor\"],\n [\"location\", \"locations\", \"location\"],\n [\"prop\", \"props\", \"prop\"],\n];\nfunction arr(v) { return Array.isArray(v) ? v : []; }\nfunction str(v) { return typeof v === \"string\" ? v : \"\"; }\n// Index by every alias that is globally unambiguous. Colliding keys are dropped\n// rather than resolved first-wins \u2014 a silently wrong target is worse than an error.\nfunction put(map, key, value, dupes) {\n if (!key)\n return;\n if (map.has(key) && map.get(key) !== value) {\n dupes.add(key);\n return;\n }\n map.set(key, value);\n}\n/** Read a script from disk. The returned document is bound: mutations write through. */\nexport function load(path) {\n return parse(JSON.parse(fs.readFileSync(path, \"utf8\")), path);\n}\n/**\n * Build a document from an in-memory object. Without a `path` the document is\n * *unbound*: mutations stay in memory and `save` does nothing, so a long agent\n * session pays one parse instead of one read-modify-write per tool call. Call\n * `commit` to choose when it hits disk.\n */\nexport function parse(raw, path = \"\") {\n const version = raw?.version;\n if (version !== 3 && version !== 4) {\n throw new Error(`Unsupported script.version: ${JSON.stringify(version)} (expected 3 or 4)`);\n }\n const doc = {\n version, path, raw,\n episodes: [], assets: [],\n byId: new Map(), eps: new Map(), scenes: new Map(), actions: new Map(),\n };\n for (const [kind, field, idKey] of KINDS) {\n for (const a of arr(raw[field])) {\n const asset = {\n id: str(a[`${idKey}_id`]), kind,\n name: str(a[`${idKey}_name`]),\n aliases: arr(a.aliases).map(str).filter(Boolean),\n importance: str(a.importance),\n desc: str(a.description),\n states: arr(a.states).map((s) => ({\n id: str(s.state_id), name: str(s.state_name), desc: str(s.description),\n })),\n raw: a, label: \"\",\n };\n doc.assets.push(asset);\n doc.byId.set(asset.id, asset);\n }\n }\n // Screenwriters use short names. Pick the shortest label unique across the\n // whole cast; aliases stay resolvable on write, so this is lossless.\n const seen = new Map();\n for (const a of doc.assets)\n for (const n of [a.name, ...a.aliases])\n seen.set(n, (seen.get(n) ?? 0) + 1);\n for (const a of doc.assets) {\n a.label = [a.name, ...a.aliases]\n .filter((n) => seen.get(n) === 1)\n .sort((x, y) => x.length - y.length)[0] ?? a.name;\n }\n const dupes = new Set();\n let gScene = 0, gAction = 0;\n arr(raw.episodes).forEach((eRaw, ei) => {\n const ep = {\n anchor: String(ei + 1), id: str(eRaw.episode_id), no: ei + 1,\n title: str(eRaw.title) || undefined, synopsis: str(eRaw.synopsis) || undefined,\n scenes: [], raw: eRaw,\n };\n arr(eRaw.scenes).forEach((sRaw, si) => {\n gScene++;\n const scene = {\n anchor: version === 4 ? str(sRaw.scene_id) : `${ei + 1}-${si + 1}`,\n id: str(sRaw.scene_id), no: si + 1, gno: gScene,\n env: sRaw.environment ?? {},\n location: refOf(sRaw.location, \"location_id\"),\n actors: arr(sRaw.actors).map((r) => refOf(r, \"actor_id\")).filter(Boolean),\n props: arr(sRaw.props).map((r) => refOf(r, \"prop_id\")).filter(Boolean),\n actions: [], raw: sRaw, ep,\n };\n arr(sRaw.actions).forEach((aRaw, ai) => {\n gAction++;\n const action = {\n anchor: version === 4 ? str(aRaw.action_id) : `${ei + 1}-${si + 1}-${ai + 1}`,\n no: ai + 1, gno: gAction,\n type: str(aRaw.type) || \"action\",\n content: str(aRaw.content),\n speaker: speakerOf(aRaw.speaker),\n paren: typeof aRaw.parenthetical === \"string\" ? aRaw.parenthetical\n : typeof aRaw.emotion === \"string\" ? aRaw.emotion : undefined,\n ts: str(aRaw.extend?.timestamp) || undefined,\n raw: aRaw, scene,\n };\n scene.actions.push(action);\n put(doc.actions, action.anchor, action, dupes);\n put(doc.actions, `${ei + 1}-${si + 1}-${ai + 1}`, action, dupes);\n if (version === 3)\n put(doc.actions, `${ep.id}/${scene.id}#${ai}`, action, dupes);\n });\n ep.scenes.push(scene);\n put(doc.scenes, scene.anchor, scene, dupes);\n put(doc.scenes, `${ei + 1}-${si + 1}`, scene, dupes);\n put(doc.scenes, `${ep.id}/${scene.id}`, scene, dupes);\n put(doc.scenes, scene.id, scene, dupes);\n });\n doc.episodes.push(ep);\n put(doc.eps, String(ei + 1), ep, dupes);\n put(doc.eps, ep.id, ep, dupes);\n });\n for (const k of dupes) {\n doc.actions.delete(k);\n doc.scenes.delete(k);\n doc.eps.delete(k);\n }\n step(path ? \"model.load\" : \"model.parse\", `v${version} \u00B7 ${doc.episodes.length} ep \u00B7 ${doc.scenes.size} scene keys \u00B7 `\n + `${doc.actions.size} action keys \u00B7 ${doc.assets.length} assets \u00B7 ${dupes.size} ambiguous keys dropped`);\n return doc;\n}\nfunction refOf(r, idKey) {\n if (!r || typeof r !== \"object\")\n return null;\n const id = str(r[idKey]);\n if (!id)\n return null;\n const states = Array.isArray(r.state_ids) ? r.state_ids.map(str)\n : r.state_id ? [str(r.state_id)] : [];\n return { id, states, raw: r };\n}\nfunction speakerOf(s) {\n if (!s || typeof s !== \"object\")\n return undefined;\n if (s.actor_id)\n return { id: str(s.actor_id), state: str(s.state_id) || undefined };\n if (s.kind)\n return { kind: str(s.kind), label: str(s.label) || undefined };\n return undefined;\n}\n/**\n * Resolve an address: ordinal (`3`, `3-2`, `3-2-5`), any canonical ID, an asset\n * name/alias, or a state as `<asset>/<state>` \u2014 where either half may be an id\n * or a name.\n */\nexport function resolve(doc, addr) {\n const q = addr.trim();\n if (!q)\n return { t: \"script\", doc };\n // `<asset>/<state>` before anything else: a v3 scene reads as `ep_001/scn_001`,\n // so only try the state reading when the left half is actually an asset.\n const slash = q.indexOf(\"/\");\n if (slash > 0 && !doc.scenes.has(q)) {\n const left = q.slice(0, slash), right = q.slice(slash + 1);\n const owner = doc.byId.get(left) ?? assetByName(doc, left);\n if (owner) {\n const hit = owner.states.filter((st) => st.id === right || st.name === right);\n if (hit.length === 1) {\n step(\"resolve\", `\"${q}\" -> state ${owner.id}/${hit[0].id} \"${hit[0].name}\"`);\n return { t: \"state\", asset: owner, state: hit[0] };\n }\n if (hit.length > 1) {\n throw new Error(`${owner.name} has ${hit.length} states named \"${right}\"; address it by state id`);\n }\n throw new Error(`${owner.name} has no state \"${right}\" `\n + `(has: ${owner.states.map((st) => `${st.id}(${st.name})`).join(\", \")})`);\n }\n }\n const a = doc.actions.get(q);\n if (a) {\n step(\"resolve\", `\"${q}\" -> action map hit -> ${a.anchor}`);\n return { t: \"action\", action: a };\n }\n const s = doc.scenes.get(q);\n if (s) {\n step(\"resolve\", `\"${q}\" -> scene map hit -> ${s.anchor}`);\n return { t: \"scene\", scene: s };\n }\n const e = doc.eps.get(q);\n if (e) {\n step(\"resolve\", `\"${q}\" -> episode map hit -> ${e.id}`);\n return { t: \"ep\", ep: e };\n }\n const byId = doc.byId.get(q);\n if (byId) {\n step(\"resolve\", `\"${q}\" -> asset id hit -> ${byId.name}`);\n return { t: \"asset\", asset: byId };\n }\n const hits = doc.assets.filter((x) => x.name === q || x.aliases.includes(q));\n if (hits.length === 1) {\n step(\"resolve\", `\"${q}\" -> exact name/alias -> ${hits[0].id} ${hits[0].name}`);\n return { t: \"asset\", asset: hits[0] };\n }\n if (hits.length > 1) {\n throw new Error(`Ambiguous name \"${q}\": ${hits.map((h) => `${h.id}(${h.name})`).join(\", \")}`);\n }\n const loose = doc.assets.filter((x) => x.name.includes(q) || x.aliases.some((al) => al.includes(q)));\n if (loose.length === 1) {\n step(\"resolve\", `\"${q}\" -> substring name match -> ${loose[0].id} ${loose[0].name}`);\n return { t: \"asset\", asset: loose[0] };\n }\n throw new Error(`Unknown address \"${q}\". Use an ordinal (3 / 3-2 / 3-2-5), a canonical ID, or an asset name.`\n + (loose.length ? ` Did you mean: ${loose.slice(0, 5).map((h) => h.name).join(\", \")}?` : \"\"));\n}\nfunction assetByName(doc, q) {\n const exact = doc.assets.filter((x) => x.name === q || x.aliases.includes(q));\n if (exact.length === 1)\n return exact[0];\n if (exact.length > 1)\n return undefined;\n const loose = doc.assets.filter((x) => x.name.includes(q) || x.aliases.some((a) => a.includes(q)));\n return loose.length === 1 ? loose[0] : undefined;\n}\nexport function assetName(doc, id) {\n return doc.byId.get(id)?.label || id;\n}\nexport function stateName(doc, assetId, stateId) {\n const st = doc.byId.get(assetId)?.states.find((s) => s.id === stateId);\n return st?.name || stateId;\n}\nexport function allActions(doc) {\n return doc.episodes.flatMap((e) => e.scenes.flatMap((s) => s.actions));\n}\nconst KIND_OF = {\n ep: \"episode\", scn: \"scene\", ac: \"action\", act: \"actor\", loc: \"location\", prp: \"prop\", st: \"state\",\n};\n/** Delegates to the schema package so there is one definition of a valid id. */\nexport function newId(prefix, taken) {\n const id = generateV4Id(KIND_OF[prefix], taken);\n taken.add(id);\n step(\"newId\", `${id} (collision-checked against ${taken.size - 1} live ids)`);\n return id;\n}\n/**\n * Flush a bound document. Unbound documents (built by `parse` with no path) are\n * in-memory only, so this is a no-op for them \u2014 every mutation calls it, and a\n * CLI wants write-through while an in-process agent does not.\n */\nexport function save(doc) {\n if (!doc.path) {\n step(\"save\", \"skipped: document is not bound to a file\");\n return;\n }\n commit(doc, doc.path);\n}\n/** Write the document to `path` and bind it there. */\n/**\n * Write the document out. Binding is `load`/`parse`'s job, so committing an\n * unbound document does not bind it: a caller that commits a checkpoint mid-run\n * must stay unbound, or every later mutation's own `save` would start writing\n * the whole document to disk again.\n */\nexport function commit(doc, path = doc.path) {\n if (!path)\n throw new Error(\"commit needs a path: this document is not bound to a file\");\n const tmp = `${path}.tmp-${process.pid}`;\n fs.writeFileSync(tmp, JSON.stringify(doc.raw, null, 2) + \"\\n\");\n fs.renameSync(tmp, path);\n step(\"commit\", `${fs.statSync(path).size} bytes -> ${path} (tmp + atomic rename)`);\n}\n", "let sink = null;\nlet t0 = 0;\nexport function record() { sink = []; t0 = performance.now(); return sink; }\nexport function stop() { sink = null; }\nexport function step(fn, note) {\n if (sink)\n sink.push({ fn, note, ms: Math.round((performance.now() - t0) * 100) / 100 });\n}\n", "export const ACTION_TYPES = [\"action\", \"dialogue\", \"inner_thought\", \"transition\"];\nexport const ACTION_TYPE_SET = new Set(ACTION_TYPES);\nexport const NON_ACTOR_SPEAKER_KINDS = [\"system\", \"broadcast\", \"offscreen\", \"group\"];\nexport const NON_ACTOR_SPEAKER_KIND_SET = new Set(NON_ACTOR_SPEAKER_KINDS);\nexport const IMPORTANCE_TIERS = [\"featured\", \"background\"];\nexport const IMPORTANCE_TIER_SET = new Set(IMPORTANCE_TIERS);\nexport const ROLE_TYPES = [\"\u4E3B\u89D2\", \"\u914D\u89D2\"];\nexport const ROLE_TYPE_SET = new Set(ROLE_TYPES);\n// Scene time is part of the schema's closed vocabulary, not an ingest concern;\n// the alias table that maps free text onto these values stays in ingest.\nexport const SCENE_TIME_VALUES = [\"day\", \"night\", \"dawn\", \"dusk\"];\nexport const SCENE_TIME_SET = new Set(SCENE_TIME_VALUES);\nexport function isSceneTime(value) {\n return typeof value === \"string\" && SCENE_TIME_SET.has(value);\n}\nexport const SCENE_SPACE_VALUES = [\"interior\", \"exterior\"];\nexport const SCENE_SPACE_SET = new Set(SCENE_SPACE_VALUES);\n", "export function canonicalNameKey(name) {\n return name.normalize(\"NFKC\").toLowerCase();\n}\n", "function issueKey(issue) {\n return JSON.stringify([issue.code, issue.path, issue.message]);\n}\nfunction issueCounts(issues) {\n const counts = new Map();\n for (const issue of issues) {\n const key = issueKey(issue);\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n return counts;\n}\nexport function strictlyReducesValidationErrors(baseline, proposed) {\n if (baseline.ok || proposed.errors.length >= baseline.errors.length)\n return false;\n const baselineCounts = issueCounts(baseline.errors);\n const proposedCounts = issueCounts(proposed.errors);\n for (const [key, count] of proposedCounts) {\n if (count > (baselineCounts.get(key) ?? 0))\n return false;\n }\n return true;\n}\n/**\n * Issues present in `current` that were not already present in `baseline`,\n * counted by multiplicity. This is what lets an edit report the damage it did\n * without drowning the agent in problems the document already had.\n */\nexport function issuesIntroduced(baseline, current) {\n const budget = issueCounts(baseline);\n const fresh = [];\n for (const issue of current) {\n const key = issueKey(issue);\n const left = budget.get(key) ?? 0;\n if (left > 0)\n budget.set(key, left - 1);\n else\n fresh.push(issue);\n }\n return fresh;\n}\n", "// Script v4 identity grammar. Owns the alphabet, the prefixes, the patterns and\n// the generator so that nothing downstream has to restate them \u2014 a second copy\n// of this alphabet is a second definition of what a valid script is.\nimport { customAlphabet } from \"nanoid\";\nexport const V4_ID_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nexport const V4_ID_RANDOM_LENGTH = 6;\nexport const V4_ID_PREFIXES = {\n episode: \"ep\",\n scene: \"scn\",\n action: \"ac\",\n actor: \"act\",\n location: \"loc\",\n prop: \"prp\",\n state: \"st\",\n};\nconst randomSuffix = customAlphabet(V4_ID_ALPHABET, V4_ID_RANDOM_LENGTH);\nconst alphabetClass = `[${V4_ID_ALPHABET}]`;\nexport const V4_ID_PATTERNS = Object.fromEntries(Object.entries(V4_ID_PREFIXES).map(([kind, prefix]) => [\n kind,\n new RegExp(`^${prefix}${alphabetClass}{${V4_ID_RANDOM_LENGTH}}$`),\n]));\nexport function isV4Id(kind, value) {\n return typeof value === \"string\" && V4_ID_PATTERNS[kind].test(value);\n}\n/** Marks the one failure `generateV4Id` raises, so callers can map it without\n * catching everything the function might ever throw. */\nexport const ID_SPACE_EXHAUSTED = \"ID_SPACE_EXHAUSTED\";\nexport function generateV4Id(kind, existing = new Set(), generateSuffix = randomSuffix) {\n const prefix = V4_ID_PREFIXES[kind];\n for (let attempt = 0; attempt < 128; attempt++) {\n const candidate = `${prefix}${generateSuffix()}`;\n if (!existing.has(candidate))\n return candidate;\n }\n throw Object.assign(new Error(`Could not generate an unused ${kind} ID after 128 attempts.`), { code: ID_SPACE_EXHAUSTED });\n}\nexport function generateV4Ids(kind, count, existing = new Set()) {\n if (!Number.isSafeInteger(count) || count < 1) {\n throw new Error(`count must be a positive integer (got ${count}).`);\n }\n const seen = new Set(existing);\n const ids = [];\n while (ids.length < count) {\n const id = generateV4Id(kind, seen);\n seen.add(id);\n ids.push(id);\n }\n return ids;\n}\n", "export class TimestampParseError extends Error {\n input;\n constructor(input, message) {\n super(message);\n this.input = input;\n this.name = \"TimestampParseError\";\n }\n}\nconst MINUTE_SECOND_RE = /^(\\d+):(\\d{2})(?:\\.(\\d{1,3}))?$/;\nconst HOUR_MINUTE_SECOND_RE = /^(\\d+):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/;\nfunction fractionMilliseconds(raw) {\n return raw ? Number(raw.padEnd(3, \"0\")) : 0;\n}\nfunction requireSafeMilliseconds(raw, milliseconds) {\n if (!Number.isSafeInteger(milliseconds)) {\n throw new TimestampParseError(raw, \"Timestamp exceeds the supported numeric range.\");\n }\n return milliseconds;\n}\nfunction canonicalTimestamp(milliseconds, fraction) {\n const totalSeconds = Math.floor(milliseconds / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const fractionPart = fraction ? `.${fraction}` : \"\";\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}${fractionPart}`;\n }\n return `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}${fractionPart}`;\n}\nexport function parseTimestamp(raw) {\n const input = raw.trim();\n if (!input) {\n throw new TimestampParseError(raw, \"Timestamp must not be empty.\");\n }\n const hourMatch = input.match(HOUR_MINUTE_SECOND_RE);\n if (hourMatch) {\n const hours = Number(hourMatch[1]);\n const minutes = Number(hourMatch[2]);\n const seconds = Number(hourMatch[3]);\n const fraction = hourMatch[4];\n if (minutes > 59) {\n throw new TimestampParseError(raw, \"Hour-form timestamps require minutes between 00 and 59.\");\n }\n if (seconds > 59) {\n throw new TimestampParseError(raw, \"Timestamp seconds must be between 00 and 59.\");\n }\n const milliseconds = requireSafeMilliseconds(raw, ((hours * 60 + minutes) * 60 + seconds) * 1000 + fractionMilliseconds(fraction));\n return {\n canonical: canonicalTimestamp(milliseconds, fraction),\n milliseconds,\n fractionDigits: fraction?.length ?? 0,\n };\n }\n const minuteMatch = input.match(MINUTE_SECOND_RE);\n if (!minuteMatch) {\n throw new TimestampParseError(raw, \"Use M:SS, MM:SS, or H:MM:SS with an optional 1-3 digit fraction.\");\n }\n const minutes = Number(minuteMatch[1]);\n const seconds = Number(minuteMatch[2]);\n const fraction = minuteMatch[3];\n if (seconds > 59) {\n throw new TimestampParseError(raw, \"Timestamp seconds must be between 00 and 59.\");\n }\n const milliseconds = requireSafeMilliseconds(raw, (minutes * 60 + seconds) * 1000 + fractionMilliseconds(fraction));\n return {\n canonical: canonicalTimestamp(milliseconds, fraction),\n milliseconds,\n fractionDigits: fraction?.length ?? 0,\n };\n}\nexport function parseTimestampRange(raw) {\n const input = raw.trim();\n const parts = input.split(\"..\");\n if (parts.length > 2 || parts.some((part) => part.trim() === \"\")) {\n throw new TimestampParseError(raw, \"Use one timestamp or a closed range such as 00:10..00:20.\");\n }\n const first = parseTimestamp(parts[0]);\n const second = parts.length === 2 ? parseTimestamp(parts[1]) : first;\n return first.milliseconds <= second.milliseconds\n ? { start: first, end: second }\n : { start: second, end: first };\n}\nexport function timestampInRange(timestamp, range) {\n return timestamp.milliseconds >= range.start.milliseconds\n && timestamp.milliseconds <= range.end.milliseconds;\n}\nfunction timestampOfAction(action) {\n if (typeof action !== \"object\" || action === null || Array.isArray(action))\n return undefined;\n const extend = action.extend;\n if (typeof extend !== \"object\" || extend === null || Array.isArray(extend))\n return undefined;\n return extend.timestamp;\n}\n/**\n * Action timestamps mark simultaneous beats as well as sequential ones, so\n * equal timestamps are valid. Only a later Action moving backwards is invalid.\n */\nexport function validateActionTimestampOrder(actions, actionsPath, issue) {\n let previous = null;\n actions.forEach((action, actionIndex) => {\n const rawTimestamp = timestampOfAction(action);\n if (rawTimestamp === undefined)\n return;\n const timestampPath = `${actionsPath}[${actionIndex}].extend.timestamp`;\n if (typeof rawTimestamp !== \"string\") {\n issue(\"timestamp_invalid\", timestampPath, \"timestamp must be a string in M:SS, MM:SS, or H:MM:SS form\");\n return;\n }\n let timestamp;\n try {\n timestamp = parseTimestamp(rawTimestamp);\n }\n catch (error) {\n if (!(error instanceof TimestampParseError))\n throw error;\n issue(\"timestamp_invalid\", timestampPath, error.message);\n return;\n }\n if (previous !== null && timestamp.milliseconds < previous.timestamp.milliseconds) {\n issue(\"timestamp_out_of_order\", timestampPath, `timestamp ${timestamp.canonical} is earlier than Action ${previous.actionIndex + 1} timestamp ${previous.timestamp.canonical}; equal timestamps are allowed`);\n }\n previous = { actionIndex, timestamp };\n });\n}\n", "// Deterministic Script v3 structural + referential validator (\u00A79.9, revised).\n// Enforces v3 invariants: plain-text content, single scene-level location,\n// scene-level actors/props with materialized state, no legacy v2 fields\n// (state_changes / action.actor_id / scene.context / speakers[] / content spans).\nimport { ACTION_TYPES, IMPORTANCE_TIERS, NON_ACTOR_SPEAKER_KINDS } from \"./types.js\";\nimport { canonicalNameKey } from \"./names.js\";\nimport { validateActionTimestampOrder } from \"./timestamp.js\";\nimport { isSceneTime } from \"./types.js\";\nconst isObj = (v) => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst isArr = (v) => Array.isArray(v);\nconst isStr = (v) => typeof v === \"string\";\nconst ACTION_LEGACY = [\"state_changes\", \"actor_id\", \"speakers\", \"lines\"];\nexport function validateScriptV3(doc) {\n const errors = [];\n const warnings = [];\n const err = (code, path, message, repairHint) => errors.push({ code, path, message, ...(repairHint ? { repair_hint: repairHint } : {}) });\n const warn = (code, path, message) => warnings.push({ code, path, message });\n if (!isObj(doc))\n return { ok: false, errors: [{ code: \"not_object\", path: \"$\", message: \"script must be an object\" }], warnings };\n if (doc.version !== 3)\n err(\"version\", \"$.version\", \"version must be 3\");\n for (const key of [\"title\", \"worldview\", \"style\"])\n if (!isStr(doc[key]))\n err(\"field\", `$.${key}`, `${key} must be a string`);\n const stateIds = new Map();\n const idKind = new Map();\n const actorNames = new Map();\n const collect = (list, kind, idField, nameField, path) => {\n if (!isArr(list)) {\n err(\"field\", path, `${path} must be an array`);\n return;\n }\n list.forEach((raw, i) => {\n const p = `${path}[${i}]`;\n if (!isObj(raw)) {\n err(\"asset\", p, \"asset must be an object\");\n return;\n }\n const id = raw[idField];\n if (!isStr(id)) {\n err(\"asset_id\", `${p}.${idField}`, `${idField} required`);\n return;\n }\n if (idKind.has(id))\n err(\"dup_id\", `${p}.${idField}`, `duplicate id ${id}`);\n idKind.set(id, kind);\n if (!isStr(raw[nameField]))\n err(\"asset_name\", `${p}.${nameField}`, `${nameField} required`);\n else if (kind === \"actor\") {\n const nameKey = canonicalNameKey(raw[nameField]);\n const existingId = actorNames.get(nameKey);\n if (existingId !== undefined) {\n err(\"dup_actor_name\", `${p}.${nameField}`, `actor name ${raw[nameField]} already belongs to ${existingId}`);\n }\n else {\n actorNames.set(nameKey, id);\n }\n }\n if (!isStr(raw.importance) || !IMPORTANCE_TIERS.includes(raw.importance))\n err(\"importance\", `${p}.importance`, `importance must be one of ${IMPORTANCE_TIERS.join(\"|\")}`);\n if (!isStr(raw.description))\n err(\"asset_desc\", `${p}.description`, \"description must be a string\");\n const ids = new Set();\n const names = new Set();\n let defaults = 0;\n if (!isArr(raw.states) || raw.states.length === 0)\n err(\"states\", `${p}.states`, \"states must be a non-empty array\");\n else\n raw.states.forEach((st, j) => {\n const sp = `${p}.states[${j}]`;\n if (!isObj(st) || !isStr(st.state_id)) {\n err(\"state_id\", sp, \"state_id required\");\n return;\n }\n if (ids.has(st.state_id))\n err(\"dup_state\", sp, `duplicate state_id ${st.state_id}`);\n ids.add(st.state_id);\n if (st.state_id === \"default\")\n defaults++;\n if (!isStr(st.state_name))\n err(\"state_name\", `${sp}.state_name`, \"state_name required\");\n else {\n if (names.has(st.state_name))\n err(\"dup_state_name\", `${sp}.state_name`, `duplicate state_name ${st.state_name}`);\n names.add(st.state_name);\n }\n });\n if (isArr(raw.states) && defaults !== 1)\n err(\"default_state\", `${p}.states`, `exactly one 'default' state required, found ${defaults}`);\n stateIds.set(id, ids);\n });\n };\n collect(doc.actors, \"actor\", \"actor_id\", \"actor_name\", \"$.actors\");\n collect(doc.locations, \"location\", \"location_id\", \"location_name\", \"$.locations\");\n collect(doc.props, \"prop\", \"prop_id\", \"prop_name\", \"$.props\");\n const refState = (assetId, stateId, kind, path) => {\n if (idKind.get(assetId) !== kind) {\n err(\"ref\", path, `${kind} ${assetId} not found`);\n return;\n }\n if (stateId !== undefined && (!isStr(stateId) || !stateIds.get(assetId)?.has(stateId)))\n err(\"state_ref\", path, `state ${String(stateId)} not materialized on ${assetId}`);\n };\n const checkEntityList = (list, kind, idField, path) => {\n if (list === undefined) {\n err(\"field\", path, `${path} required (may be empty array)`);\n return;\n }\n if (!isArr(list)) {\n err(\"field\", path, `${path} must be an array`);\n return;\n }\n list.forEach((ref, i) => {\n if (!isObj(ref) || !isStr(ref[idField])) {\n err(\"ref\", `${path}[${i}]`, `${idField} required`);\n return;\n }\n refState(ref[idField], ref.state_id, kind, `${path}[${i}]`);\n });\n };\n const checkAction = (action, path, sceneActorIds, sceneAddress) => {\n if (!isObj(action)) {\n err(\"action\", path, \"action must be an object\");\n return;\n }\n for (const bad of ACTION_LEGACY)\n if (bad in action)\n err(\"legacy_field\", `${path}.${bad}`, `v3 forbids action.${bad}`);\n const type = action.type;\n if (!isStr(type) || !ACTION_TYPES.includes(type))\n err(\"action_type\", `${path}.type`, `invalid action type ${String(type)}`);\n if (!isStr(action.content))\n err(\"content\", `${path}.content`, \"content must be a plain-text string\");\n if (type === \"dialogue\" || type === \"inner_thought\") {\n const sp = action.speaker;\n if (!isObj(sp))\n err(\"speaker\", `${path}.speaker`, \"dialogue/inner_thought needs a speaker\");\n else if (\"kind\" in sp) {\n if (!isStr(sp.kind) || !NON_ACTOR_SPEAKER_KINDS.includes(sp.kind))\n err(\"speaker_kind\", `${path}.speaker.kind`, \"invalid non-actor speaker kind\");\n }\n else if (isStr(sp.actor_id)) {\n refState(sp.actor_id, sp.state_id, \"actor\", `${path}.speaker`);\n if (!sceneActorIds.has(sp.actor_id)) {\n const ownedStates = stateIds.get(sp.actor_id);\n const requestedState = isStr(sp.state_id) && ownedStates?.has(sp.state_id)\n ? sp.state_id\n : ownedStates?.has(\"default\")\n ? \"default\"\n : ownedStates?.values().next().value;\n const repairHint = sceneAddress && requestedState\n ? `scriptctl scene-ref ${sceneAddress} actor:${sp.actor_id} --state ${requestedState} -p \"$SCRIPT\"`\n : undefined;\n err(\"actor_not_in_scene\", `${path}.speaker.actor_id`, `actor ${sp.actor_id} is not referenced by this scene`, repairHint);\n }\n }\n else\n err(\"speaker\", `${path}.speaker`, \"speaker needs actor_id or kind\");\n }\n };\n const episodes = doc.episodes;\n if (!isArr(episodes))\n err(\"episodes\", \"$.episodes\", \"episodes must be an array\");\n else\n episodes.forEach((ep, ei) => {\n const ep_p = `$.episodes[${ei}]`;\n if (!isObj(ep) || !isStr(ep.episode_id)) {\n err(\"episode_id\", ep_p, \"episode_id required\");\n return;\n }\n if (!isArr(ep.scenes)) {\n err(\"scenes\", `${ep_p}.scenes`, \"scenes must be an array\");\n return;\n }\n ep.scenes.forEach((sc, si) => {\n const sc_p = `${ep_p}.scenes[${si}]`;\n if (!isObj(sc)) {\n err(\"scene\", sc_p, \"scene must be an object\");\n return;\n }\n if (\"context\" in sc)\n err(\"legacy_field\", `${sc_p}.context`, \"v3 forbids scene.context\");\n if (!isStr(sc.scene_id))\n err(\"scene_id\", sc_p, \"scene_id required\");\n const environment = sc.environment;\n if (environment === undefined || (isObj(environment) && (!isStr(environment.time) || environment.time.trim() === \"\"))) {\n warn(\"scene_time_missing\", `${sc_p}.environment.time`, \"scene time is required for production review\");\n }\n else if (!isObj(environment)\n || (environment.space !== undefined && !isStr(environment.space))\n || !isStr(environment.time)) {\n err(\"environment\", `${sc_p}.environment`, \"environment must contain optional string space and a time string\");\n }\n else if (!isSceneTime(environment.time)) {\n err(\"scene_time\", `${sc_p}.environment.time`, \"scene time must be day|night|dawn|dusk\");\n }\n const loc = sc.location;\n if (loc !== null) {\n if (!isObj(loc) || !isStr(loc.location_id))\n err(\"location\", `${sc_p}.location`, \"location must be null or {location_id}\");\n else\n refState(loc.location_id, loc.state_id, \"location\", `${sc_p}.location`);\n }\n checkEntityList(sc.actors, \"actor\", \"actor_id\", `${sc_p}.actors`);\n checkEntityList(sc.props, \"prop\", \"prop_id\", `${sc_p}.props`);\n if (isArr(sc.props)) {\n const propIds = new Set();\n sc.props.forEach((ref, i) => {\n if (!isObj(ref) || !isStr(ref.prop_id))\n return;\n if (propIds.has(ref.prop_id))\n err(\"dup_prop_ref\", `${sc_p}.props[${i}]`, `duplicate prop ref ${ref.prop_id}`);\n propIds.add(ref.prop_id);\n });\n }\n const sceneActorIds = new Set(isArr(sc.actors)\n ? sc.actors\n .filter((ref) => isObj(ref))\n .map((ref) => ref.actor_id)\n .filter((id) => isStr(id))\n : []);\n if (!isArr(sc.actions))\n err(\"actions\", `${sc_p}.actions`, \"actions must be an array\");\n else {\n const sceneAddress = isStr(sc.scene_id) ? `${ep.episode_id}/${sc.scene_id}` : undefined;\n sc.actions.forEach((a, ai) => checkAction(a, `${sc_p}.actions[${ai}]`, sceneActorIds, sceneAddress));\n validateActionTimestampOrder(sc.actions, `${sc_p}.actions`, err);\n }\n });\n });\n return { ok: errors.length === 0, errors, warnings };\n}\n", "import { ACTION_TYPES, IMPORTANCE_TIERS, NON_ACTOR_SPEAKER_KINDS, ROLE_TYPES, } from \"./types.js\";\nimport { isV4Id } from \"./ids.js\";\nimport { validateActionTimestampOrder } from \"./timestamp.js\";\nimport { isSceneTime } from \"./types.js\";\nconst isObj = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst isStr = (value) => typeof value === \"string\";\nconst isArr = (value) => Array.isArray(value);\nfunction isJsonValue(value) {\n if (value === null\n || typeof value === \"string\"\n || typeof value === \"number\"\n || typeof value === \"boolean\")\n return true;\n if (Array.isArray(value))\n return value.every(isJsonValue);\n return isObj(value) && Object.values(value).every(isJsonValue);\n}\nfunction validateExtend(value, path, err) {\n if (value !== undefined && (!isObj(value) || !Object.values(value).every(isJsonValue))) {\n err(\"extend\", path, \"extend must be an object containing JSON values\");\n }\n}\nfunction isSorted(values) {\n for (let index = 1; index < values.length; index++) {\n if (values[index - 1] > values[index])\n return false;\n }\n return true;\n}\nexport function validateScriptV4(doc) {\n const errors = [];\n const warnings = [];\n const err = (code, path, message, repairHint) => errors.push({ code, path, message, ...(repairHint ? { repair_hint: repairHint } : {}) });\n const warn = (code, path, message, repairHint) => warnings.push({ code, path, message, ...(repairHint ? { repair_hint: repairHint } : {}) });\n if (!isObj(doc)) {\n return {\n ok: false,\n errors: [{ code: \"not_object\", path: \"$\", message: \"script must be an object\" }],\n warnings,\n };\n }\n if (doc.version !== 4)\n err(\"version\", \"$.version\", \"version must be 4\");\n for (const key of [\"title\", \"worldview\", \"style\"]) {\n if (!isStr(doc[key]))\n err(\"field\", `$.${key}`, `${key} must be a string`);\n }\n for (const key of [\"worldview_raw\", \"synopsis\", \"logline\", \"theme\"]) {\n if (doc[key] !== undefined && !isStr(doc[key]))\n err(\"field\", `$.${key}`, `${key} must be a string`);\n }\n if (doc.main_characters !== undefined\n && (!isArr(doc.main_characters)\n || !doc.main_characters.every((item) => isObj(item) && isStr(item.name) && isStr(item.role)))) {\n err(\"main_characters\", \"$.main_characters\", \"main_characters must contain {name, role} string records\");\n }\n validateExtend(doc.extend, \"$.extend\", err);\n const assetKinds = new Map();\n const stateIds = new Map();\n const actorNames = new Set();\n const collectAssets = (list, kind, idField, nameField, path) => {\n if (!isArr(list)) {\n err(\"field\", path, `${path} must be an array`);\n return;\n }\n const ids = new Set();\n list.forEach((raw, index) => {\n const itemPath = `${path}[${index}]`;\n if (!isObj(raw)) {\n err(\"asset\", itemPath, \"asset must be an object\");\n return;\n }\n const id = raw[idField];\n if (!isV4Id(kind, id)) {\n err(\"asset_id\", `${itemPath}.${idField}`, `${idField} must be ${kind} ID`);\n return;\n }\n if (ids.has(id))\n err(\"dup_id\", `${itemPath}.${idField}`, `duplicate ${idField} ${id}`);\n ids.add(id);\n assetKinds.set(id, kind);\n if (!isStr(raw[nameField]) || raw[nameField].trim() === \"\") {\n err(\"asset_name\", `${itemPath}.${nameField}`, `${nameField} must be a non-empty string`);\n }\n else if (kind === \"actor\") {\n const nameKey = raw[nameField].trim().toLocaleLowerCase();\n if (actorNames.has(nameKey)) {\n err(\"dup_actor_name\", `${itemPath}.${nameField}`, `duplicate actor name ${raw[nameField]}`);\n }\n actorNames.add(nameKey);\n }\n if (!isStr(raw.importance) || !IMPORTANCE_TIERS.includes(raw.importance)) {\n err(\"importance\", `${itemPath}.importance`, `importance must be ${IMPORTANCE_TIERS.join(\"|\")}`);\n }\n if (kind === \"actor\"\n && raw.role_type !== undefined\n && (!isStr(raw.role_type) || !ROLE_TYPES.includes(raw.role_type))) {\n err(\"role_type\", `${itemPath}.role_type`, `role_type must be ${ROLE_TYPES.join(\"|\")}`);\n }\n if (!isStr(raw.description))\n err(\"asset_desc\", `${itemPath}.description`, \"description must be a string\");\n if (raw.aliases !== undefined\n && (!isArr(raw.aliases) || !raw.aliases.every(isStr))) {\n err(\"aliases\", `${itemPath}.aliases`, \"aliases must be an array of strings\");\n }\n else if (isArr(raw.aliases) && raw.aliases.every(isStr)) {\n const seenAliases = new Set();\n const assetName = isStr(raw[nameField]) ? raw[nameField] : \"\";\n raw.aliases.forEach((alias, aliasIndex) => {\n if (alias === \"\") {\n err(\"alias_empty\", `${itemPath}.aliases[${aliasIndex}]`, \"alias must not be empty\");\n }\n if (alias === assetName) {\n err(\"alias_equals_name\", `${itemPath}.aliases[${aliasIndex}]`, \"alias must differ from the asset name\");\n }\n if (seenAliases.has(alias)) {\n err(\"dup_alias\", `${itemPath}.aliases[${aliasIndex}]`, `duplicate alias ${alias}`);\n }\n seenAliases.add(alias);\n });\n }\n validateExtend(raw.extend, `${itemPath}.extend`, err);\n const ownerStates = new Set();\n const ownerStateNames = new Set();\n let defaults = 0;\n if (!isArr(raw.states) || raw.states.length === 0) {\n err(\"states\", `${itemPath}.states`, \"states must be a non-empty array\");\n }\n else {\n raw.states.forEach((state, stateIndex) => {\n const statePath = `${itemPath}.states[${stateIndex}]`;\n if (!isObj(state)) {\n err(\"state\", statePath, \"state must be an object\");\n return;\n }\n const stateId = state.state_id;\n if (stateId !== \"default\" && !isV4Id(\"state\", stateId)) {\n err(\"state_id\", `${statePath}.state_id`, \"state_id must be default or st plus six Base58 characters\");\n return;\n }\n if (ownerStates.has(stateId))\n err(\"dup_state\", `${statePath}.state_id`, `duplicate state_id ${stateId}`);\n ownerStates.add(stateId);\n if (stateId === \"default\")\n defaults++;\n if (!isStr(state.state_name) || state.state_name.trim() === \"\") {\n err(\"state_name\", `${statePath}.state_name`, \"state_name must be a non-empty string\");\n }\n else {\n if (ownerStateNames.has(state.state_name)) {\n err(\"dup_state_name\", `${statePath}.state_name`, `duplicate state_name ${state.state_name}`);\n }\n ownerStateNames.add(state.state_name);\n }\n if (!isStr(state.description))\n err(\"state_description\", `${statePath}.description`, \"description must be a string\");\n validateExtend(state.extend, `${statePath}.extend`, err);\n });\n }\n if (defaults !== 1) {\n err(\"default_state\", `${itemPath}.states`, `exactly one default state required, found ${defaults}`);\n }\n stateIds.set(id, ownerStates);\n });\n };\n collectAssets(doc.actors, \"actor\", \"actor_id\", \"actor_name\", \"$.actors\");\n collectAssets(doc.locations, \"location\", \"location_id\", \"location_name\", \"$.locations\");\n collectAssets(doc.props, \"prop\", \"prop_id\", \"prop_name\", \"$.props\");\n const validateStateSet = (assetId, rawStateIds, path) => {\n if (!isArr(rawStateIds) || rawStateIds.length === 0 || !rawStateIds.every(isStr)) {\n err(\"state_ids\", path, \"state_ids must be a non-empty array of strings\");\n return [];\n }\n const ids = rawStateIds;\n const seen = new Set();\n ids.forEach((stateId, index) => {\n if (seen.has(stateId))\n err(\"dup_state_ref\", `${path}[${index}]`, `duplicate state_id ${stateId}`);\n seen.add(stateId);\n if (!stateIds.get(assetId)?.has(stateId)) {\n err(\"state_ref\", `${path}[${index}]`, `state ${stateId} not found on ${assetId}`);\n }\n });\n if (!isSorted(ids))\n err(\"state_ids_order\", path, \"state_ids must be sorted lexically\");\n return ids;\n };\n const episodeIds = new Set();\n const sceneIds = new Set();\n const actionIds = new Set();\n if (!isArr(doc.episodes)) {\n err(\"episodes\", \"$.episodes\", \"episodes must be an array\");\n }\n else {\n doc.episodes.forEach((episode, episodeIndex) => {\n const episodePath = `$.episodes[${episodeIndex}]`;\n if (!isObj(episode)) {\n err(\"episode\", episodePath, \"episode must be an object\");\n return;\n }\n if (!isV4Id(\"episode\", episode.episode_id)) {\n err(\"episode_id\", `${episodePath}.episode_id`, \"episode_id must be ep plus six Base58 characters\");\n }\n else {\n if (episodeIds.has(episode.episode_id)) {\n err(\"dup_episode_id\", `${episodePath}.episode_id`, `duplicate episode_id ${episode.episode_id}`);\n }\n episodeIds.add(episode.episode_id);\n }\n for (const key of [\"title\", \"synopsis\"]) {\n if (episode[key] !== undefined && !isStr(episode[key])) {\n err(\"field\", `${episodePath}.${key}`, `${key} must be a string`);\n }\n }\n validateExtend(episode.extend, `${episodePath}.extend`, err);\n if (!isArr(episode.scenes)) {\n err(\"scenes\", `${episodePath}.scenes`, \"scenes must be an array\");\n return;\n }\n episode.scenes.forEach((scene, sceneIndex) => {\n const scenePath = `${episodePath}.scenes[${sceneIndex}]`;\n if (!isObj(scene)) {\n err(\"scene\", scenePath, \"scene must be an object\");\n return;\n }\n if (!isV4Id(\"scene\", scene.scene_id)) {\n err(\"scene_id\", `${scenePath}.scene_id`, \"scene_id must be scn plus six Base58 characters\");\n }\n else {\n if (sceneIds.has(scene.scene_id)) {\n err(\"dup_scene_id\", `${scenePath}.scene_id`, `duplicate scene_id ${scene.scene_id}`);\n }\n sceneIds.add(scene.scene_id);\n }\n validateExtend(scene.extend, `${scenePath}.extend`, err);\n if (scene.environment === undefined\n || (isObj(scene.environment)\n && (!isStr(scene.environment.time) || scene.environment.time.trim() === \"\"))) {\n warn(\"scene_time_missing\", `${scenePath}.environment.time`, \"scene time is required for production review\");\n }\n else if (!isObj(scene.environment)\n || (scene.environment.space !== undefined && !isStr(scene.environment.space))\n || !isStr(scene.environment.time)) {\n err(\"environment\", `${scenePath}.environment`, \"environment must contain optional string space and a time string\");\n }\n else if (!isSceneTime(scene.environment.time)) {\n err(\"scene_time\", `${scenePath}.environment.time`, \"scene time must be day|night|dawn|dusk\");\n }\n if (scene.location !== null) {\n if (!isObj(scene.location) || !isV4Id(\"location\", scene.location.location_id)) {\n err(\"location\", `${scenePath}.location`, \"location must be null or a typed v4 location reference\");\n }\n else {\n if (\"state_id\" in scene.location) {\n err(\"v3_field\", `${scenePath}.location.state_id`, \"Script v4 scene references use state_ids\");\n }\n if (assetKinds.get(scene.location.location_id) !== \"location\") {\n err(\"location_ref\", `${scenePath}.location.location_id`, `location ${scene.location.location_id} not found`);\n }\n validateStateSet(scene.location.location_id, scene.location.state_ids, `${scenePath}.location.state_ids`);\n }\n }\n const sceneActorStates = new Map();\n const validateRefs = (refs, kind, idField, path) => {\n if (!isArr(refs)) {\n err(\"field\", path, `${path} must be an array`);\n return;\n }\n const seen = new Set();\n refs.forEach((ref, refIndex) => {\n const refPath = `${path}[${refIndex}]`;\n if (!isObj(ref) || !isV4Id(kind, ref[idField])) {\n err(\"ref\", refPath, `${idField} must be a typed v4 ID`);\n return;\n }\n const assetId = ref[idField];\n if (\"state_id\" in ref) {\n err(\"v3_field\", `${refPath}.state_id`, \"Script v4 scene references use state_ids\");\n }\n if (seen.has(assetId))\n err(\"dup_asset_ref\", `${refPath}.${idField}`, `duplicate ${kind} ref ${assetId}`);\n seen.add(assetId);\n if (assetKinds.get(assetId) !== kind) {\n err(\"asset_ref\", `${refPath}.${idField}`, `${kind} ${assetId} not found`);\n }\n const ids = validateStateSet(assetId, ref.state_ids, `${refPath}.state_ids`);\n if (kind === \"actor\")\n sceneActorStates.set(assetId, new Set(ids));\n });\n };\n validateRefs(scene.actors, \"actor\", \"actor_id\", `${scenePath}.actors`);\n validateRefs(scene.props, \"prop\", \"prop_id\", `${scenePath}.props`);\n if (!isArr(scene.actions)) {\n err(\"actions\", `${scenePath}.actions`, \"actions must be an array\");\n return;\n }\n scene.actions.forEach((action, actionIndex) => {\n const actionPath = `${scenePath}.actions[${actionIndex}]`;\n if (!isObj(action)) {\n err(\"action\", actionPath, \"action must be an object\");\n return;\n }\n if (!isV4Id(\"action\", action.action_id)) {\n err(\"action_id\", `${actionPath}.action_id`, \"action_id must be ac plus six Base58 characters\");\n }\n else {\n if (actionIds.has(action.action_id)) {\n err(\"dup_action_id\", `${actionPath}.action_id`, `duplicate action_id ${action.action_id}`);\n }\n actionIds.add(action.action_id);\n }\n if (!isStr(action.type) || !ACTION_TYPES.includes(action.type)) {\n err(\"action_type\", `${actionPath}.type`, `invalid action type ${String(action.type)}`);\n }\n if (!isStr(action.content))\n err(\"content\", `${actionPath}.content`, \"content must be a string\");\n if (\"emotion\" in action)\n err(\"v3_field\", `${actionPath}.emotion`, \"Script v4 does not allow emotion\");\n validateExtend(action.extend, `${actionPath}.extend`, err);\n const speaking = action.type === \"dialogue\" || action.type === \"inner_thought\";\n if (speaking) {\n if (action.parenthetical !== undefined && !isStr(action.parenthetical)) {\n err(\"parenthetical\", `${actionPath}.parenthetical`, \"parenthetical must be a string\");\n }\n if (!isObj(action.speaker)) {\n err(\"speaker\", `${actionPath}.speaker`, \"dialogue/inner_thought requires a speaker\");\n }\n else if (isStr(action.speaker.actor_id)) {\n if (\"kind\" in action.speaker || \"label\" in action.speaker) {\n err(\"speaker_shape\", `${actionPath}.speaker`, \"actor speaker cannot contain non-actor speaker fields\");\n }\n const actorId = action.speaker.actor_id;\n if (!isV4Id(\"actor\", actorId) || assetKinds.get(actorId) !== \"actor\") {\n err(\"speaker_actor\", `${actionPath}.speaker.actor_id`, `actor ${actorId} not found`);\n }\n const sceneStates = sceneActorStates.get(actorId);\n const ownedStates = stateIds.get(actorId);\n const speakerState = isStr(action.speaker.state_id)\n && ownedStates?.has(action.speaker.state_id)\n ? action.speaker.state_id\n : undefined;\n const defaultState = ownedStates?.has(\"default\")\n ? \"default\"\n : ownedStates?.values().next().value;\n const repairStates = speakerState ? [speakerState] : defaultState ? [defaultState] : [];\n const sceneRefRepair = isV4Id(\"scene\", scene.scene_id)\n && isV4Id(\"actor\", actorId)\n && repairStates.length > 0\n ? `scriptctl scene-ref ${scene.scene_id} ${actorId} ${repairStates.map((id) => `--state ${id}`).join(\" \")} -p \"$SCRIPT\"`\n : undefined;\n if (!sceneStates) {\n err(\"actor_not_in_scene\", `${actionPath}.speaker.actor_id`, `actor ${actorId} is not referenced by this scene`, sceneRefRepair);\n }\n if (action.speaker.state_id !== undefined\n && (!isStr(action.speaker.state_id) || !sceneStates?.has(action.speaker.state_id))) {\n const nextStates = speakerState\n ? [...new Set([...(sceneStates ?? []), speakerState])].sort()\n : [];\n const stateRepair = isV4Id(\"scene\", scene.scene_id)\n && isV4Id(\"actor\", actorId)\n && nextStates.length > 0\n ? `scriptctl scene-ref ${scene.scene_id} ${actorId} ${nextStates.map((id) => `--state ${id}`).join(\" \")} -p \"$SCRIPT\"`\n : sceneRefRepair;\n err(\"speaker_state\", `${actionPath}.speaker.state_id`, `speaker state ${String(action.speaker.state_id)} is not in this scene's actor state_ids`, stateRepair);\n }\n }\n else if (isStr(action.speaker.kind)) {\n if (\"actor_id\" in action.speaker || \"state_id\" in action.speaker) {\n err(\"speaker_shape\", `${actionPath}.speaker`, \"non-actor speaker cannot contain actor speaker fields\");\n }\n if (!NON_ACTOR_SPEAKER_KINDS.includes(action.speaker.kind)) {\n err(\"speaker_kind\", `${actionPath}.speaker.kind`, \"invalid non-actor speaker kind\");\n }\n if (action.speaker.label !== undefined && !isStr(action.speaker.label)) {\n err(\"speaker_label\", `${actionPath}.speaker.label`, \"speaker label must be a string\");\n }\n }\n else {\n err(\"speaker\", `${actionPath}.speaker`, \"speaker needs actor_id or kind\");\n }\n }\n else {\n if (\"parenthetical\" in action) {\n err(\"parenthetical_type\", `${actionPath}.parenthetical`, \"parenthetical only belongs to speaking actions\");\n }\n if (\"speaker\" in action) {\n err(\"speaker_type\", `${actionPath}.speaker`, \"speaker only belongs to speaking actions\");\n }\n }\n if (action.transition_prompt !== undefined) {\n const prompt = action.transition_prompt;\n if (!isObj(prompt)\n || !isStr(prompt.target)\n || !isStr(prompt.process)\n || prompt.process === \"\"\n || !isStr(prompt.contrast)\n || prompt.contrast === \"\") {\n err(\"transition_prompt\", `${actionPath}.transition_prompt`, \"transition_prompt requires non-empty target/process/contrast\");\n }\n else if (!assetKinds.has(prompt.target)) {\n err(\"transition_target\", `${actionPath}.transition_prompt.target`, `asset ${prompt.target} not found`);\n }\n }\n });\n validateActionTimestampOrder(scene.actions, `${scenePath}.actions`, err);\n });\n });\n }\n return { ok: errors.length === 0, errors, warnings };\n}\n", "// The prose codec: one screenplay-shaped text format that `read` emits and\n// `write` accepts back. One format for the agent to learn, and the round-trip\n// is the contract (see `sc selfcheck`).\nimport { assetName, stateName } from \"./model.js\";\nimport { step } from \"./trace.js\";\nconst NON_ACTOR = {\n system: \"\u65C1\u767D\", broadcast: \"\u5E7F\u64AD\", offscreen: \"\u753B\u5916\", group: \"\u7FA4\u58F0\",\n};\nconst THOUGHT = \"\u5FC3\u58F0\";\nfunction speakerLabel(doc, sp) {\n if (sp.kind)\n return NON_ACTOR[sp.kind] ?? sp.kind;\n const name = assetName(doc, sp.id);\n // Always show a speaker state that exists. Hiding it when the scene \"pins it\n // down\" saved a few characters and silently dropped 1001 of them on the first\n // whole-script rewrite: a field the view omits is a field write must guess.\n return sp.state ? `${name}\u00B7${stateName(doc, sp.id, sp.state)}` : name;\n}\nexport function formatAction(doc, a, gutter, opts = {}) {\n const pad = (opts.plain ? \"\" : a.anchor).padEnd(gutter);\n const ts = !opts.plain && a.ts ? `${a.ts} ` : \"\";\n const body = (() => {\n if (a.type === \"transition\")\n return `\u2192 ${a.content}`;\n if (a.type === \"dialogue\" || a.type === \"inner_thought\") {\n const who = a.speaker ? speakerLabel(doc, a.speaker) : \"?\";\n const notes = [a.type === \"inner_thought\" ? THOUGHT : \"\", a.paren ?? \"\"].filter(Boolean);\n const label = a.speaker?.kind && a.speaker.label ? `${who}\u00B7${a.speaker.label}` : who;\n return `${label}${notes.length ? `(${notes.join(\"/\")})` : \"\"}\uFF1A${a.content}`;\n }\n return a.content;\n })();\n return `${pad}${pad ? \" \" : \"\"}${ts}${body}`.replace(/\\n/g, \"\\\\n\");\n}\nfunction refText(doc, r) {\n const name = assetName(doc, r.id);\n // The bare name means exactly the lone `default` state. Anything else lists\n // every bound state by name, `default` included \u2014 dropping it here would make\n // the header lossy the moment an episode is written back.\n if (r.states.length === 1 && r.states[0] === \"default\")\n return name;\n return `${name}(${r.states.map((x) => stateName(doc, r.id, x)).join(\"+\")})`;\n}\nexport function formatSceneHead(doc, s) {\n const env = [s.env?.space, s.env?.time].filter(Boolean).join(\"/\").toUpperCase();\n const where = s.location ? refText(doc, s.location) : \"\u2014\";\n const head = `## ${s.ep.no}-${s.no} ${s.anchor === `${s.ep.no}-${s.no}` ? s.id : s.anchor}`\n + ` ${env || \"\u2014\"} ${where} ${s.actions.length} actions`;\n const cast = s.actors.map((r) => refText(doc, r)).join(\", \");\n const props = s.props.map((r) => refText(doc, r)).join(\", \");\n const meta = [cast && `cast: ${cast}`, props && `props: ${props}`].filter(Boolean).join(\" \");\n return meta ? `${head}\\n# ${meta}` : head;\n}\nexport function formatScene(doc, s, opts = {}) {\n const gutter = opts.plain ? 0 : Math.max(0, ...s.actions.map((a) => a.anchor.length));\n step(\"formatScene\", `${s.anchor}: ${s.actions.length} actions, gutter=${gutter}`);\n return [formatSceneHead(doc, s), ...s.actions.map((a) => formatAction(doc, a, gutter, opts))].join(\"\\n\");\n}\nconst ANCHOR_RE = /^([A-Za-z][A-Za-z0-9_]*|\\d+(?:-\\d+){0,2})\\s\\s+/;\n/**\n * Parse one body line back. `known(name)` decides whether a `X\uFF1A` prefix is a\n * real speaker \u2014 without it, an action line like `\u7279\u5199\uFF1A\u5979\u8F6C\u8EAB` would be\n * misread as dialogue.\n */\nexport function parseLine(line, known) {\n let rest = line.trimEnd();\n if (!rest.trim())\n return null;\n let anchor;\n const m = rest.match(ANCHOR_RE);\n if (m) {\n anchor = m[1];\n rest = rest.slice(m[0].length);\n }\n rest = rest.replace(/\\\\n/g, \"\\n\");\n let ts;\n const tm = rest.match(/^((?:\\d+:)?\\d+:\\d{2}(?:\\.\\d{1,3})?)\\s/);\n if (tm) {\n ts = tm[1];\n rest = rest.slice(tm[0].length);\n }\n if (rest.startsWith(\"\u2192\"))\n return { anchor, ts, type: \"transition\", content: rest.slice(1).trim() };\n const colon = rest.indexOf(\"\uFF1A\");\n if (colon > 0) {\n const head = rest.slice(0, colon);\n const hm = head.match(/^([^()]+)(?:\\((.*)\\))?$/);\n if (hm && known(hm[1].trim())) {\n const notes = (hm[2] ?? \"\").split(\"/\").map((s) => s.trim()).filter(Boolean);\n const thought = notes[0] === THOUGHT;\n const paren = (thought ? notes.slice(1) : notes).join(\"/\");\n return {\n anchor, ts, type: thought ? \"inner_thought\" : \"dialogue\",\n speakerName: hm[1].trim(), paren: paren || undefined,\n content: rest.slice(colon + 1).trim(),\n };\n }\n }\n return { anchor, ts, type: \"action\", content: rest.trim() };\n}\nconst SCENE_ID = /^(scn[1-9A-HJ-NP-Za-km-z]{6}|scn_\\d+)$/;\nconst ENV_WORD = /^[A-Z.\\/]+$/;\nconst COUNT = /^\\d+\\s+actions?$/;\nconst SPACE = { EXT: \"exterior\", EXTERIOR: \"exterior\", INT: \"interior\", INTERIOR: \"interior\" };\n/**\n * Parse a `## \u2026` scene header plus its optional `# cast: \u2026 props: \u2026` line.\n * Tokens are matched by shape, not position, so a hand-written new scene can\n * drop the ordinal, the id and the action count and still parse.\n */\n/**\n * Split a scene block into its two header lines and its body. Positional, not\n * pattern-matched: an action line may legitimately start with `#`, and guessing\n * would silently swallow it.\n */\nexport function splitBlock(lines) {\n const i = lines.findIndex((l) => l.startsWith(\"##\"));\n if (i < 0)\n return { body: lines };\n const hasMeta = lines[i + 1]?.startsWith(\"#\") && !lines[i + 1].startsWith(\"##\");\n const body = lines.filter((_, n) => n !== i && !(hasMeta && n === i + 1));\n return { head: lines[i], meta: hasMeta ? lines[i + 1] : undefined, body };\n}\nexport function parseHead(headLine, metaLine) {\n const out = { env: {}, cast: [], props: [] };\n const toks = headLine.replace(/^##\\s*/, \"\").split(/\\s{2,}/).map((t) => t.trim()).filter(Boolean);\n for (const t of toks) {\n if (/^\\d+-\\d+$/.test(t) || COUNT.test(t))\n continue; // ordinal / derived count\n if (SCENE_ID.test(t)) {\n out.anchor = t;\n continue;\n }\n if (ENV_WORD.test(t) && t !== \"\u2014\") {\n const [a, b] = t.split(\"/\");\n if (a)\n out.env.space = SPACE[a] ?? a.toLowerCase();\n if (b)\n out.env.time = b.toLowerCase();\n continue;\n }\n if (t !== \"\u2014\" && out.location === undefined)\n out.location = t;\n }\n if (metaLine) {\n const meta = metaLine.replace(/^#\\s*/, \"\");\n const cast = meta.match(/cast:\\s*([^]*?)(?:\\s\\sprops:|$)/);\n const props = meta.match(/props:\\s*([^]*)$/);\n const split = (v) => (v ?? \"\").split(\",\").map((x) => x.trim()).filter(Boolean);\n out.cast = split(cast?.[1]);\n out.props = split(props?.[1]);\n }\n return out;\n}\n/** `\u540D\u5B57(\u72B6\u6001+\u72B6\u6001)` -> name plus state names; a bare name means `default`. */\nexport function parseRefText(text) {\n const m = text.trim().match(/^(.*?)\\s*\\(([^)]*)\\)$/);\n if (!m)\n return { name: text.trim(), states: [] };\n return { name: m[1].trim(), states: m[2].split(\"+\").map((x) => x.trim()).filter(Boolean) };\n}\n", "import { parseTimestamp, TimestampParseError } from \"./schema/index.js\";\nimport { step } from \"./trace.js\";\nfunction fail(message, detail) {\n throw Object.assign(new Error(message), detail);\n}\n/**\n * The whole script as an ordered timeline. Addresses match what the CLI has\n * always emitted: v4 action ids, and `ep/scn#idx` for v3.\n */\nexport function spanPoints(doc) {\n return doc.episodes.flatMap((ep) => ep.scenes.flatMap((scene) => scene.actions.map((a, index) => ({\n address: doc.version === 4 ? a.anchor : `${ep.id}/${scene.id}#${index}`,\n episodeId: ep.id,\n episodeNo: ep.no,\n timestamp: a.ts,\n }))));\n}\nfunction stamp(point) {\n try {\n return parseTimestamp(point.timestamp ?? \"\");\n }\n catch (error) {\n if (!(error instanceof TimestampParseError))\n throw error;\n return fail(`Action ${point.address} has an invalid stored timestamp.`, {\n code: \"ACTION_SPAN_TIMESTAMP_INVALID\",\n hint: `Fix it with \\`scriptctl timestamp ${point.address} --set <time>\\` or remove it.`,\n data: {\n expected: [\"valid action.extend.timestamp\"],\n actual: [`${point.address}: ${JSON.stringify(point.timestamp ?? \"\")}`],\n },\n });\n }\n}\nfunction nonMonotonic(previous, current) {\n return fail(\"Action timestamps run backward within the selected episode.\", {\n code: \"ACTION_SPAN_TIMESTAMP_NON_MONOTONIC\",\n hint: \"Fix the stored timestamps so they do not move backward in document order, then rerun `actions --span`.\",\n data: { actual: [`${previous.address}: ${previous.timestamp}`, `${current.address}: ${current.timestamp}`] },\n });\n}\nexport function resolveSpan(timeline, selectedAddresses) {\n if (selectedAddresses.length === 0) {\n fail(\"The action selection matched nothing.\", {\n code: \"ACTION_SPAN_NO_MATCH\",\n hint: \"Check the selector with `scriptctl actions` and rerun with `--span`.\",\n data: { actual: [\"0 matched actions\"] },\n });\n }\n const wanted = new Set(selectedAddresses);\n const selected = timeline.filter((point) => wanted.has(point.address));\n if (selected.length !== wanted.size) {\n fail(\"The resolved action selection is inconsistent with the script timeline.\", {\n code: \"ACTION_SPAN_SELECTION_INCONSISTENT\",\n data: {\n expected: [`${wanted.size} timeline actions`],\n actual: [`${selected.length} timeline actions`],\n },\n });\n }\n const episodeIds = new Set(selected.map((point) => point.episodeId));\n if (episodeIds.size !== 1) {\n fail(\"An action timestamp span must stay within one episode.\", {\n code: \"ACTION_SPAN_CROSSES_EPISODES\",\n hint: \"Split the selector into one `actions --span` call per episode.\",\n data: { actual: [...episodeIds] },\n });\n }\n const first = selected[0], last = selected[selected.length - 1];\n if (!first.timestamp) {\n fail(`The first selected Action ${first.address} has no timestamp.`, {\n code: \"ACTION_SPAN_START_TIMESTAMP_MISSING\",\n hint: `Set it with \\`scriptctl timestamp ${first.address} --set <time>\\`, then rerun.`,\n data: { actual: [first.address] },\n });\n }\n const start = stamp(first);\n let prevPoint = first, prev = start, lastSelected = \"\";\n for (const point of selected) {\n if (!point.timestamp)\n continue;\n const ts = stamp(point);\n if (ts.milliseconds < prev.milliseconds)\n nonMonotonic(prevPoint, point);\n prevPoint = point;\n prev = ts;\n if (point.address === last.address)\n lastSelected = ts.canonical;\n }\n // The exclusive end is the next *later* timestamp still inside this episode;\n // equal neighbours are legal and do not close the window.\n const lastIndex = timeline.findIndex((point) => point.address === last.address);\n let boundary;\n let boundaryTs;\n for (let i = lastIndex + 1; i < timeline.length; i += 1) {\n const candidate = timeline[i];\n if (candidate.episodeId !== first.episodeId)\n break;\n if (!candidate.timestamp)\n continue;\n const ts = stamp(candidate);\n if (ts.milliseconds < prev.milliseconds)\n nonMonotonic(prevPoint, candidate);\n if (ts.milliseconds === prev.milliseconds)\n continue;\n boundary = candidate;\n boundaryTs = ts;\n break;\n }\n step(\"span\", `${first.episodeId} ${start.canonical}..${boundaryTs?.canonical ?? \"(open)\"}`\n + ` over ${selected.length} action(s)`);\n return {\n episode_id: first.episodeId,\n ep_no: first.episodeNo,\n start_timestamp: start.canonical,\n last_selected_timestamp: lastSelected,\n end_timestamp: boundaryTs?.canonical ?? \"\",\n end_open: boundaryTs === undefined,\n end_exclusive: true,\n start_action: first.address,\n last_action: last.address,\n end_boundary_action: boundary?.address ?? \"\",\n matched_actions: selected.length,\n };\n}\nexport const SPAN_COLUMNS = [\n \"episode_id\", \"ep_no\", \"start_timestamp\", \"last_selected_timestamp\",\n \"end_timestamp\", \"end_open\", \"end_exclusive\", \"start_action\", \"last_action\",\n \"end_boundary_action\", \"matched_actions\",\n];\n/** Timeline addresses for the actions a caller already selected. */\nexport function spanAddresses(doc, actions) {\n return actions.map((a) => {\n if (doc.version === 4)\n return a.anchor;\n const index = a.scene.actions.indexOf(a);\n return `${a.scene.ep.id}/${a.scene.id}#${index}`;\n });\n}\n", "// The agent-facing surface: four verbs over script.json.\n//\n// read(addr?) orient / read prose / inspect an asset \u2014 zoom by address\n// find(query) locate by text, speaker or type -> anchors + match window\n// edit(ops) surgical field-level changes on explicit anchors\n// write(addr,text) replace a scene from the same prose `read` emits\nimport { allActions, assetName, commit, load, newId, parse, resolve, save, stateName, } from \"./model.js\";\nimport { formatAction, formatScene, formatSceneHead, parseHead, parseLine, parseRefText, splitBlock, } from \"./text.js\";\nimport { step } from \"./trace.js\";\nimport { SPAN_COLUMNS, resolveSpan, spanAddresses, spanPoints } from \"./span.js\";\nimport { ACTION_TYPES, ACTION_TYPE_SET, IMPORTANCE_TIERS, IMPORTANCE_TIER_SET, ROLE_TYPES, ROLE_TYPE_SET, SCENE_SPACE_VALUES, SCENE_SPACE_SET, SCENE_TIME_VALUES, SCENE_TIME_SET, issuesIntroduced, parseTimestamp, TimestampParseError, validateScriptV3, validateScriptV4, } from \"./schema/index.js\";\nexport { load, parse, commit, save, resolve, allActions, assetName, stateName };\nexport { SPAN_COLUMNS, resolveSpan, spanPoints, spanAddresses } from \"./span.js\";\nexport { record, stop } from \"./trace.js\";\nconst NON_ACTOR_NAMES = [\"\u65C1\u767D\", \"\u5E7F\u64AD\", \"\u753B\u5916\", \"\u7FA4\u58F0\"];\nconst NON_ACTOR_KIND = {\n \u65C1\u767D: \"system\", \u5E7F\u64AD: \"broadcast\", \u753B\u5916: \"offscreen\", \u7FA4\u58F0: \"group\",\n};\n/** Names accepted in a `NAME\uFF1A` prefix \u2014 assets, their aliases, and `\u540D\u5B57\u00B7\u9650\u5B9A`. */\nexport function speakerResolver(doc) {\n const names = new Set(NON_ACTOR_NAMES);\n for (const a of doc.assets) {\n names.add(a.name);\n for (const al of a.aliases)\n names.add(al);\n }\n // Try the whole label first: asset names legitimately contain `\u00B7`\n // (`\u7BEE\u7403\u9986\u00B7\u66F4\u8863\u5BA4`), so it is only a state qualifier when it has to be.\n return (raw) => names.has(raw) || names.has(raw.split(\"\u00B7\")[0]);\n}\nexport function read(doc, addr = \"\", opts = {}) {\n const node = resolve(doc, addr);\n step(\"read\", `dispatch on node kind \"${node.t}\"`);\n switch (node.t) {\n case \"script\": return scriptCard(doc);\n case \"ep\": return readEpisode(doc, node.ep, opts);\n case \"scene\": return formatScene(doc, node.scene, opts);\n case \"asset\": return assetCard(doc, node.asset);\n case \"state\": return stateCard(doc, node.asset, node.state);\n case \"action\": {\n const n = opts.context ?? 3;\n const all = node.action.scene.actions;\n const i = all.indexOf(node.action);\n const slice = all.slice(Math.max(0, i - n), i + n + 1);\n const gutter = opts.plain ? 0 : Math.max(...slice.map((a) => a.anchor.length));\n const tp = node.action.raw.transition_prompt;\n const extra = Object.entries(node.action.raw.extend ?? {}).filter(([k]) => k !== \"timestamp\");\n return [\n formatSceneHead(doc, node.action.scene),\n ...slice.map((a) => (a === node.action ? \"> \" : \" \") + formatAction(doc, a, gutter, opts)),\n // Fields that have no place on the prose line still have to be visible\n // somewhere, or \"editable\" is a lie.\n tp ? `transition: ${assetName(doc, tp.target)} | ${tp.process} | ${tp.contrast}` : \"\",\n extra.length ? `extend: ${extra.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n }\n }\n}\nfunction chars(s) { return s.actions.reduce((n, a) => n + a.content.length, 0); }\nfunction scriptCard(doc) {\n const r = doc.raw;\n const scenes = doc.episodes.reduce((n, e) => n + e.scenes.length, 0);\n const actions = doc.episodes.reduce((n, e) => n + e.scenes.reduce((m, s) => m + s.actions.length, 0), 0);\n const out = [\n `${r.title || \"(untitled)\"} v${doc.version} ${doc.episodes.length} ep \u00B7 ${scenes} scenes \u00B7 ${actions} actions`,\n ];\n for (const k of [\"logline\", \"theme\", \"synopsis\", \"worldview\", \"style\"]) {\n if (r[k])\n out.push(`${k}: ${clip(String(r[k]), 300)}`);\n }\n if (Array.isArray(r.main_characters) && r.main_characters.length) {\n out.push(`main: ${r.main_characters.map((m) => `${m.name}=${m.role}`).join(\", \")}`);\n }\n for (const kind of [\"actor\", \"location\", \"prop\"]) {\n const list = doc.assets.filter((a) => a.kind === kind);\n if (!list.length)\n continue;\n out.push(\"\", `${kind}s (${list.length})`);\n for (const a of list.slice(0, 40)) {\n const al = a.aliases.length ? ` ~${a.aliases.join(\",\")}` : \"\";\n const imp = a.importance ? ` [${a.importance}]` : \"\";\n out.push(` ${a.id} ${a.name}${imp} ${a.states.length}st${al}`);\n }\n if (list.length > 40)\n out.push(` \u2026 ${list.length - 40} more`);\n }\n out.push(\"\", \"episodes\");\n for (const e of doc.episodes) {\n const c = e.scenes.reduce((n, s) => n + chars(s), 0);\n out.push(` ${e.no} ${e.id} ${e.scenes.length} scenes ${c} chars${e.title ? ` ${e.title}` : \"\"}`\n + (e.synopsis ? ` ${clip(e.synopsis, 120)}` : \"\"));\n }\n return out.join(\"\\n\");\n}\nfunction readEpisode(doc, ep, opts) {\n const head = `# EP${String(ep.no).padStart(2, \"0\")} ${ep.id} ${ep.scenes.length} scenes`\n + (ep.title ? ` ${ep.title}` : \"\");\n if (opts.depth === \"outline\") {\n return [head, ...ep.scenes.map((s) => formatSceneHead(doc, s))].join(\"\\n\");\n }\n return [head, ...ep.scenes.map((s) => formatScene(doc, s, opts))].join(\"\\n\\n\");\n}\nfunction assetCard(doc, a) {\n const role = a.raw.role_type ? ` <${a.raw.role_type}>` : \"\";\n const out = [`${a.id} ${a.name} ${a.kind}${a.importance ? ` [${a.importance}]` : \"\"}${role}`];\n if (a.aliases.length)\n out.push(`aliases: ${a.aliases.join(\", \")}`);\n if (a.desc)\n out.push(a.desc);\n out.push(`states (${a.states.length})`);\n for (const s of a.states)\n out.push(` ${s.id} ${s.name} ${clip(s.desc, 160)}`);\n const hits = [];\n const byState = new Map();\n for (const ep of doc.episodes)\n for (const s of ep.scenes) {\n const ref = [s.location, ...s.actors, ...s.props].find((r) => r && r.id === a.id);\n if (!ref)\n continue;\n hits.push(s);\n for (const st of ref.states)\n byState.set(st, (byState.get(st) ?? 0) + 1);\n }\n if (hits.length) {\n const eps = [...new Set(hits.map((s) => s.ep.no))];\n out.push(`appears: ${hits.length} scenes across ${eps.length} ep`\n + ` first ${hits[0].ep.no}-${hits[0].no} last ${hits.at(-1).ep.no}-${hits.at(-1).no}`);\n out.push(`state usage: ${[...byState].map(([k, v]) => `${stateName(doc, a.id, k)}\u00D7${v}`).join(\", \")}`);\n const unused = a.states.filter((s) => !byState.has(s.id));\n if (unused.length)\n out.push(`unused states: ${unused.map((s) => `${s.id}(${s.name})`).join(\", \")}`);\n }\n else {\n out.push(\"appears: never referenced\");\n }\n return out.join(\"\\n\");\n}\nfunction stateCard(doc, a, st) {\n const scenes = [];\n for (const ep of doc.episodes)\n for (const s of ep.scenes) {\n const ref = [s.location, ...s.actors, ...s.props].find((r) => r && r.id === a.id);\n if (ref?.states.includes(st.id))\n scenes.push(s);\n }\n const speakers = allActions(doc).filter((x) => x.speaker?.id === a.id && x.speaker.state === st.id);\n return [\n `${a.id}/${st.id} ${st.name} (${a.kind} ${a.name})`,\n st.desc,\n scenes.length\n ? `bound in ${scenes.length} scene(s): ${scenes.slice(0, 12).map((s) => `${s.ep.no}-${s.no}`).join(\", \")}`\n + (scenes.length > 12 ? ` \u2026` : \"\")\n : \"bound in no scene\",\n speakers.length ? `named by ${speakers.length} speaker reference(s)` : \"\",\n ].filter(Boolean).join(\"\\n\");\n}\nfunction clip(s, n) { return s.length > n ? s.slice(0, n) + \"\u2026\" : s; }\nfunction filterActions(doc, opts) {\n let pool = allActions(doc);\n step(\"find\", `pool = all actions (${pool.length})`);\n if (opts.in) {\n const node = resolve(doc, opts.in);\n if (node.t === \"ep\")\n pool = node.ep.scenes.flatMap((s) => s.actions);\n else if (node.t === \"scene\")\n pool = node.scene.actions;\n else if (node.t === \"action\")\n pool = [node.action];\n else\n throw new Error(`--in must address an episode, scene or action (got ${node.t})`);\n step(\"find\", `--in ${opts.in} narrows pool to ${pool.length}`);\n }\n if (opts.type) {\n pool = pool.filter((a) => a.type === opts.type);\n step(\"find\", `--type ${opts.type} -> ${pool.length}`);\n }\n if (opts.speaker) {\n const who = resolve(doc, opts.speaker);\n if (who.t !== \"asset\")\n throw new Error(`--speaker must name an actor`);\n pool = pool.filter((a) => a.speaker?.id === who.asset.id);\n step(\"find\", `--speaker ${opts.speaker} -> ${who.asset.id} -> ${pool.length}`);\n }\n return pool;\n}\nexport function find(doc, query, opts = {}) {\n const pool = filterActions(doc, opts);\n const re = query ? new RegExp(query, \"u\") : null;\n const hits = pool.filter((a) => !re || re.test(a.content));\n step(\"find\", `regex /${query}/ -> ${hits.length} hits`);\n const limit = opts.limit ?? 40;\n const w = opts.window ?? 16;\n const shown = hits.slice(0, limit);\n const gutter = Math.max(0, ...shown.map((a) => a.anchor.length));\n const head = `${hits.length} hit${hits.length === 1 ? \"\" : \"s\"}`\n + (query ? ` for /${query}/` : \"\") + (hits.length > shown.length ? ` (showing ${shown.length})` : \"\");\n const lines = shown.map((a) => {\n // v3 anchors already are the ordinal; don't print it twice.\n const ord = `${a.scene.ep.no}-${a.scene.no}-${a.no}`;\n const pos = ord === a.anchor ? \"\" : ord.padEnd(8) + \" \";\n const who = a.speaker?.id ? assetName(doc, a.speaker.id) + \"\uFF1A\" : \"\";\n const body = opts.full || !re ? a.content : windowed(a.content, re, w);\n return `${a.anchor.padEnd(gutter)} ${pos}${who}${body}`;\n });\n return [head, ...lines].join(\"\\n\");\n}\nfunction windowed(text, re, w) {\n const m = text.match(re);\n if (!m || m.index === undefined)\n return clip(text, w * 2);\n const a = Math.max(0, m.index - w), b = Math.min(text.length, m.index + m[0].length + w);\n return (a > 0 ? \"\u2026\" : \"\") + text.slice(a, b) + (b < text.length ? \"\u2026\" : \"\");\n}\n// ---- span --------------------------------------------------------------------\n/**\n * The video window that covers a set of actions. `range` takes the same shapes\n * `find --in` does \u2014 an episode, a scene, one action, or `A..B` \u2014 so an agent\n * that just located a candidate can ask what to watch without a second syntax.\n */\nexport function span(doc, range) {\n const pool = filterActions(doc, { in: range });\n const row = resolveSpan(spanPoints(doc), spanAddresses(doc, pool));\n return SPAN_COLUMNS.map((c) => `${c}=${row[c]}`).join(\" \");\n}\nconst ACTION_FIELDS = [\"content\", \"paren\", \"speaker\", \"ts\", \"type\", \"transition\"];\nconst ASSET_FIELDS = [\"name\", \"desc\", \"importance\", \"aliases\", \"role\"];\nconst STATE_FIELDS = [\"name\", \"desc\"];\nconst EPISODE_FIELDS = [\"title\", \"synopsis\"];\nconst SCENE_FIELDS = [\"space\", \"time\"];\nconst SCRIPT_FIELDS = [\"title\", \"worldview\", \"style\", \"synopsis\", \"logline\", \"theme\", \"main\"];\nfunction only(at, kind, fields, allowed) {\n const given = Object.keys(fields).filter((k) => fields[k] !== undefined);\n if (!given.length)\n throw new Error(`Nothing to change on ${at}; pass at least one field`);\n const bad = given.filter((k) => !allowed.includes(k));\n if (bad.length) {\n const art = /^[aeiou]/.test(kind) ? \"an\" : \"a\";\n throw new Error(`${at} is ${art} ${kind}; it has no ${bad.join(\", \")}`\n + ` \u2014 ${art} ${kind} takes ${allowed.join(\", \")}`);\n }\n return given;\n}\n/** Same verb for every node kind: the address decides which fields are legal. */\nexport function edit(doc, at, fields) {\n const node = resolve(doc, at);\n if (node.t === \"asset\")\n return editAsset(doc, at, node.asset, fields);\n if (node.t === \"state\")\n return editState(doc, at, node.asset, node.state, fields);\n if (node.t === \"script\")\n return editPlain(doc, at || \"script\", \"script\", node.doc.raw, fields, SCRIPT_FIELDS);\n if (node.t === \"ep\")\n return editPlain(doc, at, \"episode\", node.ep.raw, fields, EPISODE_FIELDS);\n if (node.t === \"scene\")\n return editScene(doc, at, node.scene, fields);\n const a = node.action;\n const raw = a.raw;\n const changed = only(a.anchor, \"action\", fields, ACTION_FIELDS);\n const base = baseline(doc);\n step(\"edit\", `${a.anchor}: ${changed.join(\", \")}`);\n if (fields.type !== undefined)\n raw.type = oneOf(\"type\", fields.type, ACTION_TYPE_SET, ACTION_TYPES);\n if (fields.content !== undefined)\n raw.content = fields.content;\n if (fields.paren !== undefined)\n setParen(doc, raw, fields.paren);\n if (fields.speaker !== undefined)\n raw.speaker = speakerJson(doc, fields.speaker);\n if (fields.ts !== undefined)\n setTs(raw, fields.ts);\n if (fields.transition !== undefined) {\n if (fields.transition === null)\n delete raw.transition_prompt;\n else {\n const [target, process, contrast] = fields.transition.split(\"|\").map((x) => x.trim());\n if (!target || !process || !contrast) {\n throw new Error(`transition takes \"target|process|contrast\" (got \"${fields.transition}\")`);\n }\n const t = resolve(doc, target);\n if (t.t !== \"asset\")\n throw new Error(`transition target must be an asset (got ${target})`);\n raw.transition_prompt = { target: t.asset.id, process, contrast };\n }\n }\n save(doc);\n return `${a.anchor} ${changed.join(\"+\")} ${preview(raw)}` + since(doc, base);\n}\n/** Plain string metadata on the script root or an episode. */\nfunction editPlain(doc, at, kind, raw, fields, allowed) {\n const changed = only(at, kind, fields, allowed);\n const base = baseline(doc);\n for (const k of changed) {\n if (k === \"main\") {\n raw.main_characters = fields.main.split(\",\").map((pair) => {\n const [name, role] = pair.split(\"=\").map((x) => x.trim());\n if (!name || !role)\n throw new Error(`main takes \"\u540D\u5B57=\u89D2\u8272\u5B9A\u4F4D,\u2026\" (got \"${pair}\")`);\n return { name, role };\n });\n }\n else if (k === \"aliases\" || k === \"role\") {\n throw new Error(`${at} is ${kind}; it has no ${k}`);\n }\n else {\n raw[k] = fields[k];\n }\n }\n step(\"edit\", `${kind} ${at}: ${changed.join(\", \")}`);\n save(doc);\n return `${at} ${changed.join(\"+\")}` + since(doc, base);\n}\nfunction editScene(doc, at, scene, fields) {\n const changed = only(at, \"scene\", fields, SCENE_FIELDS);\n const base = baseline(doc);\n const env = { ...(scene.raw.environment ?? {}) };\n if (fields.space !== undefined)\n env.space = oneOf(\"space\", fields.space, SCENE_SPACE_SET, SCENE_SPACE_VALUES);\n if (fields.time !== undefined)\n env.time = oneOf(\"time\", fields.time, SCENE_TIME_SET, SCENE_TIME_VALUES);\n scene.raw.environment = env;\n step(\"edit\", `scene ${scene.anchor}: ${changed.join(\", \")}`);\n save(doc);\n return `${scene.anchor} ${changed.join(\"+\")} ${[env.space, env.time].filter(Boolean).join(\"/\")}`\n + since(doc, base);\n}\nfunction editAsset(doc, at, a, fields) {\n const changed = only(at, \"asset\", fields, ASSET_FIELDS);\n const base = baseline(doc);\n if (fields.name !== undefined) {\n const clash = doc.assets.find((x) => x !== a && (x.name === fields.name || x.aliases.includes(fields.name)));\n if (clash)\n throw new Error(`\"${fields.name}\" already names ${clash.kind} ${clash.id}`);\n a.raw[`${a.kind}_name`] = fields.name;\n }\n if (fields.desc !== undefined)\n a.raw.description = fields.desc;\n if (fields.importance !== undefined)\n a.raw.importance = checkImportance(fields.importance);\n if (fields.role !== undefined) {\n if (a.kind !== \"actor\")\n throw new Error(`role only applies to actors (${a.name} is a ${a.kind})`);\n if (fields.role)\n a.raw.role_type = oneOf(\"role\", fields.role, ROLE_TYPE_SET, ROLE_TYPES);\n else\n delete a.raw.role_type;\n }\n if (fields.aliases !== undefined) {\n if (fields.aliases.length)\n a.raw.aliases = fields.aliases;\n else\n delete a.raw.aliases;\n }\n step(\"edit\", `asset ${a.id}: ${changed.join(\", \")}`);\n save(doc);\n return `${a.id} ${changed.join(\"+\")} ${fields.name ?? a.name}` + since(doc, base);\n}\nfunction editState(doc, at, a, st, fields) {\n const changed = only(at, \"state\", fields, STATE_FIELDS);\n const base = baseline(doc);\n const raw = a.raw.states.find((x) => x.state_id === st.id);\n if (fields.name !== undefined) {\n if (a.states.some((x) => x.id !== st.id && x.name === fields.name)) {\n throw new Error(`${a.name} already has a state named \"${fields.name}\"`);\n }\n raw.state_name = fields.name;\n }\n if (fields.desc !== undefined)\n raw.description = fields.desc;\n step(\"edit\", `state ${a.id}/${st.id}: ${changed.join(\", \")}`);\n save(doc);\n return `${a.id}/${st.id} ${changed.join(\"+\")} ${fields.name ?? st.name}` + since(doc, base);\n}\n/**\n * Insert one action next to an existing one. This is the narrow half of what\n * `write` could do: `write` replaces a whole scene from prose and can therefore\n * rewrite dialogue wholesale, which a fidelity review must not do. Adding a\n * single missing beat needs none of that power.\n */\nexport function insert(doc, at, where, type, content, speaker, paren) {\n const node = resolve(doc, at);\n if (node.t !== \"action\")\n throw new Error(`${at} is a ${node.t}; insert needs a sibling action`);\n const anchor = node.action;\n const base = baseline(doc);\n const raw = { type: oneOf(\"type\", type, ACTION_TYPE_SET, ACTION_TYPES), content };\n if (doc.version === 4)\n raw.action_id = newId(\"ac\", new Set(doc.actions.keys()));\n if (type === \"dialogue\" || type === \"inner_thought\") {\n if (!speaker)\n throw new Error(`a ${type} needs a speaker`);\n raw.speaker = speakerJson(doc, speaker);\n if (paren !== undefined)\n setParen(doc, raw, paren);\n }\n else if (speaker || paren) {\n throw new Error(`a ${type} takes neither speaker nor paren`);\n }\n const list = anchor.scene.raw.actions;\n const index = list.indexOf(anchor.raw) + (where === \"before\" ? 0 : 1);\n list.splice(index, 0, raw);\n step(\"insert\", `${raw.action_id ?? `${anchor.scene.anchor}#${index}`} ${where} ${anchor.anchor}`);\n save(doc);\n return `${raw.action_id ?? `${anchor.scene.anchor}#${index}`} ${where} ${anchor.anchor}`\n + ` ${preview(raw)}` + since(doc, base);\n}\n/**\n * Relocate one action. This is the single thing `write` cannot do: it works a\n * scene at a time, so moving across scenes through two writes drops the action\n * from one and creates a *new* id in the other. Here the identity survives.\n */\nexport function move(doc, at, to, where = \"after\") {\n const src = resolve(doc, at);\n if (src.t !== \"action\")\n throw new Error(`${at} is a ${src.t}; move targets one action`);\n const dst = resolve(doc, to);\n if (dst.t !== \"action\")\n throw new Error(`${to} is a ${dst.t}; move --to takes a sibling action`);\n if (src.action === dst.action)\n throw new Error(`${at} cannot move relative to itself`);\n const base = baseline(doc);\n const from = src.action.scene.raw.actions;\n from.splice(from.indexOf(src.action.raw), 1);\n const into = dst.action.scene.raw.actions;\n into.splice(into.indexOf(dst.action.raw) + (where === \"before\" ? 0 : 1), 0, src.action.raw);\n step(\"move\", `${src.action.scene.anchor} -> ${dst.action.scene.anchor}, identity ${src.action.anchor} preserved`);\n save(doc);\n return `${src.action.anchor} ${where} ${dst.action.anchor}`\n + ` (${src.action.scene.anchor} -> ${dst.action.scene.anchor})` + since(doc, base);\n}\nfunction setParen(doc, raw, v) {\n const key = doc.version === 4 ? \"parenthetical\" : \"emotion\";\n if (v === null)\n delete raw[key];\n else\n raw[key] = v;\n}\n// Timestamps are parsed and stored canonically \u2014 `0:07` becomes `00:07`, and an\n// unparseable value is refused here rather than surfacing later as a validation\n// issue on a file that already holds it. Sub-second precision is preserved as\n// written, because it is meaningful for video alignment.\nfunction setTs(raw, v) {\n if (v === null) {\n if (raw.extend)\n delete raw.extend.timestamp;\n return;\n }\n let canonical;\n try {\n canonical = parseTimestamp(v).canonical;\n }\n catch (error) {\n if (!(error instanceof TimestampParseError))\n throw error;\n throw new Error(`${error.message} (got ${JSON.stringify(v)})`);\n }\n raw.extend = { ...(raw.extend ?? {}), timestamp: canonical };\n}\nfunction speakerJson(doc, name) {\n const whole = doc.assets.find((a) => a.name === name || a.aliases.includes(name));\n const [base, qual] = whole ? [name, undefined] : splitOnce(name, \"\u00B7\");\n const kind = NON_ACTOR_KIND[base];\n if (kind)\n return qual ? { kind, label: qual } : { kind };\n const n = resolve(doc, base);\n if (n.t !== \"asset\" || n.asset.kind !== \"actor\")\n throw new Error(`Not an actor: ${name}`);\n const out = { actor_id: n.asset.id };\n if (qual) {\n const st = n.asset.states.find((s) => s.name === qual || s.id === qual);\n if (!st)\n throw new Error(`Unknown state \"${qual}\" on ${n.asset.name}`);\n out.state_id = st.id;\n }\n return out;\n}\nfunction splitOnce(v, sep) {\n const i = v.indexOf(sep);\n return i < 0 ? [v, undefined] : [v.slice(0, i), v.slice(i + sep.length)];\n}\nfunction preview(raw) { return clip(String(raw.content ?? \"\"), 40); }\n/**\n * Replace a scene or a whole episode from the prose `read` prints.\n *\n * Diffing is by anchor at every level: a line or `##` header carrying a known\n * anchor keeps its identity, one without an anchor is created, and an anchor\n * absent from the text is deleted. That last rule is the only thing about this\n * format an agent cannot infer from reading one output, so deleting a *scene*\n * needs `allowDelete` \u2014 losing 30 actions to a forgotten header is not a\n * mistake we let happen quietly.\n *\n * `addr` may also be `\"+\"` or the next episode ordinal, which appends a new one.\n */\nexport function write(doc, addr, text, opts = {}) {\n if (addr === \"+\" || Number(addr) === doc.episodes.length + 1) {\n const raw = { scenes: [] };\n if (doc.version === 4)\n raw.episode_id = newId(\"ep\", new Set(doc.eps.keys()));\n doc.raw.episodes.push(raw);\n step(\"write\", `appending episode ${doc.episodes.length + 1}`);\n return writeEpisodeRaw(doc, raw, doc.episodes.length + 1, text, opts, true);\n }\n const node = resolve(doc, addr);\n if (node.t === \"scene\")\n return writeScene(doc, node.scene, text, opts);\n if (node.t === \"ep\")\n return writeEpisodeRaw(doc, node.ep.raw, node.ep.no, text, opts, false);\n throw new Error(`write targets a scene or an episode (got ${node.t})`);\n}\nfunction writeScene(doc, scene, text, opts) {\n const base = baseline(doc);\n const r = applyScene(doc, scene.raw, scene, text, new Set(doc.actions.keys()), opts);\n save(doc);\n return report(scene.anchor, r) + since(doc, base);\n}\nfunction report(label, r) {\n return `${label}: ${r.total} actions (${r.kept} kept, ${r.created} new, ${r.dropped.length} deleted)`\n + (r.dropped.length\n ? `\\ndeleted: ${r.dropped.map((a) => `${a.anchor} ${preview(a.raw)}`).join(\"\\n \")}`\n : \"\");\n}\n/** Rewrite one scene's header fields and action list from prose. */\nfunction applyScene(doc, raw, prev, block, taken, opts, pool, claimed) {\n const known = speakerResolver(doc);\n const { head: headLine, meta: metaLine, body: lines } = splitBlock(block.split(\"\\n\"));\n if (headLine) {\n const h = parseHead(headLine, metaLine);\n raw.environment = h.env.space || h.env.time ? h.env : undefined;\n if (raw.environment === undefined)\n delete raw.environment;\n raw.location = h.location ? refJson(doc, h.location, \"location\") : null;\n raw.actors = h.cast.map((c) => refJson(doc, c, \"actor\"));\n raw.props = h.props.map((p) => refJson(doc, p, \"prop\"));\n }\n // At episode scope the pool spans every scene of the episode, so an anchor may\n // legitimately land in a different scene: that is how splitting and merging\n // scenes is expressed, without a separate verb.\n const byAnchor = pool ?? new Map((prev?.actions ?? []).map((a) => [a.anchor, a]));\n const seen = claimed ?? new Set();\n const kept = new Set();\n const out = [];\n let created = 0;\n const label = prev ? prev.anchor : \"this new scene\";\n for (const line of lines) {\n const p = parseLine(line, known);\n if (!p)\n continue;\n const old = p.anchor ? byAnchor.get(p.anchor) : undefined;\n if (p.anchor && !old) {\n throw new Error(`Anchor ${p.anchor} is not in ${label}`\n + ` \u2014 move it with \\`move\\`, or drop the anchor to create a new action`);\n }\n // One anchor is one action. Repeating it would put the same object in the\n // array twice: a duplicate id on disk, and two lines that edit each other.\n if (old && seen.has(old.anchor)) {\n throw new Error(`Anchor ${p.anchor} appears twice in ${label}`\n + ` \u2014 drop the anchor from the copy to make it a new action`);\n }\n const node = old ? old.raw : {};\n if (!old && doc.version === 4)\n node.action_id = newId(\"ac\", taken);\n node.type = oneOf(\"type\", p.type, ACTION_TYPE_SET, ACTION_TYPES);\n node.content = p.content;\n if (p.type === \"dialogue\" || p.type === \"inner_thought\") {\n node.speaker = speakerJson(doc, p.speakerName);\n setParen(doc, node, p.paren ?? null);\n }\n else {\n delete node.speaker;\n setParen(doc, node, null);\n }\n setTs(node, p.ts ?? null);\n if (old) {\n kept.add(old.anchor);\n seen.add(old.anchor);\n }\n else\n created++;\n out.push(node);\n }\n // An empty body is overwhelmingly a forgotten paste, not an intentional wipe\n // \u2014 the same reason deleting a whole scene needs the flag. Scenes that were\n // already empty are not a deletion and pass through untouched; real scripts\n // do contain them.\n if (!out.length && (prev?.actions.length ?? 0) > 0 && !opts.allowDelete) {\n throw new Error(`That would leave ${label} with no actions`\n + `${prev ? ` (deleting all ${prev.actions.length})` : \"\"}`\n + ` \u2014 the body after the \\`##\\` header is empty; pass --allow-delete if that is the intent`);\n }\n // Not one line matched an existing anchor: this is `--plain` output, or text\n // from another scene. Writing it would replace every action id in place.\n if (out.length && !kept.size && (prev?.actions.length ?? 0) > 0 && !opts.allowDelete) {\n throw new Error(`None of the ${out.length} line(s) carry an anchor from ${label},`\n + ` so all ${prev.actions.length} existing action(s) would be replaced by new ids`\n + ` \u2014 \\`read --plain\\` output cannot be written back; re-read without --plain,`\n + ` or pass --allow-delete to rewrite the scene from scratch`);\n }\n raw.actions = out;\n return { total: out.length, kept: kept.size, created,\n dropped: pool ? [] : (prev?.actions ?? []).filter((a) => !kept.has(a.anchor)) };\n}\nfunction writeEpisodeRaw(doc, epRaw, epNo, text, opts, isNew) {\n const base = baseline(doc);\n const prevScenes = isNew ? [] : doc.episodes[epNo - 1].scenes;\n const byAnchor = new Map();\n for (const s of prevScenes) {\n byAnchor.set(s.anchor, s);\n byAnchor.set(s.id, s);\n }\n // Split on `##`; anything before the first header (an `# EP..` title line) is\n // preamble and carries no scene.\n const blocks = [];\n for (const line of text.split(\"\\n\")) {\n if (line.startsWith(\"##\"))\n blocks.push(line);\n else if (blocks.length)\n blocks[blocks.length - 1] += \"\\n\" + line;\n }\n if (!blocks.length)\n throw new Error(`No scene headers found \u2014 an episode body needs \\`## \u2026\\` lines`);\n const takenAc = new Set(doc.actions.keys());\n const takenScn = new Set(doc.scenes.keys());\n const pool = new Map();\n for (const s of prevScenes)\n for (const a of s.actions)\n pool.set(a.anchor, a);\n const claimed = new Set();\n const seen = new Set();\n const scenes = [];\n const parts = [];\n let newScenes = 0;\n for (const block of blocks) {\n const h = parseHead(block.split(\"\\n\")[0]);\n const prev = h.anchor ? byAnchor.get(h.anchor) : undefined;\n if (h.anchor && !prev) {\n throw new Error(`Scene ${h.anchor} is not in episode ${epNo}`\n + ` \u2014 drop the id from the header to create a new scene here`);\n }\n const raw = prev ? prev.raw : {};\n if (!prev) {\n if (doc.version === 4)\n raw.scene_id = newId(\"scn\", takenScn);\n else\n raw.scene_id = `scn_${String(prevScenes.length + newScenes + 1).padStart(3, \"0\")}`;\n newScenes++;\n }\n else\n seen.add(prev.anchor);\n const r = applyScene(doc, raw, prev ?? null, block, takenAc, opts, pool, claimed);\n scenes.push(raw);\n parts.push(report(prev ? prev.anchor : `new ${raw.scene_id}`, r));\n }\n const goneActions = [...pool.values()].filter((a) => !claimed.has(a.anchor));\n if (goneActions.length && !opts.allowDelete) {\n throw new Error(`This would delete ${goneActions.length} action(s) from episode ${epNo}: `\n + goneActions.slice(0, 6).map((a) => `${a.anchor}(${a.scene.anchor})`).join(\", \")\n + (goneActions.length > 6 ? ` \u2026` : \"\")\n + ` \u2014 keep their lines, or pass --allow-delete if that is the intent`);\n }\n const goneScenes = prevScenes.filter((s) => !seen.has(s.anchor));\n if (goneScenes.length && !opts.allowDelete) {\n throw new Error(`This would delete ${goneScenes.length} whole scene(s) from episode ${epNo}: `\n + goneScenes.map((s) => `${s.anchor}(${s.actions.length} actions)`).join(\", \")\n + ` \u2014 include their \\`##\\` headers to keep them, or pass --allow-delete if that is the intent`);\n }\n step(\"write\", `episode ${epNo}: ${blocks.length} scene blocks, ${newScenes} new, ${goneScenes.length} deleted`);\n epRaw.scenes = scenes;\n save(doc);\n return `EP${epNo}: ${scenes.length} scenes (${scenes.length - newScenes} kept, ${newScenes} new,`\n + ` ${goneScenes.length} deleted, ${goneActions.length} actions deleted)\\n` + parts.map((p) => \" \" + p.replace(/\\n/g, \"\\n \")).join(\"\\n\")\n + (goneScenes.length ? `\\ndeleted scenes: ${goneScenes.map((s) => s.anchor).join(\", \")}` : \"\")\n + since(doc, base);\n}\n/** `\u540D\u5B57` or `\u540D\u5B57(\u72B6\u6001+\u72B6\u6001)` -> the JSON reference, resolving names to ids. */\nfunction refJson(doc, text, kind) {\n const { name, states } = parseRefText(text);\n const n = resolve(doc, name);\n if (n.t !== \"asset\" || n.asset.kind !== kind) {\n throw new Error(`\"${name}\" is not a registered ${kind} \u2014 create it with \\`asset\\` first`);\n }\n const ids = (states.length ? states : [\"default\"]).map((sn) => {\n const hit = n.asset.states.filter((st) => st.name === sn || st.id === sn);\n if (!hit.length) {\n throw new Error(`${n.asset.name} has no state \"${sn}\" (has: ${n.asset.states.map((x) => x.name).join(\", \")})`);\n }\n if (hit.length > 1)\n throw new Error(`${n.asset.name} has ${hit.length} states named \"${sn}\"; use the state id`);\n return hit[0].id;\n });\n const uniq = [...new Set(ids)].sort();\n const key = `${kind}_id`;\n return doc.version === 4\n ? { [key]: n.asset.id, state_ids: uniq }\n : { [key]: n.asset.id, state_id: uniq[0] };\n}\n// ---- ref -------------------------------------------------------------------\n/**\n * Set, change or remove one scene's reference to one asset \u2014 the atom behind a\n * `cast:` / `props:` / location entry in a scene header.\n *\n * `states` is the complete set for that asset in that scene, not an append:\n * passing it replaces whatever was bound. Nothing is implied, so binding\n * `default` means saying `default`. A bulk change across a whole episode is a\n * `write` of that episode's headers, not a flag here.\n */\nexport function ref(doc, sceneAddr, assetAddr, states, remove = false) {\n const node = resolve(doc, sceneAddr);\n if (node.t !== \"scene\")\n throw new Error(`${sceneAddr} is a ${node.t}; ref targets one scene`);\n const scene = node.scene;\n const target = resolve(doc, assetAddr);\n if (target.t !== \"asset\")\n throw new Error(`${assetAddr} is a ${target.t}; ref takes an actor, location or prop`);\n const a = target.asset;\n const field = a.kind === \"actor\" ? \"actors\" : a.kind === \"prop\" ? \"props\" : \"location\";\n const base = baseline(doc);\n if (remove) {\n if (a.kind === \"location\") {\n if (scene.location?.id !== a.id) {\n throw new Error(`${scene.anchor}'s location is `\n + `${scene.location ? assetName(doc, scene.location.id) : \"empty\"}, not ${a.name}`);\n }\n scene.raw.location = null;\n }\n else {\n const list = scene.raw[field];\n const i = list.findIndex((r) => r[`${a.kind}_id`] === a.id);\n if (i < 0)\n throw new Error(`${scene.anchor} does not reference ${a.name}`);\n list.splice(i, 1);\n }\n step(\"ref\", `${scene.anchor} -= ${a.id}`);\n save(doc);\n return `${scene.anchor} removed ${a.name}` + since(doc, base);\n }\n if (!states.length) {\n throw new Error(`ref needs at least one state for ${a.name}`\n + ` (has: ${a.states.map((st) => st.name).join(\", \")}) \u2014 nothing is implied, not even default`);\n }\n const ids = [...new Set(states.map((sn) => {\n const hit = a.states.filter((st) => st.name === sn || st.id === sn);\n if (!hit.length) {\n throw new Error(`${a.name} has no state \"${sn}\" (has: ${a.states.map((x) => x.name).join(\", \")})`);\n }\n if (hit.length > 1)\n throw new Error(`${a.name} has ${hit.length} states named \"${sn}\"; use the state id`);\n return hit[0].id;\n }))].sort();\n const key = `${a.kind}_id`;\n const entry = doc.version === 4 ? { [key]: a.id, state_ids: ids } : { [key]: a.id, state_id: ids[0] };\n if (doc.version === 3 && ids.length > 1) {\n throw new Error(`Script v3 holds one state per reference; pass a single state`);\n }\n let verb;\n if (a.kind === \"location\") {\n verb = scene.location ? (scene.location.id === a.id ? \"restated\" : \"replaced\") : \"set\";\n scene.raw.location = entry;\n }\n else {\n const list = scene.raw[field];\n const i = list.findIndex((r) => r[key] === a.id);\n if (i < 0) {\n list.push(entry);\n verb = \"added\";\n }\n else {\n list[i] = entry;\n verb = \"restated\";\n }\n }\n step(\"ref\", `${scene.anchor} ${verb} ${a.id} = [${ids.join(\", \")}]`);\n save(doc);\n return `${scene.anchor} ${verb} ${a.name}(${ids.map((i2) => stateName(doc, a.id, i2)).join(\"+\")})`\n + since(doc, base);\n}\n/**\n * Substitute text across every action a `find` would match. Same filter names\n * as `find` on purpose \u2014 this is \"find, but substituting\", so there is no\n * second selector language to learn.\n *\n * Dry-run by default: it prints the exact before/after lines and only writes\n * when `apply` is set. That, not a plan digest, is what keeps a 200-hit rewrite\n * reviewable.\n */\nexport function replace(doc, query, to, opts = {}) {\n if (!query)\n throw new Error(\"replace needs a pattern; an empty one would rewrite every action\");\n const re = new RegExp(query, \"gu\");\n const base = baseline(doc);\n const pool = filterActions(doc, opts);\n const hits = pool.filter((a) => { re.lastIndex = 0; return re.test(a.content); });\n step(\"replace\", `/${query}/ matched ${hits.length} of ${pool.length} actions in scope`);\n if (!hits.length)\n return `0 hits for /${query}/ \u2014 nothing to do`;\n const gutter = Math.max(...hits.map((a) => a.anchor.length));\n const lines = hits.map((a) => {\n const next = a.content.replace(re, to);\n return `${a.anchor.padEnd(gutter)} ${a.scene.ep.no}-${a.scene.no}-${a.no}\\n`\n + `${\" \".repeat(gutter)} - ${a.content}\\n${\" \".repeat(gutter)} + ${next}`;\n });\n if (!opts.apply) {\n return `${hits.length} action(s) would change (dry run \u2014 pass apply to write)\\n` + lines.join(\"\\n\");\n }\n for (const a of hits) {\n re.lastIndex = 0;\n a.raw.content = a.content.replace(re, to);\n }\n save(doc);\n step(\"replace\", `wrote ${hits.length} actions`);\n return `${hits.length} action(s) changed` + since(doc, base) + \"\\n\" + lines.join(\"\\n\");\n}\n// ---- asset -----------------------------------------------------------------\n// Closed sets come from the schema package \u2014 the same constants the validator\n// uses. Rejecting here beats writing a file that only `validate` will reject.\nfunction oneOf(what, v, set, allowed) {\n if (!set.has(v))\n throw new Error(`${what} must be one of ${allowed.join(\" | \")} (got \"${v}\")`);\n return v;\n}\nfunction checkImportance(v) {\n return oneOf(\"importance\", v, IMPORTANCE_TIER_SET, IMPORTANCE_TIERS);\n}\n// ---- validation --------------------------------------------------------------\nexport function validateDoc(doc) {\n return doc.version === 4 ? validateScriptV4(doc.raw) : validateScriptV3(doc.raw);\n}\n/** Human-readable validation report. */\nexport function validate(doc) {\n const r = validateDoc(doc);\n const head = `${doc.episodes.length} episodes / ${doc.scenes.size ? [...new Set(doc.episodes.flatMap((e) => e.scenes))].length : 0} scenes`\n + ` / ${allActions(doc).length} actions \u2014 ${r.ok ? \"ok\" : `${r.errors.length} error(s)`}`\n + (r.warnings.length ? `, ${r.warnings.length} warning(s)` : \"\");\n return [head, ...fmtIssues([...r.errors.map((i) => [\"error\", i]),\n ...r.warnings.map((i) => [\"warning\", i])])].join(\"\\n\");\n}\nexport function issues(doc, opts = {}) {\n const r = validateDoc(doc);\n let rows = [\n ...r.errors.map((i) => [\"error\", i]), ...r.warnings.map((i) => [\"warning\", i])\n ];\n if (opts.severity)\n rows = rows.filter(([s]) => s === opts.severity);\n if (opts.code)\n rows = rows.filter(([, i]) => i.code === opts.code);\n step(\"issues\", `${rows.length} matching issue(s)`);\n return rows.length ? fmtIssues(rows).join(\"\\n\") : \"No issues.\";\n}\nfunction fmtIssues(rows) {\n return rows.map(([sev, i]) => `${sev} ${i.code} ${i.path} ${i.message}`\n + (i.repair_hint ? `\\n fix: ${i.repair_hint}` : \"\"));\n}\n// Every mutation reports what it broke that was not already broken. This\n// replaces the timeline and speaker-state checks that used to be written by\n// hand here: one rule set, defined once, in the schema package.\nfunction baseline(doc) { return validateDoc(doc); }\nfunction since(doc, base) {\n const now = validateDoc(doc);\n const fresh = [\n ...issuesIntroduced(base.errors, now.errors).map((i) => [\"error\", i]),\n ...issuesIntroduced(base.warnings, now.warnings).map((i) => [\"warning\", i]),\n ];\n if (!fresh.length)\n return \"\";\n step(\"check\", `${fresh.length} issue(s) introduced by this edit`);\n return `\\nintroduced ${fresh.length} issue(s):\\n ` + fmtIssues(fresh).join(\"\\n \");\n}\nconst ASSET_FIELD = { actor: \"actors\", location: \"locations\", prop: \"props\" };\nconst ID_PREFIX = { actor: \"act\", location: \"loc\", prop: \"prp\" };\n/**\n * Register a new actor, location or prop, with its `default` state. Assets must\n * exist before a scene header can reference them, so this is the entry point for\n * writing an episode from scratch.\n */\nexport function asset(doc, kind, name, desc, importance = \"featured\", aliases = []) {\n if (!name.trim())\n throw new Error(\"asset needs a name\");\n const base = baseline(doc);\n const clash = doc.assets.find((a) => a.name === name || a.aliases.includes(name));\n if (clash)\n throw new Error(`\"${name}\" already names ${clash.kind} ${clash.id}; read it instead`);\n const field = ASSET_FIELD[kind];\n const id = doc.version === 4\n ? newId(ID_PREFIX[kind], new Set(doc.assets.map((a) => a.id)))\n : `${ID_PREFIX[kind]}_${String(doc.raw[field].length + 1).padStart(3, \"0\")}`;\n const raw = {\n [`${kind}_id`]: id, [`${kind}_name`]: name, importance: checkImportance(importance), description: desc,\n states: [{ state_id: \"default\", state_name: name, description: desc }],\n };\n if (aliases.length)\n raw.aliases = aliases;\n doc.raw[field].push(raw);\n step(\"asset\", `${kind} ${id} \"${name}\" + default state`);\n save(doc);\n return `${id} ${name} ${kind} states: default` + since(doc, base);\n}\n/** Add a visual state to an existing asset. */\nexport function state(doc, assetName, name, desc) {\n const n = resolve(doc, assetName);\n if (n.t !== \"asset\")\n throw new Error(`${assetName} is a ${n.t}; state targets an asset`);\n const base = baseline(doc);\n if (n.asset.states.some((s) => s.name === name)) {\n throw new Error(`${n.asset.name} already has a state named \"${name}\"`);\n }\n const id = doc.version === 4\n ? newId(\"st\", new Set(n.asset.states.map((s) => s.id)))\n : `st_${String(n.asset.states.length).padStart(3, \"0\")}`;\n n.asset.raw.states.push({ state_id: id, state_name: name, description: desc });\n step(\"state\", `${n.asset.id} + ${id} \"${name}\"`);\n save(doc);\n return `${n.asset.id}/${id} ${name} (${n.asset.name} now has ${n.asset.states.length + 1} states)`\n + since(doc, base);\n}\n// ---- ext / del / merge -----------------------------------------------------\nfunction rawOf(doc, addr) {\n const n = resolve(doc, addr);\n switch (n.t) {\n case \"script\": return { raw: n.doc.raw, label: \"script\" };\n case \"ep\": return { raw: n.ep.raw, label: n.ep.id };\n case \"scene\": return { raw: n.scene.raw, label: n.scene.anchor };\n case \"action\": return { raw: n.action.raw, label: n.action.anchor };\n case \"asset\": return { raw: n.asset.raw, label: n.asset.id };\n case \"state\": {\n const raw = n.asset.raw.states.find((s) => s.state_id === n.state.id);\n return { raw, label: `${n.asset.id}/${n.state.id}` };\n }\n }\n}\n/**\n * Read or write `extend` on any node. Extension data is deliberately absent\n * from the prose view \u2014 it is arbitrary and would be noise on every line \u2014 so\n * this is how it stays reachable rather than merely preserved.\n */\nexport function ext(doc, addr, key, value, remove = false) {\n const { raw, label } = rawOf(doc, addr);\n const map = raw.extend ?? {};\n if (!key) {\n const keys = Object.keys(map);\n return keys.length\n ? `${label} extend:\\n` + keys.map((k) => ` ${k} = ${JSON.stringify(map[k])}`).join(\"\\n\")\n : `${label} has no extend data`;\n }\n if (remove) {\n if (!(key in map))\n throw new Error(`${label} has no extend key \"${key}\"`);\n delete map[key];\n if (!Object.keys(map).length)\n delete raw.extend;\n else\n raw.extend = map;\n step(\"ext\", `${label} -= ${key}`);\n save(doc);\n return `${label} removed extend.${key}`;\n }\n if (value === undefined) {\n if (!(key in map))\n throw new Error(`${label} has no extend key \"${key}\"`);\n return `${label} extend.${key} = ${JSON.stringify(map[key])}`;\n }\n raw.extend = { ...map, [key]: value };\n step(\"ext\", `${label} extend.${key} = ${value}`);\n save(doc);\n return `${label} extend.${key} = ${JSON.stringify(value)}`;\n}\n/**\n * Delete a node. The address decides what: action, scene, episode, asset or\n * state. Anything that other nodes point at refuses to vanish silently \u2014\n * either rewire it with `replacement`, or say `force` and read the report.\n */\nexport function del(doc, addr, opts = {}) {\n const n = resolve(doc, addr);\n const base = baseline(doc);\n if (n.t === \"action\") {\n const list = n.action.scene.raw.actions;\n list.splice(list.indexOf(n.action.raw), 1);\n step(\"del\", `action ${n.action.anchor} from ${n.action.scene.anchor}`);\n save(doc);\n return `deleted ${n.action.anchor} ${preview(n.action.raw)}` + since(doc, base);\n }\n if (n.t === \"scene\") {\n if (n.scene.actions.length && !opts.force) {\n throw new Error(`${n.scene.anchor} still holds ${n.scene.actions.length} action(s)`\n + ` \u2014 pass --force to delete the scene and everything in it`);\n }\n const list = n.scene.ep.raw.scenes;\n list.splice(list.indexOf(n.scene.raw), 1);\n step(\"del\", `scene ${n.scene.anchor} (${n.scene.actions.length} actions)`);\n save(doc);\n return `deleted scene ${n.scene.anchor} with ${n.scene.actions.length} action(s)` + since(doc, base);\n }\n if (n.t === \"ep\") {\n const acts = n.ep.scenes.reduce((m, s) => m + s.actions.length, 0);\n if (n.ep.scenes.length && !opts.force) {\n throw new Error(`episode ${n.ep.no} still holds ${n.ep.scenes.length} scene(s) / ${acts} action(s)`\n + ` \u2014 pass --force to delete the episode and everything in it`);\n }\n const list = doc.raw.episodes;\n list.splice(list.indexOf(n.ep.raw), 1);\n step(\"del\", `episode ${n.ep.no}`);\n save(doc);\n return `deleted episode ${n.ep.no} (${n.ep.id}) with ${n.ep.scenes.length} scene(s) / ${acts} action(s)`;\n }\n if (n.t === \"asset\")\n return delAsset(doc, n.asset, opts) + since(doc, base);\n if (n.t === \"state\")\n return delState(doc, n.asset, n.state, opts) + since(doc, base);\n throw new Error(`del takes an action, scene, episode, asset or state (got ${n.t})`);\n}\n/** Every place a scene or a speaker points at this asset. */\nfunction assetUses(doc, id) {\n const scenes = [];\n for (const ep of doc.episodes)\n for (const s of ep.scenes) {\n if ([s.location, ...s.actors, ...s.props].some((r) => r && r.id === id))\n scenes.push(s);\n }\n return { scenes, speakers: allActions(doc).filter((a) => a.speaker?.id === id) };\n}\nfunction delAsset(doc, a, opts) {\n const { scenes, speakers } = assetUses(doc, a.id);\n const used = scenes.length + speakers.length;\n if (used && !opts.replacement && !opts.force) {\n throw new Error(`${a.name} is still referenced by ${scenes.length} scene(s)`\n + ` and ${speakers.length} speaker(s) \u2014 merge it into another asset with`\n + ` \\`merge ${a.id} <other>\\`, or pass --force to strip every reference`);\n }\n if (opts.replacement)\n return merge(doc, a.id, opts.replacement);\n for (const s of scenes) {\n if (s.raw.location?.[`${a.kind}_id`] === a.id)\n s.raw.location = null;\n for (const f of [\"actors\", \"props\"]) {\n const list = s.raw[f];\n if (!list)\n continue;\n const i = list.findIndex((r) => r[`${a.kind}_id`] === a.id);\n if (i >= 0)\n list.splice(i, 1);\n }\n }\n for (const act of speakers)\n delete act.raw.speaker;\n const field = ASSET_FIELD[a.kind];\n const list = doc.raw[field];\n list.splice(list.indexOf(a.raw), 1);\n step(\"del\", `asset ${a.id}, stripped ${scenes.length} scene refs + ${speakers.length} speakers`);\n save(doc);\n return `deleted ${a.kind} ${a.id} ${a.name}`\n + (used ? `\\nstripped ${scenes.length} scene reference(s) and ${speakers.length} speaker(s)` : \"\");\n}\nfunction delState(doc, a, st, opts) {\n if (st.id === \"default\")\n throw new Error(`every asset keeps its default state; delete the asset instead`);\n const scenes = doc.episodes.flatMap((e) => e.scenes).filter((s) => [s.location, ...s.actors, ...s.props].some((r) => r && r.id === a.id && r.states.includes(st.id)));\n const speakers = allActions(doc).filter((x) => x.speaker?.id === a.id && x.speaker.state === st.id);\n const used = scenes.length + speakers.length;\n let rewired = \"\";\n if (used) {\n if (!opts.replacement && !opts.force) {\n throw new Error(`${a.name}/${st.name} is bound in ${scenes.length} scene(s)`\n + ` and named by ${speakers.length} speaker(s) \u2014 pass --replacement <state> to rewire them,`\n + ` or --force to drop the bindings`);\n }\n let to;\n if (opts.replacement) {\n const hit = a.states.filter((x) => x.id === opts.replacement || x.name === opts.replacement);\n if (hit.length !== 1)\n throw new Error(`${a.name} has no single state \"${opts.replacement}\"`);\n if (hit[0].id === st.id)\n throw new Error(`replacement must differ from the state being deleted`);\n to = hit[0].id;\n }\n for (const s of scenes) {\n for (const r of [s.raw.location, ...(s.raw.actors ?? []), ...(s.raw.props ?? [])]) {\n if (!r || r[`${a.kind}_id`] !== a.id)\n continue;\n if (doc.version === 4) {\n const next = new Set(r.state_ids.filter((x) => x !== st.id));\n if (to)\n next.add(to);\n if (!next.size)\n next.add(\"default\");\n r.state_ids = [...next].sort();\n }\n else\n r[`state_id`] = to ?? \"default\";\n }\n }\n for (const x of speakers) {\n if (to)\n x.raw.speaker.state_id = to;\n else\n delete x.raw.speaker.state_id;\n }\n rewired = `\\n${to ? `rewired` : `cleared`} ${scenes.length} scene binding(s)`\n + ` and ${speakers.length} speaker(s)${to ? ` to ${stateName(doc, a.id, to)}` : \"\"}`;\n }\n const list = a.raw.states;\n list.splice(list.findIndex((x) => x.state_id === st.id), 1);\n step(\"del\", `state ${a.id}/${st.id}`);\n save(doc);\n return `deleted state ${a.id}/${st.id} ${st.name}` + rewired;\n}\n/**\n * Fold one asset into another: every scene reference and speaker moves to the\n * target, then the source is removed. States are matched by name where the\n * target has one, and otherwise carried over.\n */\nexport function merge(doc, srcAddr, dstAddr) {\n const s = resolve(doc, srcAddr), d = resolve(doc, dstAddr);\n if (s.t !== \"asset\" || d.t !== \"asset\")\n throw new Error(`merge takes two assets`);\n if (s.asset === d.asset)\n throw new Error(`cannot merge ${s.asset.name} into itself`);\n if (s.asset.kind !== d.asset.kind) {\n throw new Error(`cannot merge a ${s.asset.kind} into a ${d.asset.kind}`);\n }\n const base = baseline(doc);\n const src = s.asset, dst = d.asset;\n const kindKey = `${src.kind}_id`;\n // Map every source state onto a target state: same name if the target has it,\n // otherwise copy the definition across under a fresh id.\n const taken = new Set(dst.states.map((x) => x.id));\n const map = new Map();\n for (const st of src.states) {\n const same = dst.states.find((x) => x.name === st.name);\n if (same) {\n map.set(st.id, same.id);\n continue;\n }\n if (st.id === \"default\") {\n map.set(st.id, \"default\");\n continue;\n }\n const id = doc.version === 4 ? newId(\"st\", taken) : `st_${String(dst.states.length + map.size).padStart(3, \"0\")}`;\n dst.raw.states.push({ state_id: id, state_name: st.name, description: st.desc });\n map.set(st.id, id);\n }\n const { scenes, speakers } = assetUses(doc, src.id);\n for (const scene of scenes) {\n for (const field of [\"location\", \"actors\", \"props\"]) {\n const slot = scene.raw[field];\n const list = field === \"location\" ? (slot ? [slot] : []) : (slot ?? []);\n for (const r of list) {\n if (r[kindKey] !== src.id)\n continue;\n r[kindKey] = dst.id;\n if (doc.version === 4) {\n r.state_ids = [...new Set(r.state_ids.map((x) => map.get(x) ?? \"default\"))].sort();\n }\n else\n r.state_id = map.get(r.state_id) ?? \"default\";\n }\n // The target may already be referenced in this scene; one asset, one entry.\n if (field !== \"location\" && Array.isArray(slot)) {\n const merged = [];\n for (const r of slot) {\n const prev = merged.find((x) => x[kindKey] === r[kindKey]);\n if (!prev) {\n merged.push(r);\n continue;\n }\n if (doc.version === 4) {\n prev.state_ids = [...new Set([...prev.state_ids, ...r.state_ids])].sort();\n }\n }\n scene.raw[field] = merged;\n }\n }\n }\n for (const a of speakers) {\n a.raw.speaker.actor_id = dst.id;\n if (a.raw.speaker.state_id)\n a.raw.speaker.state_id = map.get(a.raw.speaker.state_id) ?? \"default\";\n }\n const list = doc.raw[ASSET_FIELD[src.kind]];\n list.splice(list.indexOf(src.raw), 1);\n step(\"merge\", `${src.id} -> ${dst.id}: ${scenes.length} scenes, ${speakers.length} speakers`);\n save(doc);\n return `merged ${src.id} ${src.name} into ${dst.id} ${dst.name}`\n + `\\nmoved ${scenes.length} scene reference(s), ${speakers.length} speaker(s),`\n + ` ${[...map].filter(([k, v]) => k !== v).length} state mapping(s)` + since(doc, base);\n}\n", "// `scriptctl ingest` \u2014 bare command (\u00A74). Converts a txt/md/docx or video source\n// into a Script v4 workspace (script.jsonl \u2192 script.initial.json \u2192 script.json).\n// Fully decoupled from `direct`: touches only ingest domain/infra + llm + common.\n\nimport * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT, EXIT_OK, type CommandOutput } from \"../../common.js\";\nimport { resolveSource } from \"../../infra/ingest/source-resolver.js\";\nimport { PRODUCTION_LLM_COMPOSITION, type LlmComposition } from \"../../llm/composition.js\";\nimport type {\n LlmExecutorOptions,\n VideoProviderCredential,\n VideoProviderOverrides,\n VideoUploadMode,\n} from \"../../llm/types.js\";\nimport { runTextIngest } from \"./pipeline.js\";\nimport { runVideoIngest } from \"./video-pipeline.js\";\n\ntype Dict = Record<string, unknown>;\nconst strOf = (v: unknown): string => (v === null || v === undefined ? \"\" : String(v));\nconst intOf = (v: unknown, fallback: number): number => {\n const n = Number(v);\n return Number.isInteger(n) && n > 0 ? n : fallback;\n};\n\nconst VIDEO_OPTION_KEYS = [\n \"upload_mode\",\n \"provider_base_url\",\n \"provider_api_key\",\n \"provider_api_key_env\",\n \"provider_model\",\n \"step\",\n] as const;\n\nfunction invalidVideoOption(message: string, actual: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VIDEO_OPTION_INVALID\",\n hint: \"Use these options only with a video file or video episode directory.\",\n data: { actual },\n });\n}\n\nfunction optionProvided(opts: Dict, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(opts, key) && opts[key] !== undefined;\n}\n\nfunction requiredOptionValue(opts: Dict, key: string, flag: string): string | undefined {\n if (!optionProvided(opts, key)) return undefined;\n const value = strOf(opts[key]).trim();\n if (!value) throw invalidVideoOption(`${flag} requires a non-empty value.`, [flag]);\n return value;\n}\n\nfunction uploadModeOf(opts: Dict): VideoUploadMode {\n const mode = requiredOptionValue(opts, \"upload_mode\", \"--upload-mode\") ?? \"file-api\";\n if (mode !== \"file-api\" && mode !== \"base64\") {\n throw invalidVideoOption(\"Video upload mode must be file-api or base64.\", [`--upload-mode ${mode}`]);\n }\n return mode;\n}\n\nfunction providerOverridesOf(opts: Dict): VideoProviderOverrides | undefined {\n const literalKeyProvided = optionProvided(opts, \"provider_api_key\");\n const keyEnvProvided = optionProvided(opts, \"provider_api_key_env\");\n if (literalKeyProvided && keyEnvProvided) {\n throw invalidVideoOption(\"Provider API key options are mutually exclusive.\", [\n \"--provider-api-key\",\n \"--provider-api-key-env\",\n ]);\n }\n const baseUrl = requiredOptionValue(opts, \"provider_base_url\", \"--provider-base-url\");\n const literalKey = requiredOptionValue(opts, \"provider_api_key\", \"--provider-api-key\");\n const keyEnv = requiredOptionValue(opts, \"provider_api_key_env\", \"--provider-api-key-env\");\n const model = requiredOptionValue(opts, \"provider_model\", \"--provider-model\");\n if (keyEnv !== undefined && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(keyEnv)) {\n throw invalidVideoOption(\"Provider API key environment variable name is invalid.\", [keyEnv]);\n }\n let apiKey: VideoProviderCredential | undefined;\n if (literalKey !== undefined) apiKey = { kind: \"literal\", value: literalKey };\n else if (keyEnv !== undefined) apiKey = { kind: \"env\", name: keyEnv };\n if (!baseUrl && !apiKey && !model) return undefined;\n return {\n ...(baseUrl ? { baseUrl } : {}),\n ...(apiKey ? { apiKey } : {}),\n ...(model ? { model } : {}),\n };\n}\n\nexport async function commandIngest(opts: Dict, composition: LlmComposition = PRODUCTION_LLM_COMPOSITION): Promise<[CommandOutput, number]> {\n const sourcePath = strOf(opts[\"source_path\"]).trim();\n if (!sourcePath) {\n throw new CliError(\"ingest needs a source file or directory.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_NO_SOURCE\",\n hint: \"Pass a txt/md/docx file or a video file/directory: scriptctl ingest --source-path <path>.\",\n data: { expected: [\"--source-path <file|dir>\"] },\n });\n }\n // Resolve to an absolute path so the workspace location is explicit and\n // independent of cwd \u2014 the default \"workspace\" would otherwise land silently\n // under wherever the command happened to run. Downstream (view / publish /\n // ingest status / the runtime watcher) then all agree on one concrete dir.\n const workspacePath = path.resolve(strOf(opts[\"workspace_path\"] || \"workspace\"));\n const resolved = resolveSource(sourcePath);\n const explicitVideoOptions = VIDEO_OPTION_KEYS.filter((key) => {\n const value = opts[key];\n return typeof value === \"boolean\" ? value : optionProvided(opts, key);\n });\n if (resolved.kind === \"text\" && explicitVideoOptions.length > 0) {\n throw invalidVideoOption(\"Video ingest options cannot be used with a text source.\", explicitVideoOptions.map((key) => `--${key.replace(/_/g, \"-\")}`));\n }\n\n if (resolved.kind !== \"text\") {\n const uploadMode = uploadModeOf(opts);\n const videoProvider = providerOverridesOf(opts);\n const executorOptions: LlmExecutorOptions | undefined = videoProvider ? { videoProvider } : undefined;\n const executor = composition.createExecutor(strOf(opts[\"llm_config\"]).trim() || undefined, executorOptions);\n const configuredRoute = executor.route(\"ingest.video-serial\");\n const report = await runVideoIngest({\n sourcePath,\n workspacePath,\n executor,\n fps: intOf(opts[\"fps\"], 3),\n force: Boolean(opts[\"force\"]),\n step: Boolean(opts[\"step\"]),\n uploadMode,\n });\n const result = [\n `workspace: ${report.workspacePath}`,\n `${report.completed}/${report.episodes} episodes complete (${report.processed} processed / ${report.reused} reused / ${report.remaining} remaining) \u2192 ${report.scriptPath}`,\n ...(report.skipped > 0 ? [`skipped: ${report.skippedEpisodes.join(\", \")}`] : []),\n `assets: ${report.assets.actors} actors / ${report.assets.locations} locations / ${report.assets.props} props`,\n ];\n const actualRoute = [...executor.usageEvents()].reverse().find((event) =>\n event.task === \"ingest.video-serial\" && event.status === \"succeeded\"\n ) ?? configuredRoute;\n return [{\n text: result.join(\"\\n\"),\n data: {\n workspace: report.workspacePath,\n script_path: report.scriptPath,\n episodes: report.episodes,\n processed: report.processed,\n reused: report.reused,\n parsed: report.completed - report.skipped,\n skipped: report.skipped,\n skipped_episodes: report.skippedEpisodes,\n has_skips: report.skipped > 0,\n completed: report.completed,\n remaining: report.remaining,\n complete: report.complete,\n next_episode: report.nextEpisode,\n upload_mode: report.uploadMode,\n route: {\n protocol: actualRoute.protocol,\n provider: actualRoute.provider,\n base_url: actualRoute.baseUrl,\n model: actualRoute.model,\n },\n assets: report.assets,\n },\n }, EXIT_OK];\n }\n\n const executor = composition.createExecutor(strOf(opts[\"llm_config\"]).trim() || undefined);\n const report = await runTextIngest({\n sourcePath,\n workspacePath,\n executor,\n concurrency: intOf(opts[\"concurrency\"], 30),\n force: Boolean(opts[\"force\"]),\n });\n\n const result = [\n `workspace: ${report.workspacePath}`,\n `${report.records} records, ${report.chunks} chunks \u2192 ${report.scriptPath}`,\n `assets: ${report.assets.actors} actors / ${report.assets.locations} locations / ${report.assets.props} props`,\n ];\n return [{\n text: result.join(\"\\n\"),\n data: {\n workspace: report.workspacePath,\n script_path: report.scriptPath,\n records: report.records,\n chunks: report.chunks,\n assets: report.assets,\n },\n }, EXIT_OK];\n}\n", "// Ingest source resolver (\u00A73.2/\u00A710.1). Classifies a source path into text or\n// video and enforces the strict input allowlist. PDF/JSON/XLSX are explicitly\n// unsupported here (they belong to other commands), returning a clear error.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nexport const TEXT_EXTENSIONS = [\".txt\", \".md\", \".docx\"] as const;\n\n// Common Gemini-ingestible video containers (\u00A710.1); extension \u2192 MIME.\nexport const VIDEO_MIME: Readonly<Record<string, string>> = {\n \".mp4\": \"video/mp4\",\n \".mov\": \"video/mov\",\n \".avi\": \"video/avi\",\n \".mpeg\": \"video/mpeg\",\n \".mpg\": \"video/mpg\",\n \".webm\": \"video/webm\",\n \".flv\": \"video/x-flv\",\n \".wmv\": \"video/wmv\",\n};\n\nexport type SourceKind = \"text\" | \"video-file\" | \"video-directory\";\n\nexport class UnsupportedInputError extends Error {\n constructor(readonly received: string) {\n super(`Unsupported input: ${received}`);\n }\n}\n\nfunction ext(p: string): string {\n return path.extname(p).toLowerCase();\n}\n\nfunction isVideoExt(e: string): boolean {\n return Object.hasOwn(VIDEO_MIME, e);\n}\n\nexport type ResolvedSource =\n | { kind: \"text\"; path: string; ext: string }\n | { kind: \"video-file\"; path: string; ext: string }\n | { kind: \"video-directory\"; path: string; files: string[] };\n\nexport function resolveSource(sourcePath: string): ResolvedSource {\n const stat = fs.statSync(sourcePath);\n if (stat.isDirectory()) {\n // Directory input is only for a set of video episodes (\u00A710.1); scan one level.\n const entries = fs.readdirSync(sourcePath)\n .filter((name) => !name.startsWith(\".\"))\n .filter((name) => isVideoExt(ext(name)))\n .sort()\n .map((name) => path.join(sourcePath, name));\n if (entries.length === 0) throw new UnsupportedInputError(`directory has no supported video files: ${sourcePath}`);\n return { kind: \"video-directory\", path: sourcePath, files: entries };\n }\n const e = ext(sourcePath);\n if ((TEXT_EXTENSIONS as readonly string[]).includes(e)) return { kind: \"text\", path: sourcePath, ext: e };\n if (isVideoExt(e)) return { kind: \"video-file\", path: sourcePath, ext: e };\n throw new UnsupportedInputError(`file extension ${e || \"(none)\"} is not supported by ingest (txt/md/docx/video only)`);\n}\n", "import { createLlmExecutor } from \"./router.js\";\nimport type { LlmExecutorOptions, LlmTaskExecutor } from \"./types.js\";\n\nexport interface LlmComposition {\n createExecutor(configPath?: string, options?: LlmExecutorOptions): LlmTaskExecutor;\n}\n\nexport const PRODUCTION_LLM_COMPOSITION: LlmComposition = {\n createExecutor: createLlmExecutor,\n};\n", "// Text ingest pipeline (\u00A76): pass1-prepare \u2192 pass2-normalize (fanout) \u2192\n// pass3-merge \u2192 pass4-mention-resolve \u2192 compile (deterministic assembler) \u2192\n// pass5-extract \u2192 SERIAL govern. The front (through assemble+extract) handles the\n// context-local body in parallel; the serial govern pass then walks episodes in\n// order carrying a running context to decide identity/importance/durable-states\n// WITH plot understanding (see serial-govern.ts), replacing the old parallel\n// curate/recall/refine/state-reconcile compensation. Workspace lifecycle per \u00A75.3.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT, sha256Text } from \"../../common.js\";\nimport { assemble, type NameScript } from \"../../domain/ingest/assembler.js\";\nimport { chunkSource, type Chunk } from \"../../domain/ingest/chunker.js\";\nimport { parseJsonl } from \"../../domain/ingest/jsonl-parser.js\";\nimport { validateProductionStandard } from \"../../domain/ingest/production-validation.js\";\nimport { renumberIds } from \"../../domain/ingest/renumber.js\";\nimport type { IngestRecord } from \"../../domain/ingest/records.js\";\nimport { validateScriptV3 } from \"../../domain/ingest/validation.js\";\nimport { requireScriptV3 } from \"../../domain/script/v3/parse.js\";\nimport {\n newScriptV4FromV3WithIdentity,\n type V4IdentityMap,\n} from \"../../domain/script/v4/from-v3.js\";\nimport { validateScriptV4 } from \"../../domain/script/v4/validation.js\";\nimport { resolveSource } from \"../../infra/ingest/source-resolver.js\";\nimport { readTextSource } from \"../../infra/ingest/text-reader.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\nimport { runTextNormalize, parseNormalizeOutput } from \"../../llm/tasks/ingest/text-normalize.js\";\nimport type { LlmTaskExecutor } from \"../../llm/types.js\";\nimport { detectBodyStart } from \"./body-start.js\";\nimport { mapSettled } from \"./fanout.js\";\nimport { runSerialGovern } from \"./serial-govern.js\";\nimport { assetAuditWarnings, auditWorkspaceScriptAssets } from \"./final-asset-audit.js\";\nimport { Timings } from \"./timings.js\";\nimport { UsageLedger, type UsageScope } from \"./usage-report.js\";\n\nconst PIPELINE_VERSION = \"12\";\n\nexport interface TextIngestOptions {\n sourcePath: string;\n workspacePath: string;\n executor: LlmTaskExecutor;\n concurrency?: number;\n force?: boolean;\n signal?: AbortSignal;\n}\n\nexport interface TextIngestReport {\n workspacePath: string;\n chunks: number;\n reused: number;\n records: number;\n notes: number;\n assets: { actors: number; locations: number; props: number };\n scriptPath: string;\n validation: { ok: boolean; errors: number; warnings: number };\n}\n\nconst pad = (n: number): string => String(n).padStart(3, \"0\");\nconst serializeJsonl = (records: IngestRecord[]): string => records.map((r) => JSON.stringify(r)).join(\"\\n\") + \"\\n\";\n\nfunction checkLifecycle(store: WorkspaceStore, sourceSha: string, force: boolean): void {\n if (store.has(\"manifest.json\")) {\n const manifest = store.readJson<{ pipeline_version?: string; source?: { sha256?: string } }>(\"manifest.json\");\n if (manifest.source?.sha256 && manifest.source.sha256 !== sourceSha) {\n throw new CliError(\"This workspace was built from a different source. --force cannot switch sources.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SOURCE_MISMATCH\",\n hint: \"Choose a fresh --workspace-path for the new source.\",\n data: { actual: [\"workspace source differs from --source-path\"] },\n });\n }\n if (!force && manifest.pipeline_version && manifest.pipeline_version !== PIPELINE_VERSION) {\n throw new CliError(\"This workspace was created by an older text-ingest pipeline.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_PIPELINE_MISMATCH\",\n hint: \"Rerun `scriptctl ingest --force` with the same source to rebuild its checkpoints.\",\n data: { actual: [`workspace pipeline ${manifest.pipeline_version}; current ${PIPELINE_VERSION}`] },\n });\n }\n }\n if (force) {\n for (const dir of [\"pass1\", \"pass2\", \"pass3\", \"pass5\", \"serial\"]) fs.rmSync(store.path(dir), { recursive: true, force: true });\n for (const f of [\n \"body.json\",\n \"script.initial.json\",\n \"script.json\",\n \"validation.json\",\n \"asset-audit.json\",\n \"notes.json\",\n \"issues.json\",\n \"provisional_assets.json\",\n \"usage.json\",\n \"v4_identity_map.json\",\n ]) fs.rmSync(store.path(f), { force: true });\n }\n}\n\nexport async function runTextIngest(opts: TextIngestOptions): Promise<TextIngestReport> {\n const resolved = resolveSource(opts.sourcePath);\n if (resolved.kind !== \"text\") {\n throw new CliError(\"runTextIngest received a non-text source.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_WRONG_PIPELINE\",\n });\n }\n const text = await readTextSource(resolved.path, resolved.ext);\n const sourceSha = sha256Text(text);\n\n const store = new WorkspaceStore(opts.workspacePath);\n store.ensure();\n checkLifecycle(store, sourceSha, opts.force ?? false);\n\n // Accurate per-run timing \u2192 workspace/timings.json (view --watch / ingest status).\n const timings = new Timings((t) => store.writeJson(\"timings.json\", t));\n const usage = new UsageLedger(store, opts.executor);\n let runStatus: \"succeeded\" | \"failed\" = \"failed\";\n try {\n const prepareStartedMs = Date.now();\n\n // pass0: locate where the real screenplay body begins and drop the planning\n // front matter (\u5927\u7EB2/\u89D2\u8272\u5361/\u5B8F\u89C2\u7ED3\u6784/\u4E00\u5361\u96C6\u7EB2) before it. Cheap tool-mode LLM scan,\n // cached under pass1/ so a rerun skips it; --force wipes pass1 and recomputes.\n let bodyStart = 0;\n if (!opts.force && store.has(\"pass1/body_start.json\")) {\n bodyStart = store.readJson<{ line?: number }>(\"pass1/body_start.json\").line ?? 0;\n opts.executor.recordReuse(\"ingest.body-start\");\n } else {\n const scan = await detectBodyStart(opts.executor, text, opts.signal);\n bodyStart = scan.line;\n store.writeJson(\"pass1/body_start.json\", scan);\n }\n const lines0 = text.split(\"\\n\");\n const bodyText = bodyStart > 0 ? lines0.slice(bodyStart).join(\"\\n\") : text;\n // The stripped front matter (\u89D2\u8272\u5361/\u8BBE\u5B9A) \u2014 capped \u2014 is fed to serial govern as an\n // \u539F\u6587\u8BBE\u5B9A reference so descriptions can draw on the source's own wording.\n const sourceRef = bodyStart > 0 ? lines0.slice(0, bodyStart).join(\"\\n\").trim().slice(0, 6000) : \"\";\n\n // pass1: prepare + chunk (the body only; full source kept for reference).\n const chunks = chunkSource(bodyText);\n store.writeText(\"pass1/source.txt\", text);\n store.writeJson(\"pass1/chunks.json\", chunks.map((c) => ({ index: c.index, core_line_start: c.core_line_start, core_line_end: c.core_line_end })));\n store.writeJson(\"manifest.json\", {\n version: 1,\n pipeline_version: PIPELINE_VERSION,\n updated: new Date().toISOString(),\n source: { path: path.resolve(resolved.path), sha256: sourceSha, kind: \"text\", ext: resolved.ext },\n chunks: chunks.length,\n });\n usage.flush({\n scope: { kind: \"phase\", phase: \"prepare\" },\n status: \"succeeded\",\n startedAtMs: prepareStartedMs,\n });\n\n // pass2: normalize fanout with per-chunk structured JSON checkpoint.\n let reused = 0;\n timings.phaseStart(\"normalize\");\n const settled = await mapSettled(chunks, opts.concurrency ?? 30, async (chunk: Chunk) => {\n const jsonRel = `pass2/chunk_${pad(chunk.index)}.json`;\n const errorRel = `pass2/chunk_${pad(chunk.index)}.error.json`;\n if (store.has(jsonRel) && !opts.force) {\n const records = parseNormalizeOutput(store.readJson<unknown>(jsonRel), chunk);\n store.clearError(errorRel);\n reused++;\n opts.executor.recordReuse(\"ingest.text-normalize\");\n return records;\n }\n const { raw, records } = await runTextNormalize(opts.executor, chunk, opts.signal);\n store.writeText(jsonRel, raw);\n store.writeText(`pass2/chunk_${pad(chunk.index)}.jsonl`, serializeJsonl(records));\n store.clearError(errorRel);\n return records;\n });\n\n const failures = settled.filter((s): s is Extract<typeof s, { ok: false }> => !s.ok);\n for (const f of failures) {\n const message = f.error instanceof Error ? f.error.message : String(f.error);\n store.writeJson(`pass2/chunk_${pad(f.index)}.error.json`, { chunk: f.index, error: message });\n }\n usage.flush({\n scope: { kind: \"phase\", phase: \"normalize\" },\n status: failures.length ? \"failed\" : \"succeeded\",\n });\n if (failures.length > 0) {\n throw new CliError(`${failures.length}/${chunks.length} chunk(s) failed normalization.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_NORMALIZE_INCOMPLETE\",\n hint: \"Inspect pass2/chunk_NNN.error.json and rerun `scriptctl ingest` to resume.\",\n data: { actual: failures.map((f) => `chunk ${f.index}`) },\n });\n }\n timings.phaseEnd(\"normalize\");\n\n // pass3 merge \u2192 pass4 mention-resolve \u2192 assemble = the name-based BODY (\u6B63\u6587).\n // NO asset extraction / id assignment here \u2014 the serial pass discovers assets,\n // \u9020\u578B and per-scene presence itself from the body. Reuse body.json on a rerun so\n // a serial failure doesn't redo pass3/pass4/assemble.\n let body: NameScript;\n let recordCount: number;\n let noteCount: number;\n if (!opts.force && store.has(\"body.json\")) {\n body = store.readJson<NameScript>(\"body.json\");\n recordCount = store.has(\"pass3/script.jsonl\") ? parseJsonl(store.readText(\"pass3/script.jsonl\")).length : 0;\n noteCount = store.has(\"notes.json\") ? store.readJson<unknown[]>(\"notes.json\").length : 0;\n reused++;\n } else {\n // pass3: merge normalized chunks in source order. Dialogue stays verbatim in\n // its source language; non-dialogue screenplay prose is already localized to\n // Simplified Chinese by pass2. The serial pass resolves identity from context\n // instead of rewriting the body.\n const merged: IngestRecord[] = [];\n for (const s of settled) if (s.ok) merged.push(...s.value);\n store.writeText(\"pass3/script.jsonl\", serializeJsonl(merged));\n const reparsed = parseJsonl(store.readText(\"pass3/script.jsonl\")); // round-trip validation\n\n // compile: assemble the name-based body (scenes + actions).\n const title = deriveTitle(resolved.path);\n const assembled = assemble(reparsed, { title });\n store.writeJson(\"notes.json\", assembled.notes);\n body = assembled.script;\n store.writeJson(\"body.json\", body);\n recordCount = merged.length;\n noteCount = assembled.notes.length;\n }\n\n // Serial govern: context starts EMPTY and grows per episode; the model reads each\n // episode's body + context-so-far and reports discovered entities / importance /\n // \u9020\u578B / per-scene presence. The governed v3 intermediate is converted to v4. Every step\n // persists the full context md (= prompt) and the model's `# \u66F4\u65B0` md; resume\n // replays cached `# \u66F4\u65B0` (no LLM). Cleared by --force (serial dir wiped).\n const pad3 = (n: number): string => String(n).padStart(3, \"0\");\n // One window (1+ contiguous episodes) per `serial/win_<start>_<end>.json`; the\n // filename range is deterministic (pure packing), so resume replays from cache.\n // Content is the model's raw tool-call Delta (JSON) \u2014 `.json`, not `.md`. The\n // context_ trace (rendered prompt) and arc_ summary stay markdown.\n const winRel = (startEp: number, endEp: number): string => `serial/win_${pad3(startEp)}_${pad3(endEp)}.json`;\n const serialCheckpoint = {\n readUpdate: (startEp: number, endEp: number): string | undefined => (store.has(winRel(startEp, endEp)) ? store.readText(winRel(startEp, endEp)) : undefined),\n writeStep: (startEp: number, endEp: number, contextMd: string, updateMd: string): void => {\n store.writeText(`serial/context_${pad3(startEp)}.md`, contextMd);\n store.writeText(winRel(startEp, endEp), updateMd);\n },\n readArc: (startEp: number, endEp: number): string | undefined => {\n const rel = `serial/arc_${pad3(startEp)}_${pad3(endEp)}.md`;\n return store.has(rel) ? store.readText(rel) : undefined;\n },\n writeArc: (startEp: number, endEp: number, summaryMd: string): void => {\n store.writeText(`serial/arc_${pad3(startEp)}_${pad3(endEp)}.md`, summaryMd);\n },\n readNameFix: (startEp: number, endEp: number): string | undefined => {\n const rel = `serial/fix_${pad3(startEp)}_${pad3(endEp)}.json`;\n return store.has(rel) ? store.readText(rel) : undefined;\n },\n writeNameFix: (startEp: number, endEp: number, raw: string): void => store.writeText(`serial/fix_${pad3(startEp)}_${pad3(endEp)}.json`, raw),\n };\n timings.phaseStart(\"serial\");\n const serial = await runSerialGovern(body, {\n executor: opts.executor, checkpoint: serialCheckpoint, force: opts.force ?? false,\n ...(sourceRef ? { sourceRef } : {}),\n onWindow: (t) => {\n if (t.index === 0) timings.serialStart(t.total, t.totalEpisodes);\n timings.windowDone(t.startEp, t.endEp, t.ms, t.cached);\n const scope: UsageScope = t.startEp === t.endEp\n ? { kind: \"episode\", episode: t.startEp }\n : { kind: \"episode-range\", startEpisode: t.startEp, endEpisode: t.endEp };\n const endedAtMs = Date.now();\n usage.flush({\n scope,\n status: t.cached ? \"reused\" : \"succeeded\",\n startedAtMs: endedAtMs - t.ms,\n endedAtMs,\n });\n },\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n const governed = serial.doc;\n reused += serial.reused;\n // Audit: entities the engine auto-created because a merge named an unregistered\n // `into`. Written so this implicit step is inspectable, never silent.\n timings.phaseEnd(\"serial\");\n // Final clean numbering: contiguous per-kind asset ids + per-asset state ids.\n timings.phaseStart(\"govern\");\n const { script: renumbered, idMap } = renumberIds(governed);\n store.writeJson(\"id_map.json\", idMap);\n const intermediateValidation = validateScriptV3(renumbered);\n if (!intermediateValidation.ok) {\n store.writeJson(\"validation.json\", intermediateValidation);\n throw new CliError(\"Intermediate script failed validation before v4 identity assignment.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VALIDATION_FAILED\",\n hint: \"Inspect validation.json.\",\n data: { actual: intermediateValidation.errors.slice(0, 5).map((e) => `${e.path}: ${e.message}`) },\n });\n }\n const priorIdentity = !opts.force && store.has(\"v4_identity_map.json\")\n ? store.readJson<V4IdentityMap>(\"v4_identity_map.json\")\n : undefined;\n // V4 identities bind to the stable pre-renumber ingest keys. The contiguous\n // V3 ids in `renumbered` are an audit artifact only: deleting or merging an\n // earlier entity can shift them onto a different surviving entity.\n const converted = newScriptV4FromV3WithIdentity(\n requireScriptV3(governed),\n priorIdentity,\n serial.identityKeys,\n );\n const finalScript = converted.script;\n const structuralValidation = validateScriptV4(finalScript);\n let auditWarnings = [] as ReturnType<typeof assetAuditWarnings>;\n const auditStartedMs = Date.now();\n let auditStatus: \"succeeded\" | \"failed\" = \"failed\";\n try {\n if (structuralValidation.ok) {\n const audit = await auditWorkspaceScriptAssets(store, finalScript, opts.executor, {\n force: opts.force ?? false,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n auditWarnings = assetAuditWarnings(audit.report);\n }\n auditStatus = \"succeeded\";\n } finally {\n usage.flush({\n scope: { kind: \"phase\", phase: \"asset-audit\" },\n status: auditStatus,\n startedAtMs: auditStartedMs,\n });\n }\n const validation = {\n ...structuralValidation,\n warnings: [\n ...structuralValidation.warnings,\n ...validateProductionStandard(finalScript),\n ...auditWarnings,\n ],\n };\n store.writeJson(\"pass5/script.json\", finalScript);\n store.writeJson(\"v4_identity_map.json\", converted.identityMap);\n store.writeJson(\"validation.json\", validation);\n if (!validation.ok) {\n throw new CliError(\"Final script.json failed v4 validation.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VALIDATION_FAILED\",\n hint: \"Inspect validation.json.\",\n data: { actual: validation.errors.slice(0, 5).map((e) => `${e.path}: ${e.message}`) },\n });\n }\n store.writeJson(\"script.json\", finalScript);\n timings.phaseEnd(\"govern\");\n timings.finish();\n\n const g = finalScript;\n runStatus = \"succeeded\";\n return {\n workspacePath: store.root,\n chunks: chunks.length,\n reused,\n records: recordCount,\n notes: noteCount,\n assets: { actors: g.actors?.length ?? 0, locations: g.locations?.length ?? 0, props: g.props?.length ?? 0 },\n scriptPath: store.path(\"script.json\"),\n validation: { ok: validation.ok, errors: validation.errors.length, warnings: validation.warnings.length },\n };\n } finally {\n usage.finish(runStatus);\n }\n}\n\nfunction deriveTitle(sourcePath: string): string {\n return path.basename(sourcePath, path.extname(sourcePath));\n}\n", "// Deterministic assembler (\u00A78): merged JSONL records \u2192 provisional Script v3.\n// Two steps: (1) assemble() builds a name-based script skeleton (plain-text\n// content; scene-level cast = declared `\u4EBA\u7269\uFF1A` \u222A dialogue speakers; declared\n// props); (2) assignProvisionalIds() turns names into provisional ids and builds\n// the Pass5 evidence roster. pass5-extract augments the name-based scene cast\n// between the two steps. Pure and byte-stable. Body before the first scene\n// (preamble/outline) is captured as a note, not fatal; a scene that arrives\n// before any episode header auto-opens a synthetic episode rather than aborting\n// (pass0 strips outline front matter, but a stray scene must never crash).\n\nimport type {\n NameStateRef,\n IngestRecord,\n SourceSpan,\n SpeakerRef,\n} from \"./records.js\";\n\nexport type ProvisionalOccurrence = { episode: number; scene: number };\nexport type ProvisionalAsset = {\n provisional_id: string;\n kind: \"actor\" | \"location\" | \"prop\";\n names: string[];\n states: Array<{ name: string; id: string }>; // id is globally unique so merges never collide\n occurrences: ProvisionalOccurrence[];\n};\n\n// Name-based intermediate script (pre id-assignment). Loosely typed on purpose.\nexport type NameScene = {\n identity_key: string;\n scene_id: string;\n environment?: { space?: string; time?: string };\n location: NameStateRef | null;\n actors: NameStateRef[];\n props: NameStateRef[];\n actions: Array<{\n identity_key: string;\n type: string;\n content: string;\n speaker?: SpeakerRef;\n emotion?: string;\n parenthetical?: string;\n extend?: Record<string, unknown>;\n }>;\n};\nexport type NameScript = {\n title: string;\n episodes: Array<{\n identity_key: string;\n episode_id: string;\n title?: string;\n scenes: NameScene[];\n }>;\n};\nexport type AssembleResult = { script: NameScript; notes: Array<{ content: string; category?: string; source: unknown }> };\nexport interface StructuralIdentityKeys {\n episode: Record<string, string>;\n scene: Record<string, string>;\n action: Record<string, string>;\n}\n\nconst pad = (n: number): string => String(n).padStart(3, \"0\");\nconst norm = (s: string): string => s.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n\nexport function assemble(records: IngestRecord[], opts: { title?: string } = {}): AssembleResult {\n const episodes: NameScript[\"episodes\"] = [];\n const notes: AssembleResult[\"notes\"] = [];\n let curEpisode: NameScript[\"episodes\"][number] | null = null;\n let curScene: NameScene | null = null;\n let epNo = 0;\n let scnNo = 0;\n const identityOccurrences = new Map<string, number>();\n const sourceIdentityKey = (kind: string, source: SourceSpan): string => {\n const base = `text:${kind}:${source.chunk}:${source.line_start}:${source.line_end}`;\n const occurrence = (identityOccurrences.get(base) ?? 0) + 1;\n identityOccurrences.set(base, occurrence);\n return `${base}:${occurrence}`;\n };\n\n const addActor = (scene: NameScene, ref: NameStateRef) => {\n const existing = scene.actors.find((a) => norm(a.name) === norm(ref.name));\n if (!existing) scene.actors.push(ref);\n else if (ref.state && !existing.state) existing.state = ref.state;\n };\n\n for (const rec of records) {\n switch (rec.kind) {\n case \"episode\": {\n epNo++;\n curEpisode = {\n identity_key: sourceIdentityKey(\"episode\", rec.source),\n episode_id: `ep_${pad(epNo)}`,\n scenes: [],\n };\n if (rec.title !== undefined) curEpisode.title = rec.title;\n episodes.push(curEpisode);\n curScene = null;\n break;\n }\n case \"scene\": {\n if (!curEpisode) {\n // A scene with no preceding episode header (stray outline scene, or a\n // screenplay that opens directly on a scene): auto-open episode 1 so\n // the content is kept and structured instead of crashing the ingest.\n epNo++;\n curEpisode = {\n identity_key: sourceIdentityKey(\"synthetic-episode\", rec.source),\n episode_id: `ep_${pad(epNo)}`,\n scenes: [],\n };\n episodes.push(curEpisode);\n }\n scnNo++;\n curScene = {\n identity_key: sourceIdentityKey(\"scene\", rec.source),\n scene_id: `scn_${pad(scnNo)}`,\n location: rec.location ? { ...rec.location } : null,\n actors: (rec.actors ?? []).map((a) => ({ ...a })),\n props: (rec.props ?? []).map((p) => ({ ...p })),\n actions: [],\n };\n if (rec.environment) curScene.environment = rec.environment;\n curEpisode.scenes.push(curScene);\n break;\n }\n case \"note\":\n notes.push({ content: rec.content, ...(rec.category ? { category: rec.category } : {}), source: rec.source });\n break;\n case \"action\":\n case \"transition\": {\n // Leading preamble (title block / \u7B56\u5212\u5927\u7EB2 / \u9879\u76EE\u4FE1\u606F before the first\n // scene) normalizes to body records with no scene to hang on. Keep it as\n // a note instead of aborting the whole ingest.\n if (!curScene) { notes.push({ content: rec.content, category: \"preamble\", source: rec.source }); break; }\n curScene.actions.push({\n identity_key: sourceIdentityKey(rec.kind, rec.source),\n type: rec.kind,\n content: rec.content,\n });\n break;\n }\n case \"dialogue\":\n case \"inner_thought\": {\n if (!curScene) { notes.push({ content: rec.content, category: \"preamble\", source: rec.source }); break; }\n const action: NameScene[\"actions\"][number] = {\n identity_key: sourceIdentityKey(rec.kind, rec.source),\n type: rec.kind,\n content: rec.content,\n speaker: rec.speaker,\n };\n if (rec.emotion !== undefined) action.emotion = rec.emotion;\n curScene.actions.push(action);\n // An actor speaker is present in the scene.\n if (\"name\" in rec.speaker) addActor(curScene, rec.speaker.state !== undefined ? { name: rec.speaker.name, state: rec.speaker.state } : { name: rec.speaker.name });\n break;\n }\n }\n }\n\n return { script: { title: opts.title ?? \"\", episodes }, notes };\n}\n\nclass Registry {\n private byNorm = new Map<string, ProvisionalAsset>();\n private order: ProvisionalAsset[] = [];\n constructor(private prefix: string, private kind: ProvisionalAsset[\"kind\"], private nextStateId: () => string) {}\n ensure(name: string, occ: ProvisionalOccurrence): ProvisionalAsset {\n const key = norm(name);\n let a = this.byNorm.get(key);\n if (!a) { a = { provisional_id: `${this.prefix}_${pad(this.order.length + 1)}`, kind: this.kind, names: [], states: [], occurrences: [] }; this.byNorm.set(key, a); this.order.push(a); }\n if (!a.names.includes(name)) a.names.push(name);\n a.occurrences.push(occ);\n return a;\n }\n stateId(a: ProvisionalAsset, state: string): string {\n const key = norm(state);\n const existing = a.states.find((s) => norm(s.name) === key);\n if (existing) return existing.id;\n const id = this.nextStateId();\n a.states.push({ name: state, id });\n return id;\n }\n list(): ProvisionalAsset[] { return this.order; }\n}\n\nfunction emitStates(a: ProvisionalAsset): Array<{ state_id: string; state_name: string; description: string }> {\n const out = [{ state_id: \"default\", state_name: \"default\", description: \"\" }];\n for (const s of a.states) out.push({ state_id: s.id, state_name: s.name, description: \"\" });\n return out;\n}\n\n// Deterministically assign provisional ids to a (possibly extract-augmented)\n// name-based script; returns the provisional v3 doc + evidence roster.\nexport function assignProvisionalIds(name: NameScript): {\n script: Record<string, unknown>;\n assets: ProvisionalAsset[];\n identityKeys: StructuralIdentityKeys;\n} {\n let stateSeq = 0;\n const nextStateId = (): string => `st_${pad(++stateSeq)}`; // globally unique across all assets\n const actors = new Registry(\"act\", \"actor\", nextStateId);\n const locations = new Registry(\"loc\", \"location\", nextStateId);\n const props = new Registry(\"prp\", \"prop\", nextStateId);\n const identityKeys: StructuralIdentityKeys = {\n episode: {},\n scene: {},\n action: {},\n };\n const seenIdentityKeys: Record<keyof StructuralIdentityKeys, Set<string>> = {\n episode: new Set(),\n scene: new Set(),\n action: new Set(),\n };\n const bindIdentity = (\n kind: keyof StructuralIdentityKeys,\n address: string,\n identityKey: string,\n ): void => {\n if (!identityKey || seenIdentityKeys[kind].has(identityKey)) {\n throw new Error(`Duplicate or missing ${kind} source identity: ${identityKey}`);\n }\n seenIdentityKeys[kind].add(identityKey);\n identityKeys[kind][address] = identityKey;\n };\n\n const idState = (reg: Registry, ref: NameStateRef, occ: ProvisionalOccurrence, idKey: string): Record<string, unknown> => {\n const a = reg.ensure(ref.name, occ);\n const out: Record<string, unknown> = { [idKey]: a.provisional_id };\n if (ref.state !== undefined) out.state_id = reg.stateId(a, ref.state);\n return out;\n };\n\n const episodes = name.episodes.map((ep, ei) => {\n bindIdentity(\"episode\", ep.episode_id, ep.identity_key);\n return {\n episode_id: ep.episode_id,\n ...(ep.title ? { title: ep.title } : {}),\n scenes: ep.scenes.map((sc, si) => {\n const sceneAddress = `${ep.episode_id}/${sc.scene_id}`;\n bindIdentity(\"scene\", sceneAddress, sc.identity_key);\n const occ: ProvisionalOccurrence = { episode: ei, scene: si };\n const location = sc.location ? idState(locations, sc.location, occ, \"location_id\") : null;\n const sceneActors = sc.actors.map((a) => idState(actors, a, occ, \"actor_id\"));\n const sceneProps = sc.props.map((p) => idState(props, p, occ, \"prop_id\"));\n const actions = sc.actions.map((ac, actionIndex) => {\n bindIdentity(\"action\", `${sceneAddress}#${actionIndex}`, ac.identity_key);\n const out: Record<string, unknown> = { type: ac.type, content: ac.content };\n if (ac.speaker) {\n if (\"name\" in ac.speaker) {\n const a = actors.ensure(ac.speaker.name, occ);\n const sp: Record<string, unknown> = { actor_id: a.provisional_id };\n if (ac.speaker.state !== undefined) sp.state_id = actors.stateId(a, ac.speaker.state);\n out.speaker = sp;\n } else {\n out.speaker = ac.speaker.label !== undefined\n ? { kind: ac.speaker.kind, label: ac.speaker.label }\n : { kind: ac.speaker.kind };\n }\n }\n if (ac.type === \"dialogue\" || ac.type === \"inner_thought\") {\n // The V3 bridge only has `emotion`; Script v4's parenthetical is\n // translated to that legacy field immediately before V4 conversion.\n if (ac.parenthetical !== undefined) out.emotion = ac.parenthetical;\n else if (ac.emotion !== undefined) out.emotion = ac.emotion;\n }\n // Carry through free-form extend (e.g. video timestamps) so it survives\n // into the final v3 product; text ingest never sets it.\n if (ac.extend !== undefined) out.extend = ac.extend;\n return out;\n });\n return {\n scene_id: sc.scene_id,\n ...(sc.environment ? { environment: sc.environment } : {}),\n location,\n actors: sceneActors,\n props: sceneProps,\n actions,\n };\n }),\n };\n });\n\n const mkAssets = (reg: Registry, idKey: string, nameKey: string) => reg.list().map((a) => ({ [idKey]: a.provisional_id, [nameKey]: a.names[0] ?? a.provisional_id, aliases: a.names.slice(1), description: \"\", states: emitStates(a) }));\n\n const script: Record<string, unknown> = {\n version: 3,\n title: name.title,\n worldview: \"\",\n style: \"\",\n actors: mkAssets(actors, \"actor_id\", \"actor_name\"),\n locations: mkAssets(locations, \"location_id\", \"location_name\"),\n props: mkAssets(props, \"prop_id\", \"prop_name\"),\n episodes,\n };\n return {\n script,\n assets: [...actors.list(), ...locations.list(), ...props.list()],\n identityKeys,\n };\n}\n", "// Deterministic source chunker (\u00A7pass1-prepare). Splits normalized (LF) source\n// text into contiguous, non-overlapping chunks under a char budget. Blank lines\n// stay with the preceding content, so paragraph boundaries are preserved when\n// they occur near a cut; line-oriented sources without blank separators fall\n// back to line boundaries. It does NOT interpret episode/scene structure \u2014 that\n// is pass2-normalize's job. Lines carry stable 0-based indices; a chunk's core\n// range is the half-open [core_line_start, core_line_end). A single overlong line\n// may exceed the budget because cuts never split a Unicode line.\n\nexport type Chunk = {\n index: number;\n core_line_start: number;\n core_line_end: number;\n text: string;\n};\n\nconst DEFAULT_MAX_CHARS = 500;\n\nexport function chunkSource(text: string, opts: { maxChars?: number } = {}): Chunk[] {\n const maxChars = opts.maxChars ?? DEFAULT_MAX_CHARS;\n const lines = text.split(\"\\n\");\n const chunks: Chunk[] = [];\n let start = 0;\n let acc = 0;\n\n const push = (end: number): boolean => {\n const chunkText = lines.slice(start, end).join(\"\\n\");\n if (chunkText.trim() === \"\") return false;\n chunks.push({\n index: chunks.length,\n core_line_start: start,\n core_line_end: end,\n text: chunkText,\n });\n start = end;\n acc = 0;\n return true;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n const separatorChars = i === start ? 0 : 1;\n const projected = acc + separatorChars + line.length;\n\n // Keep blank separators with the preceding content. Before the next\n // non-blank line crosses the budget, cut at its line boundary. If the source\n // has no blank lines this still bounds every chunk to roughly maxChars.\n if (line.trim() !== \"\" && i > start && projected > maxChars && push(i)) {\n acc = line.length;\n } else {\n acc = projected;\n }\n }\n push(lines.length);\n return chunks;\n}\n\n// ponytail: no context-only windows yet \u2014 normalize sees whole chunk text.\n// Add a prefix/suffix context band if cross-chunk pronoun resolution needs it.\n", "// Typed JSONL record shapes for the ingest pipeline (\u00A77). Records are name-based\n// and pre-canonicalization; Pass5 assigns final ids. Content is plain text (no\n// inline entity tags); scene-level cast/props are declared on the scene record\n// (from source `\u4EBA\u7269\uFF1A`/`\u9053\u5177\uFF1A` lines) and augmented by the extract pass.\n\nimport {\n NON_ACTOR_SPEAKER_KINDS,\n type NonActorSpeakerKind,\n} from \"../script/shared/types.js\";\n\nexport type SourceSpan = { chunk: number; line_start: number; line_end: number };\n\n// A name-based entity reference with an optional (declared) state description.\nexport type NameStateRef = { name: string; state?: string };\n\nexport type SpeakerRef =\n | { name: string; state?: string }\n | { kind: NonActorSpeakerKind; label?: string };\n\n// Non-actor speaker kinds. Bit-part characters (\u9F99\u5957) are still actors (tagged\n// importance=background), so they speak via actor_id \u2014 no special speaker kind.\nexport { NON_ACTOR_SPEAKER_KINDS };\n\nexport type EpisodeRecord = { kind: \"episode\"; episode: number; title?: string; source: SourceSpan };\nexport type SceneRecord = {\n kind: \"scene\";\n scene?: number;\n environment?: { space?: string; time?: string };\n location?: { name: string; state?: string };\n actors?: NameStateRef[]; // declared cast (\u6E90\u300E\u4EBA\u7269\uFF1A\u540D\u3010\u72B6\u6001\u3011\u300F)\n props?: NameStateRef[]; // declared props (\u6E90\u300E\u9053\u5177\uFF1A\u300F)\n source: SourceSpan;\n};\nexport type ActionRecord = { kind: \"action\"; content: string; source: SourceSpan };\nexport type DialogueRecord = { kind: \"dialogue\"; speaker: SpeakerRef; content: string; emotion?: string; source: SourceSpan };\nexport type InnerThoughtRecord = { kind: \"inner_thought\"; speaker: SpeakerRef; content: string; emotion?: string; source: SourceSpan };\nexport type TransitionRecord = { kind: \"transition\"; content: string; source: SourceSpan };\nexport type NoteRecord = { kind: \"note\"; content: string; category?: \"author_note\" | \"format_note\" | \"unclassified\"; source: SourceSpan };\n\nexport type IngestRecord =\n | EpisodeRecord\n | SceneRecord\n | ActionRecord\n | DialogueRecord\n | InnerThoughtRecord\n | TransitionRecord\n | NoteRecord;\n\nexport const RECORD_KINDS = [\"episode\", \"scene\", \"action\", \"dialogue\", \"inner_thought\", \"transition\", \"note\"] as const;\nexport type RecordKind = (typeof RECORD_KINDS)[number];\n", "export { SCENE_TIME_VALUES, isSceneTime, type SceneTime } from \"@lingjingai/screenplay/schema\";\n\nimport { SCENE_TIME_VALUES, type SceneTime } from \"@lingjingai/screenplay/schema\";\n\nconst TIME_ALIASES: Readonly<Record<string, SceneTime>> = {\n day: \"day\",\n \"\u65E5\": \"day\",\n \"\u767D\u5929\": \"day\",\n \"\u65E5\u95F4\": \"day\",\n \"\u663C\": \"day\",\n \"\u663C\u95F4\": \"day\",\n night: \"night\",\n \"\u591C\": \"night\",\n \"\u591C\u665A\": \"night\",\n \"\u591C\u95F4\": \"night\",\n \"\u665A\": \"night\",\n dawn: \"dawn\",\n \"\u6668\": \"dawn\",\n \"\u6E05\u6668\": \"dawn\",\n \"\u65E9\u6668\": \"dawn\",\n \"\u9ECE\u660E\": \"dawn\",\n \"\u62C2\u6653\": \"dawn\",\n dusk: \"dusk\",\n \"\u660F\": \"dusk\",\n \"\u9EC4\u660F\": \"dusk\",\n \"\u508D\u665A\": \"dusk\",\n \"\u65E5\u843D\": \"dusk\",\n};\n\nexport function normalizeSceneTime(value: unknown): SceneTime | undefined {\n if (typeof value !== \"string\") return undefined;\n const normalized = value.normalize(\"NFC\").replace(/\\s+/g, \"\").trim().toLocaleLowerCase();\n return TIME_ALIASES[normalized];\n}\n\n\n", "// Strict JSONL \u2192 typed record parser (\u00A77). Rejects unknown fields, malformed\n// records, missing/invalid source spans, and inline-tag syntax errors. Never\n// repairs or downgrades: a bad line fails the batch (\u00A712.3).\n\nimport {\n type IngestRecord,\n type NameStateRef,\n type SourceSpan,\n type SpeakerRef,\n NON_ACTOR_SPEAKER_KINDS,\n RECORD_KINDS,\n} from \"./records.js\";\nimport { normalizeSceneTime } from \"./environment.js\";\n\nexport class JsonlParseError extends Error {\n constructor(message: string, readonly line: number) {\n super(`line ${line}: ${message}`);\n }\n}\n\ntype Obj = Record<string, unknown>;\n\nfunction isObj(v: unknown): v is Obj {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction requireKeys(obj: Obj, allowed: string[], line: number): void {\n for (const key of Object.keys(obj)) {\n if (!allowed.includes(key)) throw new JsonlParseError(`unknown field '${key}'`, line);\n }\n}\n\nfunction parseSource(v: unknown, line: number): SourceSpan {\n if (!isObj(v)) throw new JsonlParseError(\"missing source\", line);\n requireKeys(v, [\"chunk\", \"line_start\", \"line_end\"], line);\n const { chunk, line_start, line_end } = v;\n if (![chunk, line_start, line_end].every((n) => typeof n === \"number\" && Number.isInteger(n) && n >= 0)) {\n throw new JsonlParseError(\"source needs integer chunk/line_start/line_end\", line);\n }\n if ((line_start as number) >= (line_end as number)) throw new JsonlParseError(\"source line_start must be < line_end\", line);\n return { chunk: chunk as number, line_start: line_start as number, line_end: line_end as number };\n}\n\nfunction str(obj: Obj, key: string, line: number): string {\n const v = obj[key];\n if (typeof v !== \"string\" || v === \"\") throw new JsonlParseError(`'${key}' must be a non-empty string`, line);\n return v;\n}\n\nfunction optStr(obj: Obj, key: string, line: number): string | undefined {\n if (!(key in obj) || obj[key] === undefined) return undefined;\n const v = obj[key];\n if (typeof v !== \"string\" || v === \"\") throw new JsonlParseError(`'${key}' must be a non-empty string`, line);\n return v;\n}\n\nfunction parseEntityRefs(v: unknown, key: string, line: number): NameStateRef[] {\n if (!Array.isArray(v)) throw new JsonlParseError(`'${key}' must be an array`, line);\n return v.map((item) => {\n if (!isObj(item)) throw new JsonlParseError(`'${key}' entries must be objects`, line);\n requireKeys(item, [\"name\", \"state\"], line);\n const ref: NameStateRef = { name: str(item, \"name\", line) };\n const state = optStr(item, \"state\", line);\n if (state !== undefined) ref.state = state;\n return ref;\n });\n}\n\nfunction parseSpeaker(v: unknown, line: number): SpeakerRef {\n if (!isObj(v)) throw new JsonlParseError(\"dialogue/inner_thought needs a speaker\", line);\n if (\"kind\" in v) {\n requireKeys(v, [\"kind\", \"label\"], line);\n const kind = v.kind;\n if (typeof kind !== \"string\" || !(NON_ACTOR_SPEAKER_KINDS as readonly string[]).includes(kind)) {\n throw new JsonlParseError(`speaker.kind must be one of ${NON_ACTOR_SPEAKER_KINDS.join(\"|\")}`, line);\n }\n const ref: SpeakerRef = { kind: kind as (typeof NON_ACTOR_SPEAKER_KINDS)[number] };\n const label = optStr(v, \"label\", line);\n if (label !== undefined) ref.label = label;\n return ref;\n }\n requireKeys(v, [\"name\", \"state\"], line);\n const name = str(v, \"name\", line);\n if (!/[\\p{L}\\p{N}]/u.test(name)) {\n throw new JsonlParseError(\"speaker.name must contain a letter or number\", line);\n }\n const ref: SpeakerRef = { name };\n const state = optStr(v, \"state\", line);\n if (state !== undefined) ref.state = state;\n return ref;\n}\n\nfunction parseRecord(obj: Obj, line: number): IngestRecord {\n const kind = obj.kind;\n if (typeof kind !== \"string\" || !(RECORD_KINDS as readonly string[]).includes(kind)) {\n throw new JsonlParseError(`unknown or missing kind '${String(kind)}'`, line);\n }\n const source = parseSource(obj.source, line);\n\n switch (kind) {\n case \"episode\": {\n requireKeys(obj, [\"kind\", \"episode\", \"title\", \"source\"], line);\n const episode = obj.episode;\n if (typeof episode !== \"number\" || !Number.isInteger(episode)) throw new JsonlParseError(\"episode must be an integer\", line);\n const rec = { kind, episode, source } as IngestRecord;\n const title = optStr(obj, \"title\", line);\n if (title !== undefined) (rec as { title?: string }).title = title;\n return rec;\n }\n case \"scene\": {\n requireKeys(obj, [\"kind\", \"scene\", \"environment\", \"location\", \"actors\", \"props\", \"source\"], line);\n const rec: Record<string, unknown> = { kind, source };\n if (\"scene\" in obj && obj.scene !== undefined) {\n if (typeof obj.scene !== \"number\" || !Number.isInteger(obj.scene)) throw new JsonlParseError(\"scene must be an integer\", line);\n rec.scene = obj.scene;\n }\n if (\"environment\" in obj && obj.environment !== undefined) {\n if (!isObj(obj.environment)) throw new JsonlParseError(\"environment must be an object\", line);\n requireKeys(obj.environment, [\"space\", \"time\"], line);\n const environment: { space?: string; time?: string } = {};\n const space = optStr(obj.environment, \"space\", line);\n if (space !== undefined) environment.space = space;\n const rawTime = optStr(obj.environment, \"time\", line);\n if (rawTime !== undefined) {\n const time = normalizeSceneTime(rawTime);\n if (!time) {\n throw new JsonlParseError(\n \"environment.time must be day|night|dawn|dusk or a recognized Chinese equivalent\",\n line,\n );\n }\n environment.time = time;\n }\n rec.environment = environment;\n }\n if (\"location\" in obj && obj.location !== undefined) {\n if (!isObj(obj.location)) throw new JsonlParseError(\"location must be an object\", line);\n requireKeys(obj.location, [\"name\", \"state\"], line);\n const loc: Record<string, unknown> = { name: str(obj.location, \"name\", line) };\n const st = optStr(obj.location, \"state\", line);\n if (st !== undefined) loc.state = st;\n rec.location = loc;\n }\n if (\"actors\" in obj && obj.actors !== undefined) rec.actors = parseEntityRefs(obj.actors, \"actors\", line);\n if (\"props\" in obj && obj.props !== undefined) rec.props = parseEntityRefs(obj.props, \"props\", line);\n return rec as unknown as IngestRecord;\n }\n case \"action\":\n case \"transition\": {\n requireKeys(obj, [\"kind\", \"content\", \"source\"], line);\n const content = str(obj, \"content\", line);\n return { kind, content, source } as IngestRecord;\n }\n case \"dialogue\":\n case \"inner_thought\": {\n requireKeys(obj, [\"kind\", \"speaker\", \"content\", \"emotion\", \"source\"], line);\n const content = str(obj, \"content\", line);\n const speaker = parseSpeaker(obj.speaker, line);\n const rec: Record<string, unknown> = { kind, speaker, content, source };\n const emotion = optStr(obj, \"emotion\", line);\n if (emotion !== undefined) rec.emotion = emotion;\n return rec as unknown as IngestRecord;\n }\n case \"note\": {\n requireKeys(obj, [\"kind\", \"content\", \"category\", \"source\"], line);\n const content = str(obj, \"content\", line);\n const rec: Record<string, unknown> = { kind, content, source };\n if (\"category\" in obj && obj.category !== undefined) {\n const cat = obj.category;\n if (cat !== \"author_note\" && cat !== \"format_note\" && cat !== \"unclassified\") {\n throw new JsonlParseError(\"note.category must be author_note|format_note|unclassified\", line);\n }\n rec.category = cat;\n }\n return rec as unknown as IngestRecord;\n }\n default:\n throw new JsonlParseError(`unhandled kind '${kind}'`, line);\n }\n}\n\n// Parse full JSONL text. Blank lines are skipped; every other line must be a\n// valid record. `lineOffset` lets callers report absolute file lines.\nexport function parseJsonl(text: string, lineOffset = 0): IngestRecord[] {\n const out: IngestRecord[] = [];\n const lines = text.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!.trim();\n if (raw === \"\") continue;\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new JsonlParseError(\"invalid JSON\", i + 1 + lineOffset);\n }\n if (!isObj(parsed)) throw new JsonlParseError(\"record must be a JSON object\", i + 1 + lineOffset);\n out.push(parseRecord(parsed, i + 1 + lineOffset));\n }\n return out;\n}\n", "// Serial-govern running context (\u00A7 serial), built INCREMENTALLY. The front gives\n// only the body (scenes + dialogue/action, speakers by name); it does NOT feed any\n// pre-extracted assets/states. This module maintains a registry that starts EMPTY\n// and grows episode by episode: the model, reading one episode's body plus the\n// context-so-far, discovers entities (with \u9020\u578B/looks + descriptions),\n// merges identities, and states \u2014 per scene \u2014 who is present and in which \u9020\u578B.\n//\n// Nothing here is seeded from the jsonl roster. render() shows only what has been\n// discovered up to now (so episode 1 is small). The persistent core (entities +\n// looks + per-scene refs) never compacts; the plot narrative (recent \u2192 synopsis \u2192\n// arc) ages down a ladder to stay within budget. The final v3 assets/scene-refs\n// are built from THIS registry, not the roster.\n\nconst norm = (s: string): string => s.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n// Strip an inline paren annotation from a name \u2014 `\u5927\u725B(BigBull)` \u2192 `\u5927\u725B`. The\n// serial tool output is cleaned in toDelta, but names coming from the assembled\n// BODY (scene cast, dialogue speakers written by normalize) still carry the source\n// `\u4E2D\u6587\uFF08English\uFF09` dual-naming. resolveCanon runs those through this so a polluted\n// speaker resolves against the clean registry (and, if unmatched, still ships\n// clean). A leading paren (no name before it) is left whole.\nconst stripParen = (s: string): string => {\n const m = /[\uFF08(]/.exec(s);\n if (!m || m.index === 0) return s;\n return s.slice(0, m.index).trim();\n};\n\n// One \u9020\u578B (durable look): a canonical name, equivalent aliases (\u5A5A\u670D=\u5927\u7EA2\u5AC1\u8863), and\n// a visual description for image generation.\nexport interface Look { name: string; aliases: string[]; description: string }\nexport interface DefaultLook { name: string; description: string }\n\n// A registry entity, name-keyed (no provisional id \u2014 ids are minted at build time\n// by assignProvisionalIds). Discovered incrementally by the serial pass.\nexport interface RegEntity {\n kind: \"actor\" | \"location\" | \"prop\";\n canonical: string;\n aliases: string[];\n description: string;\n looks: Look[];\n currentLook?: string; // canonical look name currently in effect (continuity)\n lastSeen: number; // last episode this entity was referenced (for render detail gating)\n}\n\n// A \u9020\u578B change the serial pass reports: from this scene on, `entity` (canonical)\n// wears look `look` (a registered look\u6863\u4F4D). Sparse \u2014 only where a look CHANGES;\n// finalize carries it forward until the next change. Presence/cast are NOT taken\n// from the model \u2014 they come from the (name-corrected) body itself.\nexport interface LookChange { entity: string; look: string }\n\n// A processed serial STEP \u2014 one window of 1+ contiguous episodes [startEp, endEp]\n// parsed together in a single call. startEp === endEp when a window held one episode.\nexport interface RecentEpisode { startEp: number; endEp: number; summary: string; subEvents: string[] }\nexport const recentLabel = (r: { startEp: number; endEp: number }): string =>\n r.startEp === r.endEp ? `\u7B2C${r.startEp}\u96C6` : `\u7B2C${r.startEp}\u96C6\u2013\u7B2C${r.endEp}\u96C6`;\n// One synopsis entry: a single aged-out episode (startEp === endEp) or an arc\n// covering a contiguous range [startEp, endEp]. The range is tracked as numbers\n// (not a concatenated label string) so re-folding yields a clean \u7B2CX\u96C6\u2013\u7B2CY\u96C6\n// instead of the old compounding \u7B2C1\u96C6\u2013\u7B2C10\u96C6\u2013\u7B2C19\u96C6\u2026 artifact.\nexport interface SynopsisLine { startEp: number; endEp: number; line: string }\n\nexport const synopsisLabel = (s: SynopsisLine): string =>\n s.startEp === s.endEp ? `\u7B2C${s.startEp}\u96C6` : `\u7B2C${s.startEp}\u96C6\u2013\u7B2C${s.endEp}\u96C6`;\n\nexport interface GlobalContext {\n entities: RegEntity[];\n lookChanges: Record<string, LookChange[]>; // scene_id \u2192 look changes at that scene (ordered)\n recent: RecentEpisode[];\n synopsis: SynopsisLine[];\n}\n\n// Per-window decisions the model emits. Identity work is split into two distinct\n// acts (merging two entities is deliberate, not a side effect of listing aliases):\n// newEntities \u2014 declare a NEW entity with its canonical name + EVERY \u53EB\u6CD5 seen\n// this window (aliases: translations, short/full names, past-life names, and\n// crucially the dialogue-speaker spellings \u2014 so body speakers resolve by alias\n// with no ghost asset). Re-declaring a known entity just tops up its aliases.\n// merges \u2014 a body \u79F0\u547C that is NOT yet registered is an alias of a known entity.\n// applyDelta is CONSERVATIVE: neither act ever folds two already-registered\n// entities. A name that belongs to another entity is skipped, never absorbed \u2014\n// wrongly merging two real characters is irreversible, a missed merge is a cheap\n// manual fix.\nexport interface Delta {\n newEntities: Array<{\n name: string;\n kind: RegEntity[\"kind\"];\n description: string;\n aliases: string[];\n defaultLook: DefaultLook;\n }>;\n merges: Array<{ from: string; into: string }>;\n looks: Array<{ entity: string; names: string[]; description: string }>; // names[0]=canonical\n lookChanges: Array<{ scene: string; entity: string; look: string }>; // sparse \u9020\u578B changes\n subEvents: string[];\n summary: string;\n}\n\nexport const emptyDelta = (): Delta => ({ newEntities: [], merges: [], looks: [], lookChanges: [], subEvents: [], summary: \"\" });\nexport const emptyContext = (): GlobalContext => ({ entities: [], lookChanges: {}, recent: [], synopsis: [] });\n\nexport interface CompactOpts { recentEpisodes: number; synopsisChars: number; arcFold: number }\nexport const DEFAULT_COMPACT: CompactOpts = { recentEpisodes: 6, synopsisChars: 3500, arcFold: 10 };\n\n// Serial windowing: pack contiguous episode bodies up to this token budget and\n// parse them in ONE call. Context still flows window\u2192window (serial), so a window\n// only trades a little within-window pre-applied context for far fewer calls \u2014\n// the win is biggest late, where one big context is amortized over several episodes.\nexport const DEFAULT_WINDOW_TOKENS = 10000;\n\n// Deterministic token estimate for CJK+latin mixed body text. Not a real\n// tokenizer (grok/deepseek differ), but stable across runs so window boundaries \u2014\n// hence resume cache keys \u2014 are identical. CJK \u2248 0.7 tok/char, latin \u2248 0.25.\nexport function estimateTokens(text: string): number {\n let cjk = 0, total = 0;\n for (const ch of text) {\n total++;\n const c = ch.codePointAt(0)!;\n if ((c >= 0x3400 && c <= 0x9fff) || (c >= 0x3000 && c <= 0x30ff) || (c >= 0xff00 && c <= 0xffef) || (c >= 0xf900 && c <= 0xfaff)) cjk++;\n }\n return Math.round(cjk * 0.7 + (total - cjk) * 0.25);\n}\n\n// Greedy-pack episode token sizes into windows under `budget`. Episodes are atomic\n// (cut only on episode boundaries); a single episode larger than the budget takes\n// its own window. Returns inclusive 1-based [startEp, endEp] ranges. Pure +\n// deterministic so resume re-packs identically.\nexport function packEpisodes(tokens: number[], budget: number = DEFAULT_WINDOW_TOKENS): Array<[number, number]> {\n const windows: Array<[number, number]> = [];\n let start = 0, acc = 0;\n for (let i = 0; i < tokens.length; i++) {\n if (i > start && acc + tokens[i]! > budget) { windows.push([start + 1, i]); start = i; acc = 0; }\n acc += tokens[i]!;\n }\n if (start < tokens.length) windows.push([start + 1, tokens.length]);\n return windows;\n}\n\nconst KIND_LABEL: Record<RegEntity[\"kind\"], string> = { actor: \"\u4EBA\u7269\", location: \"\u573A\u666F\", prop: \"\u9053\u5177\" };\nconst LABEL_KIND: Record<string, RegEntity[\"kind\"]> = { \u4EBA\u7269: \"actor\", \u573A\u666F: \"location\", \u5730\u70B9: \"location\", \u9053\u5177: \"prop\" };\nexport const kindFromLabel = (s: string): RegEntity[\"kind\"] | undefined => LABEL_KIND[s.trim()];\n\nexport function findEntity(ctx: GlobalContext, name: string): RegEntity | undefined {\n const key = norm(name);\n return ctx.entities.find((e) => norm(e.canonical) === key || e.aliases.some((a) => norm(a) === key));\n}\n\nconst addAlias = (e: RegEntity, name: string): void => {\n if (norm(name) !== norm(e.canonical) && !e.aliases.some((a) => norm(a) === norm(name))) e.aliases.push(name);\n};\n\n// Age/size modifier prefixes that a proper name would not carry \u2014 a name whose\n// only extra over a shorter one is such a modifier is NOT \"fuller\" (\u5E74\u8F7B\u82CF\u8FDC\u6865 is\n// not fuller than \u82CF\u8FDC\u6865; \u82CF\u82E5\u96EA IS fuller than \u82E5\u96EA because \u82CF is a surname).\nconst MODIFIERS = [\"\u5E74\u8F7B\", \"\u5E74\u8001\", \"\u5E74\u5E7C\", \"\u5E74\u5C11\", \"\u4E2D\u5E74\", \"\u9752\u5E74\", \"\u5C11\u5E74\", \"\u8001\u5E74\", \"\u5E7C\u5E74\", \"\u8001\", \"\u5C0F\", \"\u5927\", \"\u5C11\", \"\u5E7C\"];\n\n// n properly extends m if it contains m and the leftover part is a real name\n// fragment (a surname), not just a modifier.\nfunction properlyExtends(n: string, m: string): boolean {\n const N = norm(n), M = norm(m);\n if (N === M || !N.includes(M)) return false;\n const extra = N.replace(M, \"\").trim();\n return extra.length > 0 && !MODIFIERS.some((mod) => extra === mod || extra.startsWith(mod));\n}\n\n// The \"fullest\" name in a set = the longest one that PROPERLY extends another\n// (surname prefix, not a modifier). If none does, keep the first (current\n// canonical) \u2014 avoids promoting a modified or unrelated long name.\nexport function fullest(names: string[]): string {\n const supers = names.filter((n) => names.some((m) => m !== n && properlyExtends(n, m)));\n return supers.length ? supers.reduce((a, b) => (b.length > a.length ? b : a)) : names[0]!;\n}\n\n// Crowd / collective names (\u540C\u5B66\u4EEC, \u4F17\u4EBA, \u4E2B\u9B1F\u4EEC, \u6751\u6C11, \u8F7F\u592B4\u540D) are NOT single\n// characters \u2014 nobody draws a portrait of \"\u540C\u5B66\u4EEC\". Such a name must never become an\n// actor asset; its lines belong to a `group` speaker instead. Signal: ends with \u4EEC,\n// is a bare crowd noun, has an explicit group qualifier/count, or ends in an\n// inherently collective noun such as \u7FA4\u4F17/\u89C2\u4F17. A trailing count (\u8F7F\u592B4\u540D \u2192 \u8F7F\u592B)\n// is stripped first. Specific individual roles such as \u4F20\u65E8\u592A\u76D1 remain actors.\nconst CROWD_WORDS = [\n \"\u4F17\u4EBA\", \"\u7FA4\u4F17\", \"\u6C11\u4F17\", \"\u89C2\u4F17\", \"\u4EBA\u7FA4\", \"\u4EBA\u4EEC\", \"\u5927\u5BB6\", \"\u8DEF\u4EBA\", \"\u884C\u4EBA\", \"\u770B\u5BA2\", \"\u56F4\u89C2\u8005\",\n \"\u6751\u6C11\", \"\u58EB\u5175\", \"\u767E\u59D3\", \"\u5B66\u751F\", \"\u540C\u5B66\", \"\u4E2B\u9B1F\", \"\u968F\u4ECE\", \"\u4F8D\u536B\", \"\u5BB6\u4E01\", \"\u4EC6\u4EBA\", \"\u4E0B\u4EBA\", \"\u5B69\u5B50\",\n \"\u8F7F\u592B\", \"\u62A4\u536B\", \"\u624B\u4E0B\", \"\u5C0F\u5F1F\", \"\u55BD\u5570\", \"\u5B98\u5175\", \"\u8859\u5F79\", \"\u592A\u76D1\", \"\u5BAB\u5973\", \"\u5A62\u5973\", \"\u5546\u8D29\", \"\u98DF\u5BA2\",\n];\nconst COLLECTIVE_SUFFIXES = [\"\u4F17\u4EBA\", \"\u7FA4\u4F17\", \"\u6C11\u4F17\", \"\u89C2\u4F17\", \"\u4EBA\u7FA4\", \"\u4EBA\u4EEC\", \"\u5927\u5BB6\", \"\u767E\u59D3\", \"\u5B98\u5175\"];\nconst GROUP_QUALIFIER = /^(?:\u4E00\u7FA4|\u4E00\u4F17|\u5168\u4F53|\u6240\u6709|\u51E0\u540D|\u6570\u540D|\u591A\u540D|[0-9\u96F6\u4E00\u4E8C\u4E24\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343]+\u540D?)/;\nexport function isCrowdName(name: string): boolean {\n const n = norm(name).replace(/[0-9\u96F6\u4E00\u4E8C\u4E24\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343]+\u540D?$/, \"\").trim();\n if (!n) return false;\n if (n.endsWith(\"\u4EEC\")) return true;\n if (CROWD_WORDS.includes(n)) return true;\n if (COLLECTIVE_SUFFIXES.some((word) => n.endsWith(word))) return true;\n return GROUP_QUALIFIER.test(n) && CROWD_WORDS.some((word) => n.endsWith(word));\n}\n\n// Canonical name for any name/alias (post-upsert), else the (paren-stripped) name.\n// Body-sourced names (dialogue speakers, scene cast) resolve here \u2014 since the model\n// declares every \u53EB\u6CD5 (incl. speaker spellings) as an entity alias, findEntity picks\n// them up; an unmatched name is the model having missed an alias, and ships clean.\nexport function resolveCanon(ctx: GlobalContext, name: string): string {\n const clean = stripParen(name);\n return findEntity(ctx, clean)?.canonical ?? clean;\n}\n\n// Canonical look name for a look name/alias on an entity, else the name unchanged.\nexport function resolveLook(e: RegEntity, name: string): string {\n const key = norm(name);\n return e.looks.find((l) => norm(l.name) === key || l.aliases.some((a) => norm(a) === key))?.name ?? name;\n}\n\n// The entity's baseline \"\u5E38\u6001\" look name (everyday appearance) \u2014 the explicitly\n// labelled one if present, else the first look reported. Scenes with no specific\n// look fall back to this, so an ordinary scene never inherits a dramatic outfit.\nconst BASE_LABELS = [\"\u5E38\u6001\", \"\u65E5\u5E38\", \"\u5E73\u65F6\", \"\u57FA\u7840\", \"\u666E\u901A\"];\nexport function baseLook(e: RegEntity): string | undefined {\n if (e.looks.length === 0) return undefined;\n return (e.looks.find((l) => BASE_LABELS.some((b) => l.name.includes(b))) ?? e.looks[0]!).name;\n}\n\n// The registered entity (within kind) that a name belongs to, else undefined.\n// exclude lets a caller ignore the entity it's currently updating.\nfunction ownerOf(ctx: GlobalContext, kind: RegEntity[\"kind\"], name: string, exclude?: RegEntity): RegEntity | undefined {\n const k = norm(stripParen(name));\n if (!k) return undefined;\n return ctx.entities.find((e) => e.kind === kind && e !== exclude && (norm(e.canonical) === k || e.aliases.some((a) => norm(a) === k)));\n}\n\n// Promote the fullest name (a superstring of another in the set) to canonical, so\n// \u82CF\u82E5\u96EA wins over \u82E5\u96EA, \u987E\u591C\u6E0A over \u591C\u6E0A.\nfunction promoteCanonical(e: RegEntity): void {\n const all = [e.canonical, ...e.aliases];\n const best = fullest(all);\n if (norm(best) !== norm(e.canonical)) { e.canonical = best; e.aliases = all.filter((n) => norm(n) !== norm(best)); }\n}\n\nexport function applyDelta(ctx: GlobalContext, delta: Delta, startEp: number, endEp: number = startEp): GlobalContext {\n // newEntities: declare/refresh an entity. An alias that already belongs to a\n // DIFFERENT entity is a cross-entity slip \u2192 skipped (never absorb another\n // character). Re-declaring a known name just tops up its aliases/description.\n for (const ne of delta.newEntities) {\n const canon = stripParen(ne.name);\n if (!canon) continue;\n const dst = ownerOf(ctx, ne.kind, canon);\n if (!dst) {\n const aliases: string[] = [];\n for (const a of ne.aliases) { const n = stripParen(a); if (n && norm(n) !== norm(canon) && !ownerOf(ctx, ne.kind, n)) aliases.push(n); }\n ctx.entities.push({\n kind: ne.kind,\n canonical: canon,\n aliases: [...new Set(aliases)],\n description: ne.description,\n looks: [{ name: ne.defaultLook.name, aliases: [], description: ne.defaultLook.description }],\n lastSeen: endEp,\n });\n continue;\n }\n for (const a of ne.aliases) { const n = stripParen(a); if (n && !ownerOf(ctx, ne.kind, n, dst)) addAlias(dst, n); }\n if (!dst.description && ne.description) dst.description = ne.description;\n const registeredDefault = dst.looks.find((look) => norm(look.name) === norm(ne.defaultLook.name));\n if (registeredDefault) registeredDefault.description = ne.defaultLook.description;\n else dst.looks.unshift({ name: ne.defaultLook.name, aliases: [], description: ne.defaultLook.description });\n promoteCanonical(dst);\n }\n\n // merges: a body \u79F0\u547C (`from`) that is NOT yet registered is an alias of `into`.\n // CONSERVATIVE: if `from` is already its own registered entity, skip \u2014 never fold\n // two registered characters (wrong merge is irreversible; a missed one is cheap).\n for (const { from, into } of delta.merges) {\n const intoCanon = stripParen(into);\n if (!intoCanon) continue;\n const dst = findEntity(ctx, intoCanon);\n if (!dst) continue;\n const f = stripParen(from);\n if (!f || norm(f) === norm(dst.canonical)) continue;\n if (findEntity(ctx, f)) continue; // `from` is a registered entity \u2192 don't fold\n addAlias(dst, f);\n promoteCanonical(dst);\n }\n\n for (const { entity, names: raw, description } of delta.looks) {\n const e = findEntity(ctx, entity);\n if (!e) continue;\n const names = raw.map((n) => n.trim()).filter(Boolean);\n if (!names.length) continue;\n const canonical = names[0]!;\n const existing = e.looks.find((l) => norm(l.name) === norm(canonical) || names.some((n) => l.aliases.some((a) => norm(a) === norm(n))));\n if (existing) {\n if (description) existing.description = description;\n for (const n of names) {\n if (norm(n) !== norm(existing.name) && !existing.aliases.some((a) => norm(a) === norm(n))) existing.aliases.push(n);\n }\n }\n else e.looks.push({ name: canonical, aliases: names.slice(1), description });\n }\n\n // Sparse \u9020\u578B changes \u2192 accumulate per scene; entity resolved to canonical. Also\n // stamp currentLook so the render gives the model each entity's latest \u9020\u578B.\n for (const lc of delta.lookChanges) {\n const scene = lc.scene.trim();\n const entity = resolveCanon(ctx, lc.entity);\n const rawLook = lc.look.trim();\n if (!scene || !entity || !rawLook) continue;\n const registered = findEntity(ctx, entity);\n const look = registered ? resolveLook(registered, rawLook) : rawLook;\n (ctx.lookChanges[scene] ??= []).push({ entity, look });\n if (registered) registered.currentLook = look;\n }\n\n // Mark every entity referenced this episode as freshly seen (drives render\n // detail gating: recent entities render in full, dormant ones fold to one line).\n const touched = new Set<string>();\n for (const ne of delta.newEntities) { touched.add(ne.name); for (const a of ne.aliases) touched.add(a); }\n for (const mg of delta.merges) { touched.add(mg.from); touched.add(mg.into); }\n for (const l of delta.looks) touched.add(l.entity);\n for (const lc of delta.lookChanges) touched.add(lc.entity);\n for (const n of touched) { const e = findEntity(ctx, n); if (e) e.lastSeen = endEp; }\n\n ctx.recent.push({ startEp, endEp, summary: delta.summary, subEvents: delta.subEvents });\n return ctx;\n}\n\nconst recentChars = (r: RecentEpisode): number => r.summary.length + r.subEvents.reduce((n, s) => n + s.length, 0);\n\n// Age recent \u2192 synopsis one-liners (pure). Arc folding of the synopsis is a\n// SEPARATE async step (pendingArcFold + applyArcFold) because it summarizes via\n// LLM; keeping compact pure lets resume replay it deterministically.\nexport function compact(ctx: GlobalContext, opts: CompactOpts = DEFAULT_COMPACT): GlobalContext {\n while (ctx.recent.length > opts.recentEpisodes || (ctx.recent.length > 1 && ctx.recent.reduce((n, r) => n + recentChars(r), 0) > 6000)) {\n const oldest = ctx.recent.shift()!;\n if (oldest.summary.trim()) ctx.synopsis.push({ startEp: oldest.startEp, endEp: oldest.endEp, line: oldest.summary.trim() });\n }\n return ctx;\n}\n\n// The oldest `arcFold` synopsis entries to compress, if the synopsis is over its\n// char budget; else null. Pure + deterministic, so the fold boundary \u2014 and thus\n// the arc summary's cache key [startEp, endEp] \u2014 is identical across runs/resumes.\nexport function pendingArcFold(ctx: GlobalContext, opts: CompactOpts = DEFAULT_COMPACT): SynopsisLine[] | null {\n const total = ctx.synopsis.reduce((n, s) => n + s.line.length, 0);\n if (total <= opts.synopsisChars || ctx.synopsis.length <= opts.arcFold) return null;\n return ctx.synopsis.slice(0, opts.arcFold);\n}\n\n// Replace the oldest `arcFold` synopsis entries with one arc entry carrying the\n// (LLM-produced) summary and the folded range's clean [startEp, endEp].\nexport function applyArcFold(ctx: GlobalContext, summary: string, opts: CompactOpts = DEFAULT_COMPACT): void {\n const fold = ctx.synopsis.splice(0, opts.arcFold);\n if (!fold.length) return;\n ctx.synopsis.unshift({ startEp: fold[0]!.startEp, endEp: fold[fold.length - 1]!.endEp, line: summary.trim() });\n}\n\n// Episodes of recency within which an entity renders in FULL detail; older\n// (dormant) entities fold to a one-line stub so input doesn't grow with cast.\nexport const DETAIL_EPISODES = 6;\n\n// Render the discovered-so-far context as md \u2014 BOTH the prompt and the per-step\n// trace. Empty at episode 1. When `currentEpisode` is given, only entities seen\n// within DETAIL_EPISODES render in full (\u7B80\u4ECB + \u9020\u578B + \u63CF\u8FF0); dormant ones fold to a\n// one-line stub (name + aliases + current look) so identity is still recognizable\n// on their return without bloating the input.\nexport function render(ctx: GlobalContext, currentEpisode?: number): string {\n const detailed = (e: RegEntity): boolean => currentEpisode === undefined || e.lastSeen >= currentEpisode - DETAIL_EPISODES;\n const out: string[] = [\"# \u8BBE\u5B9A\"];\n for (const kind of [\"actor\", \"location\", \"prop\"] as const) {\n const list = ctx.entities.filter((e) => e.kind === kind);\n if (!list.length) continue;\n out.push(`## ${KIND_LABEL[kind]}`);\n for (const e of list) {\n const bits = [...(e.aliases.length ? [`\u522B\u540D ${e.aliases.join(\"\u3001\")}`] : []), ...(e.currentLook ? [`\u5F53\u524D\u9020\u578B ${e.currentLook}`] : [])];\n out.push(`- ${e.canonical}\uFF5C${bits.join(\"\uFF5C\")}`);\n if (!detailed(e)) continue; // dormant \u2192 one-line stub only\n if (e.description) out.push(` \u7B80\u4ECB\uFF1A${e.description}`);\n for (const l of e.looks) {\n const nm = l.aliases.length ? `${l.name}(=${l.aliases.join(\"=\")})` : l.name;\n out.push(` \u9020\u578B ${nm}${l.description ? `\uFF1A${l.description}` : \"\"}`);\n }\n }\n }\n if (ctx.synopsis.length) { out.push(\"\", \"# \u524D\u60C5\"); for (const s of ctx.synopsis) out.push(`- ${synopsisLabel(s)}\uFF1A${s.line}`); }\n if (ctx.recent.length) {\n out.push(\"\", \"# \u6700\u8FD1\");\n for (const r of ctx.recent) {\n out.push(`## ${recentLabel(r)}`);\n if (r.summary.trim()) out.push(`\u6897\u6982\uFF1A${r.summary.trim()}`);\n for (const e of r.subEvents) out.push(`- ${e}`);\n }\n }\n return out.join(\"\\n\");\n}\n", "import { isCrowdName } from \"./serial-context.js\";\nimport type { ValidationIssue } from \"./validation.js\";\nimport type { ScriptV4 } from \"../script/v4/types.js\";\n\nconst ACTION_PRONOUN = /(?:^|[\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A\u3001\\s\u201C\u201D\"'\uFF08(])(\u4ED6\u4EEC|\u5979\u4EEC|\u5B83\u4EEC|\u5176\u4E2D\u4E00\u4EBA|\u53E6\u4E00\u4E2A\u4EBA|\u524D\u8005|\u540E\u8005|\u5BF9\u65B9|\u6709\u4EBA|\u4E24\u4EBA|\u4ED6|\u5979|\u5B83)(?!\u4EBA)/;\n\n/**\n * Production-facing quality checks for the final Script v4 document. Ingest\n * appends these as warnings so source fidelity and model uncertainty remain\n * reviewable without turning a valid extraction into data loss.\n */\nexport function validateProductionStandard(script: ScriptV4): ValidationIssue[] {\n const warnings: ValidationIssue[] = [];\n const warn = (code: string, path: string, message: string): void => {\n warnings.push({ code, path, message });\n };\n\n script.actors.forEach((asset, index) => {\n if (isCrowdName(asset.actor_name)) {\n warn(\"production_crowd_actor\", `$.actors[${index}].actor_name`, `${asset.actor_name} is a group speaker, not an actor asset`);\n }\n });\n\n script.episodes.forEach((episode, episodeIndex) => {\n episode.scenes.forEach((scene, sceneIndex) => {\n const scenePath = `$.episodes[${episodeIndex}].scenes[${sceneIndex}]`;\n if (scene.location === null) {\n warn(\"production_location_missing\", `${scenePath}.location`, \"production scene needs one stable location\");\n }\n scene.actions.forEach((action, actionIndex) => {\n const actionPath = `${scenePath}.actions[${actionIndex}]`;\n if (action.type === \"action\") {\n const match = ACTION_PRONOUN.exec(action.content);\n if (match) {\n warn(\"production_action_pronoun\", `${actionPath}.content`, `action uses ambiguous reference ${match[1]}`);\n }\n }\n });\n });\n });\n\n return warnings;\n}\n", "// Deterministic final id renumbering (\u00A7 ids). Governance leaves survivor ids\n// with gaps (merges/\u2026) and globally-unique state ids; this one-time pass, run at\n// the very end of ingest, renumbers everything to clean, contiguous, readable\n// ids and rewrites all references. ids are opaque stable keys \u2014 this is only the\n// clean initial numbering for the freshly-generated product (editing never\n// renumbers). Pure: input never mutated; returns the doc + old\u2192new id map.\n//\n// episode ep_NNN by episodes[] order\n// scene scn_NNN global, by appearance order (scenes can move across eps)\n// actor act_NNN by first appearance in the script (per kind, contiguous)\n// location loc_NNN\n// prop prp_NNN\n// state default + st_NNN per-asset scoped (default kept)\n\ntype Obj = Record<string, unknown>;\nconst isObj = (v: unknown): v is Obj => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst isArr = (v: unknown): v is unknown[] => Array.isArray(v);\nconst pad = (n: number): string => String(n).padStart(3, \"0\");\n\nexport type IdMap = {\n episodes: Record<string, string>;\n scenes: Record<string, string>;\n actors: Record<string, string>;\n locations: Record<string, string>;\n props: Record<string, string>;\n states: Record<string, string>; // old global-unique state id \u2192 new per-asset id\n};\n\nconst KINDS = [\n { key: \"actors\", idField: \"actor_id\", prefix: \"act\" },\n { key: \"locations\", idField: \"location_id\", prefix: \"loc\" },\n { key: \"props\", idField: \"prop_id\", prefix: \"prp\" },\n] as const;\n\nexport function renumberIds(input: unknown): { script: Obj; idMap: IdMap } {\n if (!isObj(input)) throw new Error(\"renumberIds expects a script object\");\n const doc = JSON.parse(JSON.stringify(input)) as Obj;\n const idMap: IdMap = { episodes: {}, scenes: {}, actors: {}, locations: {}, props: {} , states: {} };\n\n // 1. Asset ids by first appearance (document walk).\n const seen: Record<\"actors\" | \"locations\" | \"props\", string[]> = { actors: [], locations: [], props: [] };\n const seenSet: Record<\"actors\" | \"locations\" | \"props\", Set<string>> = { actors: new Set(), locations: new Set(), props: new Set() };\n const see = (bucket: \"actors\" | \"locations\" | \"props\", id: unknown) => { if (typeof id === \"string\" && !seenSet[bucket].has(id)) { seenSet[bucket].add(id); seen[bucket].push(id); } };\n for (const ep of isArr(doc.episodes) ? doc.episodes : []) {\n if (!isObj(ep) || !isArr(ep.scenes)) continue;\n for (const sc of ep.scenes) {\n if (!isObj(sc)) continue;\n if (isObj(sc.location)) see(\"locations\", sc.location.location_id);\n for (const a of isArr(sc.actors) ? sc.actors : []) if (isObj(a)) see(\"actors\", a.actor_id);\n for (const p of isArr(sc.props) ? sc.props : []) if (isObj(p)) see(\"props\", p.prop_id);\n for (const ac of isArr(sc.actions) ? sc.actions : []) if (isObj(ac) && isObj(ac.speaker)) see(\"actors\", ac.speaker.actor_id);\n }\n }\n // Append any asset present in the top-level lists but never referenced.\n for (const { key, idField } of KINDS) for (const a of isArr(doc[key]) ? (doc[key] as unknown[]) : []) if (isObj(a)) see(key as \"actors\" | \"locations\" | \"props\", a[idField]);\n\n for (const { key, prefix } of KINDS) seen[key as \"actors\" | \"locations\" | \"props\"].forEach((old, i) => { idMap[key as \"actors\" | \"locations\" | \"props\"][old] = `${prefix}_${pad(i + 1)}`; });\n\n // 2. Rebuild top-level asset lists in new-id order; renumber per-asset states.\n for (const { key, idField } of KINDS) {\n const list = (isArr(doc[key]) ? doc[key] : []).filter(isObj) as Obj[];\n const bucket = idMap[key as \"actors\" | \"locations\" | \"props\"];\n const byNew = new Map<string, Obj>();\n for (const a of list) {\n const oldId = a[idField] as string;\n const newId = bucket[oldId] ?? oldId;\n a[idField] = newId;\n // states: keep default, renumber the rest st_001.. in array order.\n let n = 0;\n for (const st of isArr(a.states) ? a.states : []) {\n if (!isObj(st) || typeof st.state_id !== \"string\") continue;\n if (st.state_id === \"default\") continue;\n const ns = `st_${pad(++n)}`;\n idMap.states[st.state_id] = ns;\n st.state_id = ns;\n }\n byNew.set(newId, a);\n }\n doc[key] = [...byNew.entries()].sort((x, y) => (x[0] < y[0] ? -1 : 1)).map((e) => e[1]);\n }\n\n // 3. Episode / scene ids (in order).\n let scn = 0;\n (isArr(doc.episodes) ? doc.episodes : []).forEach((ep, ei) => {\n if (!isObj(ep)) return;\n if (typeof ep.episode_id === \"string\") { const nid = `ep_${pad(ei + 1)}`; idMap.episodes[ep.episode_id] = nid; ep.episode_id = nid; }\n for (const sc of isArr(ep.scenes) ? ep.scenes : []) {\n if (!isObj(sc)) continue;\n if (typeof sc.scene_id === \"string\") { const nid = `scn_${pad(++scn)}`; idMap.scenes[sc.scene_id] = nid; sc.scene_id = nid; }\n }\n });\n\n // 4. Rewrite references (asset ids + state ids) throughout the scenes.\n const remapRef = (holder: unknown, idField: string, kind: \"actors\" | \"locations\" | \"props\") => {\n if (!isObj(holder) || typeof holder[idField] !== \"string\") return;\n holder[idField] = idMap[kind][holder[idField] as string] ?? holder[idField];\n if (typeof holder.state_id === \"string\" && idMap.states[holder.state_id]) holder.state_id = idMap.states[holder.state_id];\n };\n for (const ep of isArr(doc.episodes) ? doc.episodes : []) {\n if (!isObj(ep) || !isArr(ep.scenes)) continue;\n for (const sc of ep.scenes) {\n if (!isObj(sc)) continue;\n remapRef(sc.location, \"location_id\", \"locations\");\n for (const a of isArr(sc.actors) ? sc.actors : []) remapRef(a, \"actor_id\", \"actors\");\n for (const p of isArr(sc.props) ? sc.props : []) remapRef(p, \"prop_id\", \"props\");\n for (const ac of isArr(sc.actions) ? sc.actions : []) if (isObj(ac)) remapRef(ac.speaker, \"actor_id\", \"actors\");\n }\n }\n\n return { script: doc, idMap };\n}\n", "import { CliError, EXIT_INPUT } from \"../../../common.js\";\nimport {\n ACTION_TYPE_SET,\n IMPORTANCE_TIER_SET,\n NON_ACTOR_SPEAKER_KIND_SET,\n type ActionV3,\n type ActorV3,\n type EpisodeV3,\n type LocationV3,\n type PropV3,\n type SceneV3,\n type ScriptV3,\n type StateV3,\n} from \"./types.js\";\n\ntype RecordValue = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is RecordValue {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction optionalString(record: RecordValue, key: string): boolean {\n return record[key] === undefined || typeof record[key] === \"string\";\n}\n\nfunction isJsonValue(value: unknown): boolean {\n if (value === null\n || typeof value === \"string\"\n || typeof value === \"number\"\n || typeof value === \"boolean\") return true;\n if (Array.isArray(value)) return value.every(isJsonValue);\n return isRecord(value) && Object.values(value).every(isJsonValue);\n}\n\nfunction hasValidExtension(record: RecordValue): boolean {\n return record.extend === undefined\n || (isRecord(record.extend) && Object.values(record.extend).every(isJsonValue));\n}\n\nfunction isState(value: unknown): value is StateV3 {\n return isRecord(value)\n && typeof value.state_id === \"string\"\n && typeof value.state_name === \"string\"\n && typeof value.description === \"string\"\n && hasValidExtension(value);\n}\n\nfunction isActor(value: unknown): value is ActorV3 {\n return isRecord(value)\n && typeof value.actor_id === \"string\"\n && typeof value.actor_name === \"string\"\n && typeof value.description === \"string\"\n && typeof value.importance === \"string\"\n && IMPORTANCE_TIER_SET.has(value.importance)\n && (value.aliases === undefined || (Array.isArray(value.aliases) && value.aliases.every((item) => typeof item === \"string\")))\n && (value.role_type === undefined || value.role_type === \"\u4E3B\u89D2\" || value.role_type === \"\u914D\u89D2\")\n && Array.isArray(value.states)\n && value.states.every(isState)\n && hasValidExtension(value);\n}\n\nfunction isLocation(value: unknown): value is LocationV3 {\n return isRecord(value)\n && typeof value.location_id === \"string\"\n && typeof value.location_name === \"string\"\n && typeof value.description === \"string\"\n && typeof value.importance === \"string\"\n && IMPORTANCE_TIER_SET.has(value.importance)\n && (value.aliases === undefined || (Array.isArray(value.aliases) && value.aliases.every((item) => typeof item === \"string\")))\n && Array.isArray(value.states)\n && value.states.every(isState)\n && hasValidExtension(value);\n}\n\nfunction isProp(value: unknown): value is PropV3 {\n return isRecord(value)\n && typeof value.prop_id === \"string\"\n && typeof value.prop_name === \"string\"\n && typeof value.description === \"string\"\n && typeof value.importance === \"string\"\n && IMPORTANCE_TIER_SET.has(value.importance)\n && (value.aliases === undefined || (Array.isArray(value.aliases) && value.aliases.every((item) => typeof item === \"string\")))\n && Array.isArray(value.states)\n && value.states.every(isState)\n && hasValidExtension(value);\n}\n\nfunction isAction(value: unknown): value is ActionV3 {\n if (!isRecord(value)\n || typeof value.type !== \"string\"\n || !ACTION_TYPE_SET.has(value.type)\n || typeof value.content !== \"string\"\n || !optionalString(value, \"emotion\")) return false;\n if (value.speaker !== undefined) {\n if (!isRecord(value.speaker)) return false;\n if (typeof value.speaker.actor_id === \"string\") {\n if (!optionalString(value.speaker, \"state_id\")) return false;\n } else if (typeof value.speaker.kind === \"string\") {\n if (!NON_ACTOR_SPEAKER_KIND_SET.has(value.speaker.kind) || !optionalString(value.speaker, \"label\")) return false;\n } else {\n return false;\n }\n }\n if (value.transition_prompt !== undefined) {\n if (!isRecord(value.transition_prompt)\n || typeof value.transition_prompt.target !== \"string\"\n || typeof value.transition_prompt.process !== \"string\"\n || typeof value.transition_prompt.contrast !== \"string\") return false;\n }\n return hasValidExtension(value);\n}\n\nfunction isScene(value: unknown): value is SceneV3 {\n if (!isRecord(value)\n || typeof value.scene_id !== \"string\"\n || !Array.isArray(value.actors)\n || !Array.isArray(value.props)\n || !Array.isArray(value.actions)\n || !value.actions.every(isAction)) return false;\n if (!value.actors.every((ref) => isRecord(ref) && typeof ref.actor_id === \"string\" && optionalString(ref, \"state_id\"))) return false;\n if (!value.props.every((ref) => isRecord(ref) && typeof ref.prop_id === \"string\" && optionalString(ref, \"state_id\"))) return false;\n if (value.location !== null\n && (!isRecord(value.location)\n || typeof value.location.location_id !== \"string\"\n || !optionalString(value.location, \"state_id\"))) return false;\n if (value.environment !== undefined\n && (!isRecord(value.environment)\n || !optionalString(value.environment, \"space\")\n || !optionalString(value.environment, \"time\"))) return false;\n return hasValidExtension(value);\n}\n\nfunction isEpisode(value: unknown): value is EpisodeV3 {\n return isRecord(value)\n && typeof value.episode_id === \"string\"\n && optionalString(value, \"title\")\n && optionalString(value, \"synopsis\")\n && Array.isArray(value.scenes)\n && value.scenes.every(isScene)\n && hasValidExtension(value);\n}\n\nexport function isScriptV3(value: unknown): value is ScriptV3 {\n return isRecord(value)\n && value.version === 3\n && typeof value.title === \"string\"\n && typeof value.worldview === \"string\"\n && typeof value.style === \"string\"\n && optionalString(value, \"worldview_raw\")\n && optionalString(value, \"synopsis\")\n && optionalString(value, \"logline\")\n && optionalString(value, \"theme\")\n && (value.main_characters === undefined\n || (Array.isArray(value.main_characters)\n && value.main_characters.every((item) => isRecord(item) && typeof item.name === \"string\" && typeof item.role === \"string\")))\n && Array.isArray(value.actors)\n && value.actors.every(isActor)\n && Array.isArray(value.locations)\n && value.locations.every(isLocation)\n && Array.isArray(value.props)\n && value.props.every(isProp)\n && Array.isArray(value.episodes)\n && value.episodes.every(isEpisode)\n && hasValidExtension(value);\n}\n\nexport function requireScriptV3(value: unknown): ScriptV3 {\n if (isScriptV3(value)) return value;\n throw new CliError(\"The local file is not a structurally readable Script v3 document.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_V3_SHAPE_INVALID\",\n hint: \"Repair the local Script v3 structure, then rerun authoring.\",\n data: { expected: [\"Script v3 with typed assets, episodes, scenes, and actions\"], actual: [Array.isArray(value) ? \"array\" : typeof value] },\n });\n}\n", "import { createHash } from \"node:crypto\";\n\nimport type {\n ActionV3,\n AssetKind,\n ScriptV3,\n SpeakerV3,\n} from \"../v3/types.js\";\nimport { parseAssetTarget } from \"../v3/address.js\";\nimport { sortDeep } from \"../text-util.js\";\nimport { generateV4Id, isV4Id, type V4IdByKind, type V4IdKind } from \"./ids.js\";\nimport type {\n ActionV4,\n ActorIdV4,\n ActorRefV4,\n LocationIdV4,\n PropIdV4,\n PropRefV4,\n ScriptV4,\n SpeakerV4,\n StateIdV4,\n} from \"./types.js\";\n\ntype AssetIdMap = {\n actor: Map<string, ActorIdV4>;\n location: Map<string, LocationIdV4>;\n prop: Map<string, PropIdV4>;\n};\n\nexport interface V4IdentityMap {\n version: 3;\n actor: Record<string, ActorIdV4>;\n location: Record<string, LocationIdV4>;\n prop: Record<string, PropIdV4>;\n state: Record<string, Record<string, StateIdV4>>;\n episode: Record<string, V4IdByKind[\"episode\"]>;\n scene: Record<string, V4IdByKind[\"scene\"]>;\n action: Record<string, V4IdByKind[\"action\"]>;\n}\n\nexport interface V4ConversionResult {\n script: ScriptV4;\n identityMap: V4IdentityMap;\n}\n\nexport interface V3IdentityKeys {\n actor?: Readonly<Record<string, string>>;\n location?: Readonly<Record<string, string>>;\n prop?: Readonly<Record<string, string>>;\n state?: Readonly<Record<string, Readonly<Record<string, string>>>>;\n episode?: Readonly<Record<string, string>>;\n scene?: Readonly<Record<string, string>>;\n action?: Readonly<Record<string, string>>;\n}\n\nexport function emptyV4IdentityMap(): V4IdentityMap {\n return {\n version: 3,\n actor: {},\n location: {},\n prop: {},\n state: {},\n episode: {},\n scene: {},\n action: {},\n };\n}\n\nfunction requiredMapped<T extends string>(map: ReadonlyMap<string, T>, oldId: string): T {\n const value = map.get(oldId);\n if (value === undefined) throw new Error(`Missing mapped ID for ${oldId}`);\n return value;\n}\n\nexport function newScriptV4FromV3WithIdentity(\n script: ScriptV3,\n prior: V4IdentityMap = emptyV4IdentityMap(),\n sourceKeys: V3IdentityKeys = {},\n): V4ConversionResult {\n if (prior.version !== 3) throw new Error(`Unsupported v4 identity map version: ${String(prior.version)}`);\n const identityMap = structuredClone(prior);\n const ids: AssetIdMap = {\n actor: new Map(),\n location: new Map(),\n prop: new Map(),\n };\n const used = {\n actor: new Set<string>(),\n location: new Set<string>(),\n prop: new Set<string>(),\n episode: new Set<string>(),\n scene: new Set<string>(),\n action: new Set<string>(),\n };\n const allocate = <K extends Exclude<V4IdKind, \"state\">>(\n kind: K,\n key: string,\n map: Record<string, V4IdByKind[K]>,\n existing: Set<string>,\n ): V4IdByKind[K] => {\n const saved = map[key];\n if (saved !== undefined) {\n if (!isV4Id(kind, saved)) throw new Error(`Invalid persisted ${kind} ID for ${key}: ${saved}`);\n if (existing.has(saved)) throw new Error(`Duplicate persisted ${kind} ID: ${saved}`);\n existing.add(saved);\n return saved;\n }\n const generated = generateV4Id(kind, existing);\n existing.add(generated);\n map[key] = generated;\n return generated;\n };\n const assetSourceKey = (\n kind: \"actor\" | \"location\" | \"prop\",\n id: string,\n ): string => sourceKeys[kind]?.[id] ?? id;\n for (const actor of script.actors) {\n const id = allocate(\n \"actor\",\n assetSourceKey(\"actor\", actor.actor_id),\n identityMap.actor,\n used.actor,\n );\n ids.actor.set(actor.actor_id, id);\n }\n for (const location of script.locations) {\n const id = allocate(\n \"location\",\n assetSourceKey(\"location\", location.location_id),\n identityMap.location,\n used.location,\n );\n ids.location.set(location.location_id, id);\n }\n for (const prop of script.props) {\n const id = allocate(\n \"prop\",\n assetSourceKey(\"prop\", prop.prop_id),\n identityMap.prop,\n used.prop,\n );\n ids.prop.set(prop.prop_id, id);\n }\n\n const stateMaps = new Map<string, Map<string, StateIdV4>>();\n const convertStates = (\n ownerKind: \"actor\" | \"location\" | \"prop\",\n ownerId: string,\n states: ScriptV3[\"actors\"][number][\"states\"],\n ): ScriptV4[\"actors\"][number][\"states\"] => {\n const map = new Map<string, StateIdV4>();\n const usedStates = new Set<string>();\n const ownerSourceKey = assetSourceKey(ownerKind, ownerId);\n const persisted = identityMap.state[ownerSourceKey] ?? {};\n identityMap.state[ownerSourceKey] = persisted;\n const converted = states.map((state) => {\n let stateId: StateIdV4;\n if (state.state_id === \"default\") {\n stateId = \"default\";\n } else {\n const sourceKey = sourceKeys.state?.[ownerId]?.[state.state_id] ?? state.state_id;\n const saved = persisted[sourceKey];\n if (saved !== undefined) {\n if (!isV4Id(\"state\", saved)) throw new Error(`Invalid persisted state ID for ${ownerId}/${state.state_id}: ${saved}`);\n if (usedStates.has(saved)) throw new Error(`Duplicate persisted state ID on ${ownerId}: ${saved}`);\n stateId = saved;\n } else {\n stateId = generateV4Id(\"state\", usedStates);\n persisted[sourceKey] = stateId;\n }\n }\n usedStates.add(stateId);\n map.set(state.state_id, stateId);\n return { ...state, state_id: stateId };\n });\n stateMaps.set(ownerId, map);\n return converted;\n };\n const stateId = (ownerId: string, oldStateId: string | undefined): StateIdV4 | undefined =>\n oldStateId === undefined ? undefined : requiredMapped(stateMaps.get(ownerId) ?? new Map(), oldStateId);\n\n const actors = script.actors.map((actor) => ({\n ...actor,\n actor_id: requiredMapped(ids.actor, actor.actor_id),\n states: convertStates(\"actor\", actor.actor_id, actor.states),\n }));\n const locations = script.locations.map((location) => ({\n ...location,\n location_id: requiredMapped(ids.location, location.location_id),\n states: convertStates(\"location\", location.location_id, location.states),\n }));\n const props = script.props.map((prop) => ({\n ...prop,\n prop_id: requiredMapped(ids.prop, prop.prop_id),\n states: convertStates(\"prop\", prop.prop_id, prop.states),\n }));\n\n const speaker = (value: SpeakerV3): SpeakerV4 => {\n if (\"actor_id\" in value) {\n const mappedState = stateId(value.actor_id, value.state_id);\n return {\n actor_id: requiredMapped(ids.actor, value.actor_id),\n ...(mappedState === undefined ? {} : { state_id: mappedState }),\n };\n }\n return value.label === undefined\n ? { kind: value.kind }\n : { kind: value.kind, label: value.label };\n };\n const transitionTarget = (target: string): ActorIdV4 | LocationIdV4 | PropIdV4 => {\n if (target.includes(\":\")) {\n const [kind, oldId] = parseAssetTarget(target);\n if (kind === \"actor\") return requiredMapped(ids.actor, oldId);\n if (kind === \"location\") return requiredMapped(ids.location, oldId);\n return requiredMapped(ids.prop, oldId);\n }\n const mapped = ids.actor.get(target) ?? ids.location.get(target) ?? ids.prop.get(target);\n if (mapped === undefined) throw new Error(`Missing transition target mapping for ${target}`);\n return mapped;\n };\n const action = (value: ActionV3, key: string): ActionV4 => {\n const actionId = allocate(\"action\", key, identityMap.action, used.action);\n const transition = value.transition_prompt === undefined\n ? {}\n : {\n transition_prompt: {\n ...value.transition_prompt,\n target: transitionTarget(value.transition_prompt.target),\n },\n };\n if (value.type === \"dialogue\" || value.type === \"inner_thought\") {\n if (value.speaker === undefined) {\n throw new Error(`Speaking action ${value.content.slice(0, 40)} has no speaker`);\n }\n return {\n action_id: actionId,\n type: value.type,\n content: value.content,\n speaker: speaker(value.speaker),\n ...(value.emotion === undefined ? {} : { parenthetical: value.emotion }),\n ...transition,\n ...(value.extend === undefined ? {} : { extend: value.extend }),\n };\n }\n return {\n action_id: actionId,\n type: value.type,\n content: value.content,\n ...transition,\n ...(value.extend === undefined ? {} : { extend: value.extend }),\n };\n };\n const refStates = (ownerId: string, oldStateId: string | undefined): StateIdV4[] =>\n [stateId(ownerId, oldStateId ?? \"default\") ?? \"default\"];\n const actorRefs = (\n refs: ScriptV3[\"episodes\"][number][\"scenes\"][number][\"actors\"],\n actions: ScriptV3[\"episodes\"][number][\"scenes\"][number][\"actions\"],\n ): ActorRefV4[] => {\n const merged = new Map<ActorIdV4, Set<StateIdV4>>();\n for (const ref of refs) {\n const id = requiredMapped(ids.actor, ref.actor_id);\n const states = merged.get(id) ?? new Set<StateIdV4>();\n refStates(ref.actor_id, ref.state_id).forEach((item) => states.add(item));\n merged.set(id, states);\n }\n for (const candidate of actions) {\n if (candidate.speaker === undefined || !(\"actor_id\" in candidate.speaker)) continue;\n const oldActorId = candidate.speaker.actor_id;\n const id = requiredMapped(ids.actor, oldActorId);\n const states = merged.get(id) ?? new Set<StateIdV4>();\n refStates(oldActorId, candidate.speaker.state_id).forEach((item) => states.add(item));\n merged.set(id, states);\n }\n return [...merged].map(([actor_id, states]) => ({\n actor_id,\n state_ids: [...states].sort(),\n }));\n };\n const propRefs = (refs: ScriptV3[\"episodes\"][number][\"scenes\"][number][\"props\"]): PropRefV4[] => {\n const merged = new Map<PropIdV4, Set<StateIdV4>>();\n for (const ref of refs) {\n const id = requiredMapped(ids.prop, ref.prop_id);\n const states = merged.get(id) ?? new Set<StateIdV4>();\n refStates(ref.prop_id, ref.state_id).forEach((item) => states.add(item));\n merged.set(id, states);\n }\n return [...merged].map(([prop_id, states]) => ({\n prop_id,\n state_ids: [...states].sort(),\n }));\n };\n const liveEpisodeKeys = new Set<string>();\n const liveSceneKeys = new Set<string>();\n const liveActionKeys = new Set<string>();\n\n const converted: ScriptV4 = {\n version: 4,\n title: script.title,\n worldview: script.worldview,\n style: script.style,\n ...(script.worldview_raw === undefined ? {} : { worldview_raw: script.worldview_raw }),\n ...(script.synopsis === undefined ? {} : { synopsis: script.synopsis }),\n ...(script.logline === undefined ? {} : { logline: script.logline }),\n ...(script.theme === undefined ? {} : { theme: script.theme }),\n ...(script.main_characters === undefined ? {} : { main_characters: script.main_characters }),\n ...(script.extend === undefined ? {} : { extend: script.extend }),\n actors,\n locations,\n props,\n episodes: script.episodes.map((episode) => {\n const episodeKey = sourceKeys.episode?.[episode.episode_id] ?? episode.episode_id;\n liveEpisodeKeys.add(episodeKey);\n const episodeId = allocate(\"episode\", episodeKey, identityMap.episode, used.episode);\n return {\n ...episode,\n episode_id: episodeId,\n scenes: episode.scenes.map((scene) => {\n const sceneAddress = `${episode.episode_id}/${scene.scene_id}`;\n const sceneKey = sourceKeys.scene?.[sceneAddress] ?? sceneAddress;\n liveSceneKeys.add(sceneKey);\n const sceneId = allocate(\"scene\", sceneKey, identityMap.scene, used.scene);\n const fallbackOccurrences = new Map<string, number>();\n return {\n ...scene,\n scene_id: sceneId,\n location: scene.location === null\n ? null\n : {\n location_id: requiredMapped(ids.location, scene.location.location_id),\n state_ids: refStates(scene.location.location_id, scene.location.state_id),\n },\n actors: actorRefs(scene.actors, scene.actions),\n props: propRefs(scene.props),\n actions: scene.actions.map((candidate, index) => {\n const actionAddress = `${sceneAddress}#${index}`;\n const signature = JSON.stringify(sortDeep(candidate));\n const occurrence = (fallbackOccurrences.get(signature) ?? 0) + 1;\n fallbackOccurrences.set(signature, occurrence);\n const signatureHash = createHash(\"sha256\").update(signature).digest(\"hex\");\n const actionKey = sourceKeys.action?.[actionAddress]\n ?? `${sceneKey}:action:${signatureHash}:${occurrence}`;\n liveActionKeys.add(actionKey);\n return action(candidate, actionKey);\n }),\n };\n }),\n };\n }),\n };\n const keepOnly = (record: Record<string, unknown>, keys: ReadonlySet<string>): void => {\n for (const key of Object.keys(record)) {\n if (!keys.has(key)) delete record[key];\n }\n };\n keepOnly(identityMap.actor, new Set(script.actors.map((asset) => assetSourceKey(\"actor\", asset.actor_id))));\n keepOnly(identityMap.location, new Set(script.locations.map((asset) => assetSourceKey(\"location\", asset.location_id))));\n keepOnly(identityMap.prop, new Set(script.props.map((asset) => assetSourceKey(\"prop\", asset.prop_id))));\n keepOnly(identityMap.episode, liveEpisodeKeys);\n keepOnly(identityMap.scene, liveSceneKeys);\n keepOnly(identityMap.action, liveActionKeys);\n const owners = [\n ...script.actors.map((asset) => ({\n id: assetSourceKey(\"actor\", asset.actor_id),\n oldId: asset.actor_id,\n states: asset.states,\n })),\n ...script.locations.map((asset) => ({\n id: assetSourceKey(\"location\", asset.location_id),\n oldId: asset.location_id,\n states: asset.states,\n })),\n ...script.props.map((asset) => ({\n id: assetSourceKey(\"prop\", asset.prop_id),\n oldId: asset.prop_id,\n states: asset.states,\n })),\n ];\n keepOnly(identityMap.state, new Set(owners.map((owner) => owner.id)));\n for (const owner of owners) {\n keepOnly(\n identityMap.state[owner.id] ?? {},\n new Set(owner.states.map((state) =>\n sourceKeys.state?.[owner.oldId]?.[state.state_id] ?? state.state_id)),\n );\n }\n return { script: converted, identityMap };\n}\n\nexport function newScriptV4FromV3(script: ScriptV3): ScriptV4 {\n return newScriptV4FromV3WithIdentity(script).script;\n}\n", "import {\n CliError, DELIVERY_VALUES, EFFECTIVE_FROM_VALUES,\n EXIT_INPUT, EXIT_USAGE, SCRIPT_SCHEMA_VERSION,\n SCRIPT_TARGET_KINDS, WORLDVIEW_VALUES,\n directDir, exists, fmtId, readJson, readText, writeJson,\n} from \"../../../common.js\";\nimport { asList, type Dict, idNum, isDict, isList, opErr, strOf } from \"../shared.js\";\n\nexport function parseAssetTarget(raw: unknown): [string, string] {\n const value = strOf(raw).trim();\n if (!value.includes(\":\")) {\n throw new CliError(\"Target invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"TARGET_INVALID\",\n hint: \"Use a concrete asset target.\",\n data: { expected: [\"target: actor:<id>, location:<id>, or prop:<id>\"], actual: [value || \"<empty>\"] },\n });\n }\n const idx = value.indexOf(\":\");\n const kind = value.slice(0, idx).trim();\n const targetId = value.slice(idx + 1).trim();\n if (!SCRIPT_TARGET_KINDS.has(kind) || !targetId) {\n throw new CliError(\"Target invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"TARGET_INVALID\",\n hint: \"Use actor, location, or prop with a non-empty id.\",\n data: { expected: [\"target: actor:<id>, location:<id>, or prop:<id>\"], actual: [value] },\n });\n }\n return [kind, targetId];\n}\n\nexport function parseStateTarget(raw: unknown): [string, string, string] {\n const value = strOf(raw).trim();\n if (!value.includes(\"/\")) {\n throw new CliError(\"State target invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"STATE_TARGET_INVALID\",\n hint: \"Use a concrete state target.\",\n data: { expected: [\"state target: actor:<id>/<state_id>\"], actual: [value || \"<empty>\"] },\n });\n }\n const lastSlash = value.lastIndexOf(\"/\");\n const assetRaw = value.slice(0, lastSlash);\n const stateId = value.slice(lastSlash + 1).trim();\n const [kind, targetId] = parseAssetTarget(assetRaw);\n if (!stateId) {\n throw new CliError(\"State target invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"STATE_TARGET_INVALID\",\n hint: \"Use a non-empty state_id.\",\n data: { expected: [\"state_id after '/'\"], actual: [value] },\n });\n }\n return [kind, targetId, stateId];\n}\n\nexport function parseSceneRef(raw: unknown): [string, string] {\n const value = strOf(raw).trim();\n if (!value.includes(\"/\")) {\n throw new CliError(\"Scene ref invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SCENE_REF_INVALID\",\n hint: \"Use ep_id/scn_id.\",\n data: { expected: [\"scene ref: ep_001/scn_001\"], actual: [value || \"<empty>\"] },\n });\n }\n const idx = value.indexOf(\"/\");\n return [value.slice(0, idx).trim(), value.slice(idx + 1).trim()];\n}\n\nexport function parseActionRef(raw: unknown): [string, string, number] {\n const value = strOf(raw).trim();\n if (!value.includes(\"#\")) {\n throw new CliError(\"Action ref invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"ACTION_REF_INVALID\",\n hint: \"Use ep_id/scn_id#action_index.\",\n data: { expected: [\"action ref: ep_001/scn_001#4\"], actual: [value || \"<empty>\"] },\n });\n }\n const lastHash = value.lastIndexOf(\"#\");\n const sceneRaw = value.slice(0, lastHash);\n const indexRaw = value.slice(lastHash + 1);\n const [epId, sceneId] = parseSceneRef(sceneRaw);\n const actionIndex = parseInt(indexRaw, 10);\n if (Number.isNaN(actionIndex)) {\n throw new CliError(\"Action index invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"ACTION_INDEX_INVALID\",\n hint: \"Use a zero-based action index.\",\n data: { expected: [\"integer action index after '#'\"], actual: [value] },\n });\n }\n return [epId, sceneId, actionIndex];\n}\n\nexport type AnyAddress =\n | { kind: \"action\"; episodeId: string; sceneId: string; actionIndex: number }\n | { kind: \"scene\"; episodeId: string; sceneId: string }\n | { kind: \"asset\"; assetKind: string; assetId: string }\n | { kind: \"state\"; assetKind: string; assetId: string; stateId: string }\n | { kind: \"episode\"; episodeId: string }\n | { kind: \"speaker\"; speakerId: string }\n | { kind: \"global\" };\n\n// Try each format in order. The order matters: action (has `#`) is checked\n// before scene (just `/`), and asset+state (has `:`) is checked before scene.\n// Episode and speaker are bare ids (no separators) distinguished by prefix;\n// `global` is the literal script-level sentinel.\nexport function parseAnyAddress(raw: unknown): AnyAddress {\n const value = strOf(raw).trim();\n if (!value) {\n throw new CliError(\"Address empty.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"ADDRESS_EMPTY\",\n hint: \"Pass an address like ep_001/scn_001#3, ep_001/scn_001, actor:act_001, actor:act_001/st_001, ep_001, spk_001, or global.\",\n data: { expected: [\"one of the supported address formats\"], actual: [\"<empty>\"] },\n });\n }\n if (value.includes(\"#\")) {\n const [episodeId, sceneId, actionIndex] = parseActionRef(value);\n return { kind: \"action\", episodeId, sceneId, actionIndex };\n }\n if (value.includes(\":\")) {\n if (value.slice(value.indexOf(\":\") + 1).includes(\"/\")) {\n const [assetKind, assetId, stateId] = parseStateTarget(value);\n return { kind: \"state\", assetKind, assetId, stateId };\n }\n const [assetKind, assetId] = parseAssetTarget(value);\n return { kind: \"asset\", assetKind, assetId };\n }\n if (value.includes(\"/\")) {\n const [episodeId, sceneId] = parseSceneRef(value);\n return { kind: \"scene\", episodeId, sceneId };\n }\n if (value === \"global\") {\n return { kind: \"global\" };\n }\n if (/^ep_/.test(value)) {\n return { kind: \"episode\", episodeId: value };\n }\n if (/^spk_/.test(value)) {\n return { kind: \"speaker\", speakerId: value };\n }\n throw new CliError(\"Address invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"ADDRESS_INVALID\",\n hint: \"Use a recognized address format.\",\n data: { expected: [\n \"address: ep_NNN/scn_NNN#idx (action) | ep_NNN/scn_NNN (scene) | actor|location|prop:id (asset) | actor|location|prop:id/state_id (state) | ep_NNN (episode) | spk_XXX (speaker) | global (script-level)\",\n ], actual: [value] },\n });\n}\n", "// Pure text/canonicalization helpers for the script edit + validation layer.\n// Extracted from the (now-removed) direct-core so the script subsystem is\n// self-contained. No I/O, no schema knowledge beyond field names.\nimport { asList, type Dict, isDict, strOf } from \"./shared.js\";\n\n// Deep-sort object keys for a stable canonical JSON (idempotency hashing).\nexport function sortDeep(value: unknown): unknown {\n if (Array.isArray(value)) return value.map((v) => sortDeep(v));\n if (isDict(value)) {\n const sorted: Dict = {};\n for (const k of Object.keys(value).sort()) sorted[k] = sortDeep(value[k]);\n return sorted;\n }\n return value;\n}\n\nconst _ANNOTATION_RE = /(?:\u3010[^\u3011]*\u3011|[\uFF08(][^\uFF09)]*[\uFF09)])/g;\nconst _STATE_MIXED_SEPARATORS = [\"/\", \"\uFF0F\", \"+\", \"\u3001\", \"\uFF0C\", \",\"];\n\nfunction reReplace(pattern: RegExp, s: string, replacement: string): string {\n const flags = pattern.flags.includes(\"g\") ? pattern.flags : pattern.flags + \"g\";\n return s.replace(new RegExp(pattern.source, flags), replacement);\n}\n\nfunction pyStrip(s: string, chars?: string): string {\n if (chars === undefined) return s.trim();\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start += 1;\n while (end > start && chars.includes(s[end - 1]!)) end -= 1;\n return s.slice(start, end);\n}\n\nfunction reSearch(pattern: RegExp, s: string): RegExpExecArray | null {\n const flags = pattern.flags.includes(\"g\") ? pattern.flags.replace(\"g\", \"\") : pattern.flags;\n return new RegExp(pattern.source, flags).exec(s);\n}\n\n// Canonical asset name: strip \u3010\u2026\u3011/\uFF08\u2026\uFF09 annotations + leading/trailing punctuation.\nexport function cleanName(name: unknown): string {\n const value = reReplace(_ANNOTATION_RE, strOf(name).trim(), \"\");\n return pyStrip(value, \" \\t\\r\\n:\uFF1A,\uFF0C\u3001\");\n}\n\n// null when the state label is a single clean state; a reason code otherwise.\nexport function stateLabelError(stateName: unknown): string | null {\n const text = strOf(stateName).trim().replace(/\\s+/g, \"\");\n if (!text) return \"empty\";\n if (_STATE_MIXED_SEPARATORS.some((sep) => text.includes(sep))) return \"mixed_state_label\";\n return null;\n}\n\nexport function stateRejectionReason(targetKind: string, stateName: unknown): string | null {\n const kind = strOf(targetKind).trim();\n if (kind === \"actor\" || kind === \"location\" || kind === \"prop\") return stateLabelError(stateName);\n return strOf(stateName).trim().replace(/\\s+/g, \"\") ? null : \"empty\";\n}\n\n// Heuristic: is a would-be actor name actually a non-actor voice source?\nexport function inferNonActorSpeakerKind(name: string, scene: Dict | null = null): string {\n const value = strOf(name).trim();\n if (!value) return \"actor\";\n if (reSearch(/\u7CFB\u7EDF|\u63D0\u793A\u97F3|\u63D0\u793A\u58F0|\u673A\u68B0\u97F3|\u7535\u5B50\u97F3/, value)) return \"system\";\n if (reSearch(/\u5E7F\u64AD(?!\u5458)|\u5587\u53ED|\u7535\u53F0|\u64AD\u62A5|\u901A\u77E5|\u8B66\u62A5/, value)) return \"broadcast\";\n if (reSearch(/\u4F17\u4EBA|\u4F17|\u7FA4\u4F53|\u5168\u4F53|\u5927\u5BB6|\u4EBA\u7FA4|\u5BBE\u5BA2|\u89C2\u4F17|\u7FA4\u4F17|\u56F4\u89C2\u8005/, value)) return \"group\";\n if (scene) {\n const propSet = new Set(asList<string>(scene[\"prop_names\"]).map((p) => strOf(p).trim()));\n if (propSet.has(value)) return \"prop\";\n if (value === strOf(scene[\"location_name\"]).trim()) return \"location\";\n }\n return \"actor\";\n}\n\n// One-line summary of a validation issue list, for command output warnings.\nexport function summarizeIssues(issues: Dict[]): string[] {\n if (issues.length === 0) return [];\n const counts: Record<string, number> = {};\n for (const item of issues) {\n const sev = strOf(item[\"severity\"]);\n counts[sev] = (counts[sev] ?? 0) + 1;\n }\n const parts = Object.entries(counts).sort(([a], [b]) => a.localeCompare(b)).map(([sev, c]) => `${sev}: ${c}`);\n const first = issues[0]!;\n return [\n parts.join(\"; \"),\n `first: ${first[\"code\"]} - ${first[\"summary\"]}`,\n ...(first[\"repair_hint\"] ? [`repair: ${first[\"repair_hint\"]}`] : []),\n ];\n}\n", "// The v4 identity grammar and generator live in `@lingjingai/screenplay/schema`.\n// Only the wrappers that raise scriptctl's own CliError stay here.\nimport { CliError, EXIT_INPUT } from \"../../../common.js\";\nimport {\n ID_SPACE_EXHAUSTED,\n generateV4Id as generate,\n generateV4Ids as generateMany,\n isV4Id,\n V4_ID_PREFIXES,\n type V4IdByKind,\n type V4IdKind,\n} from \"@lingjingai/screenplay/schema\";\n\nexport {\n isV4Id,\n V4_ID_ALPHABET,\n V4_ID_PATTERNS,\n V4_ID_PREFIXES,\n V4_ID_RANDOM_LENGTH,\n type V4IdByKind,\n type V4IdKind,\n} from \"@lingjingai/screenplay/schema\";\n\nexport function requireV4Id<K extends V4IdKind>(kind: K, value: unknown, path: string): V4IdByKind[K] {\n if (isV4Id(kind, value)) return value;\n throw new CliError(`${path} must be ${V4_ID_PREFIXES[kind]} plus six Base58 characters.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_V4_ID_INVALID\",\n data: { expected: [`${V4_ID_PREFIXES[kind]} + 6 Bitcoin Base58 characters`], actual: [String(value)] },\n });\n}\n\nexport function generateV4Id<K extends V4IdKind>(\n kind: K,\n existing: ReadonlySet<string> = new Set(),\n generateSuffix?: () => string,\n): V4IdByKind[K] {\n try {\n return generateSuffix ? generate(kind, existing, generateSuffix) : generate(kind, existing);\n } catch (error) {\n // Only remap the one failure this is about; anything else keeps its own\n // identity instead of being relabelled as a retry exhaustion.\n if ((error as { code?: string })?.code !== ID_SPACE_EXHAUSTED) throw error;\n throw new CliError(`Could not generate an unused ${kind} ID.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"ID_SPACE_RETRY_EXHAUSTED\",\n hint: \"Retry the command. If this persists, inspect the configured ID generator.\",\n });\n }\n}\n\nexport function generateV4Ids<K extends V4IdKind>(\n kind: K,\n count: number,\n existing: ReadonlySet<string> = new Set(),\n): V4IdByKind[K][] {\n if (!Number.isSafeInteger(count) || count < 1) {\n throw new CliError(\"count must be a positive integer.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"ID_COUNT_INVALID\",\n data: { actual: [String(count)] },\n });\n }\n return generateMany(kind, count, existing);\n}\n", "// Text source reader (\u00A7pass1-prepare). Strict UTF-8 decode (rejects invalid\n// bytes), BOM strip, CRLF/CR \u2192 LF. Markdown is preserved verbatim (order,\n// headings, lists) \u2014 no screenplay interpretation here. DOCX reuses the existing\n// OpenXML converter, then goes through the same normalization.\n\nimport * as fs from \"node:fs\";\n\nimport { convertDocx } from \"../converters.js\";\n\nexport class SourceDecodeError extends Error {}\n\nfunction normalize(text: string): string {\n return text.replace(/^\uFEFF/, \"\").replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction decodeUtf8Strict(buf: Buffer): string {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(buf);\n } catch {\n throw new SourceDecodeError(\"source is not valid UTF-8\");\n }\n}\n\nexport async function readTextSource(sourcePath: string, ext: string): Promise<string> {\n if (ext === \".docx\") {\n const [text] = await convertDocx(sourcePath);\n return normalize(text);\n }\n return normalize(decodeUtf8Strict(fs.readFileSync(sourcePath)));\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport JSZip from \"jszip\";\nimport { XMLParser } from \"fast-xml-parser\";\n\nimport {\n fmtId,\n readText,\n sha256File,\n sha256Text,\n writeText,\n} from \"../common.js\";\nimport {\n cleanEpisodeShortTitle,\n episodeNumberFromValue,\n isTechnicalEpisodeTitle,\n} from \"./episode-title.js\";\n\ntype Dict = Record<string, unknown>;\n// fast-xml-parser preserveOrder emits arrays of keyed node objects. Attributes\n// live on the same object under \":@\".\ntype OrderedNode = Record<string, unknown> & { \"#text\"?: string | number | boolean; \":@\"?: Record<string, unknown> };\n\nfunction strOf(v: unknown): string {\n if (v === null || v === undefined) return \"\";\n return String(v);\n}\n\nfunction isDict(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction isList(v: unknown): v is unknown[] {\n return Array.isArray(v);\n}\n\nfunction asList<T = unknown>(v: unknown): T[] {\n return Array.isArray(v) ? (v as T[]) : [];\n}\n\n// ---------------------------------------------------------------------------\n// Text formats\n// ---------------------------------------------------------------------------\n\nexport function convertTxt(source: string): string {\n return readText(source).replace(/^\uFEFF/, \"\");\n}\n\nexport function rowsToMergedLines(rows: string[][]): string {\n if (rows.length === 0) return \"\";\n const lines: string[] = [];\n let prevScene = \"\";\n for (let i = 1; i < rows.length; i++) {\n const row = rows[i]!;\n const nonEmpty = row.filter((c) => c);\n if (nonEmpty.length === 0) continue;\n const first = row[0] ?? \"\";\n if (first.includes(\"\uD83C\uDFAC\") || /\u7B2C\\s*\\d+\\s*\u96C6/.test(first)) {\n lines.push(`\\n${first}`);\n continue;\n }\n let scene = row.length > 1 ? row[1] ?? \"\" : \"\";\n if (!scene) scene = prevScene;\n prevScene = scene;\n const parts: string[] = [];\n if (first) parts.push(`${first}.`);\n const remaining = row.slice(2).filter((c) => c);\n if (scene && remaining.length > 0) parts.push(`${scene}\uFF0C${remaining.join(\" \")}`);\n else if (scene) parts.push(scene);\n else parts.push(...remaining);\n lines.push(parts.join(\" \"));\n }\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// XLSX (OpenXML text extraction)\n// ---------------------------------------------------------------------------\n\ntype XlsxSheet = { name: string; path: string };\n\nfunction attrOf(node: Record<string, unknown>, key: string): string {\n const attrs = node[\":@\"];\n if (!isDict(attrs)) return \"\";\n return strOf(attrs[key]).trim();\n}\n\nfunction firstChildNode(node: Record<string, unknown>, childName: string): OrderedNode[] | null {\n for (const [key, value] of Object.entries(node)) {\n if (localName(key) === childName && isList(value)) return value as OrderedNode[];\n }\n return null;\n}\n\nfunction textFromOrderedNodes(items: unknown): string {\n const parts: string[] = [];\n const walk = (value: unknown): void => {\n if (!isList(value)) return;\n for (const item of value) {\n if (!isDict(item)) continue;\n for (const [key, child] of Object.entries(item)) {\n if (key === \"#text\" && child !== null && child !== undefined) {\n parts.push(strOf(child));\n } else if (key !== \":@\" && isList(child)) {\n walk(child);\n }\n }\n }\n };\n walk(items);\n return parts.join(\"\");\n}\n\nfunction parseXmlFile(xml: string): OrderedNode[] {\n const parsed = xmlParser.parse(xml) as unknown;\n if (!isList(parsed)) throw new Error(\"xlsx xml part has an unexpected shape\");\n return parsed as OrderedNode[];\n}\n\nfunction findDescendantNodes(items: unknown, childName: string): Record<string, unknown>[] {\n const result: Record<string, unknown>[] = [];\n const walk = (value: unknown): void => {\n const nodes: Record<string, unknown>[] = isList(value)\n ? value.filter(isDict)\n : isDict(value)\n ? [value]\n : [];\n for (const item of nodes) {\n for (const [key, child] of Object.entries(item)) {\n if (localName(key) === childName && isList(child)) {\n result.push(item);\n }\n if (isList(child)) walk(child);\n }\n }\n };\n walk(items);\n return result;\n}\n\nfunction columnIndexFromRef(cellRef: string): number | null {\n const match = /^[A-Z]+/i.exec(cellRef.trim());\n if (!match) return null;\n let index = 0;\n for (const ch of match[0]!.toUpperCase()) {\n index = index * 26 + ch.charCodeAt(0) - 64;\n }\n return index - 1;\n}\n\nfunction normalizeXlsxPartPath(baseDir: string, target: string): string {\n const rawPath = target.startsWith(\"/\") ? target.slice(1) : `${baseDir}/${target}`;\n const parts = rawPath.split(\"/\");\n const out: string[] = [];\n for (const part of parts) {\n if (!part || part === \".\") continue;\n if (part === \"..\") out.pop();\n else out.push(part);\n }\n return out.join(\"/\");\n}\n\nasync function readZipText(zip: JSZip, partPath: string): Promise<string | null> {\n const file = zip.file(partPath);\n return file ? file.async(\"string\") : null;\n}\n\nasync function loadSharedStrings(zip: JSZip): Promise<string[]> {\n const xml = await readZipText(zip, \"xl/sharedStrings.xml\");\n if (!xml) return [];\n const parsed = parseXmlFile(xml);\n const strings: string[] = [];\n for (const si of findDescendantNodes(parsed, \"si\")) {\n strings.push(textFromOrderedNodes(firstChildNode(si, \"si\") ?? []));\n }\n return strings;\n}\n\nasync function loadWorkbookSheets(zip: JSZip): Promise<XlsxSheet[]> {\n const workbookXml = await readZipText(zip, \"xl/workbook.xml\");\n const relsXml = await readZipText(zip, \"xl/_rels/workbook.xml.rels\");\n if (!workbookXml || !relsXml) throw new Error(\"xlsx missing workbook metadata\");\n\n const rels = new Map<string, string>();\n for (const rel of findDescendantNodes(parseXmlFile(relsXml), \"Relationship\")) {\n const id = attrOf(rel, \"@_Id\");\n const target = attrOf(rel, \"@_Target\");\n if (id && target) rels.set(id, normalizeXlsxPartPath(\"xl\", target));\n }\n\n const sheets: XlsxSheet[] = [];\n for (const sheet of findDescendantNodes(parseXmlFile(workbookXml), \"sheet\")) {\n const name = attrOf(sheet, \"@_name\");\n const relId = attrOf(sheet, \"@_r:id\");\n const sheetPath = rels.get(relId);\n if (name && sheetPath) sheets.push({ name, path: sheetPath });\n }\n if (sheets.length === 0) throw new Error(\"xlsx workbook contains no readable sheets\");\n return sheets;\n}\n\nfunction cellText(cell: Record<string, unknown>, sharedStrings: string[]): string {\n const type = attrOf(cell, \"@_t\");\n if (type === \"inlineStr\") {\n const inline = findDescendantNodes(cell, \"is\")[0];\n const inlineNodes = inline ? firstChildNode(inline, \"is\") : null;\n return inlineNodes ? textFromOrderedNodes(inlineNodes).trim() : \"\";\n }\n\n const value = findDescendantNodes(cell, \"v\")[0];\n const valueNode = value ? firstChildNode(value, \"v\") : null;\n const rawValue = valueNode ? textFromOrderedNodes(valueNode).trim() : \"\";\n if (!rawValue && type === \"str\") {\n const formulaString = findDescendantNodes(cell, \"is\")[0];\n const formulaNodes = formulaString ? firstChildNode(formulaString, \"is\") : null;\n return formulaNodes ? textFromOrderedNodes(formulaNodes).trim() : \"\";\n }\n if (type === \"s\") {\n const index = Number.parseInt(rawValue, 10);\n return Number.isInteger(index) ? (sharedStrings[index] ?? \"\").trim() : \"\";\n }\n if (type === \"b\") return rawValue === \"1\" ? \"TRUE\" : rawValue === \"0\" ? \"FALSE\" : rawValue;\n if (type === \"str\") return rawValue;\n return rawValue;\n}\n\nasync function sheetToRowsFromBuffer(buffer: Buffer | Uint8Array): Promise<{ name: string; rows: string[][] }[]> {\n const zip = await JSZip.loadAsync(buffer);\n const [sharedStrings, sheets] = await Promise.all([\n loadSharedStrings(zip),\n loadWorkbookSheets(zip),\n ]);\n const result: { name: string; rows: string[][] }[] = [];\n for (const sheet of sheets) {\n const xml = await readZipText(zip, sheet.path);\n if (!xml) throw new Error(`xlsx missing worksheet part: ${sheet.path}`);\n const rows: string[][] = [];\n for (const row of findDescendantNodes(parseXmlFile(xml), \"row\")) {\n const cells: string[] = [];\n for (const cell of findDescendantNodes(row, \"c\")) {\n const ref = attrOf(cell, \"@_r\");\n const index = ref ? columnIndexFromRef(ref) : null;\n const text = cellText(cell, sharedStrings);\n const targetIndex = index ?? cells.length;\n while (cells.length < targetIndex) cells.push(\"\");\n cells[targetIndex] = text.trim();\n }\n if (cells.some((c) => c)) rows.push(cells);\n }\n result.push({ name: sheet.name, rows });\n }\n return result;\n}\n\nexport async function convertXlsx(source: string): Promise<string> {\n const buf = fs.readFileSync(source);\n const sheets = await sheetToRowsFromBuffer(buf);\n const parts: string[] = [];\n for (const sheet of sheets) {\n if (sheet.rows.length === 0) continue;\n parts.push(`## ${sheet.name}\\n`);\n parts.push(rowsToMergedLines(sheet.rows));\n }\n return parts.join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// DOCX (jszip + fast-xml-parser)\n// ---------------------------------------------------------------------------\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n preserveOrder: true,\n trimValues: false,\n textNodeName: \"#text\",\n});\n\nfunction localName(tag: string): string {\n const idx = tag.indexOf(\":\");\n return idx >= 0 ? tag.slice(idx + 1) : tag;\n}\n\nfunction isParsedNode(node: unknown): node is Record<string, unknown> {\n return isDict(node);\n}\n\nfunction getChildren(node: Record<string, unknown>, tagPredicate: (local: string) => boolean): Array<{ tag: string; node: Record<string, unknown> }> {\n const out: Array<{ tag: string; node: Record<string, unknown> }> = [];\n for (const key of Object.keys(node)) {\n if (key.startsWith(\"@_\") || key === \"#text\" || key === \":@\") continue;\n if (tagPredicate(localName(key))) {\n const value = node[key];\n if (isList(value)) {\n for (const item of value) {\n if (isParsedNode(item)) out.push({ tag: key, node: item });\n }\n } else if (isParsedNode(value)) {\n out.push({ tag: key, node: value });\n }\n }\n }\n return out;\n}\n\nfunction paragraphText(paragraphNode: OrderedNode[]): string {\n const parts: string[] = [];\n function walk(items: unknown): void {\n if (!isList(items)) return;\n for (const item of items) {\n if (!isDict(item)) continue;\n for (const [key, value] of Object.entries(item)) {\n if (key === \":@\") continue;\n if (key === \"#text\" && typeof value === \"string\") {\n // ignore \u2014 we look at w:t below\n continue;\n }\n const local = localName(key);\n if (local === \"t\") {\n if (isList(value)) {\n for (const inner of value) {\n if (isDict(inner)) {\n const txt = inner[\"#text\"];\n if (typeof txt === \"string\") parts.push(txt);\n }\n }\n }\n } else if (local === \"tab\") {\n parts.push(\"\\t\");\n } else if (local === \"br\" || local === \"cr\") {\n parts.push(\"\\n\");\n } else if (isList(value)) {\n walk(value);\n }\n }\n }\n }\n walk(paragraphNode);\n return parts.join(\"\").trim();\n}\n\nfunction tableText(tableNode: OrderedNode[]): string {\n const rows: string[][] = [];\n for (const item of tableNode) {\n if (!isDict(item)) continue;\n for (const [key, value] of Object.entries(item)) {\n if (localName(key) !== \"tr\") continue;\n const cells: string[] = [];\n if (isList(value)) {\n for (const cellItem of value) {\n if (!isDict(cellItem)) continue;\n for (const [ckey, cval] of Object.entries(cellItem)) {\n if (localName(ckey) !== \"tc\") continue;\n if (isList(cval)) {\n // find all w:p inside this w:tc\n const paragraphs: string[] = [];\n const collect = (items: unknown): void => {\n if (!isList(items)) return;\n for (const x of items) {\n if (!isDict(x)) continue;\n for (const [k, v] of Object.entries(x)) {\n if (localName(k) === \"p\" && isList(v)) {\n const t = paragraphText(v as OrderedNode[]);\n if (t) paragraphs.push(t);\n } else if (isList(v)) {\n collect(v);\n }\n }\n }\n };\n collect(cval);\n cells.push(paragraphs.join(\" \").trim());\n }\n }\n }\n }\n if (cells.some((c) => c)) rows.push(cells);\n }\n }\n return rowsToMergedLines(rows);\n}\n\nasync function extractEmbeddedXlsx(zip: JSZip): Promise<Array<[string, string]>> {\n const results: Array<[string, string]> = [];\n const xlsxFiles: string[] = [];\n zip.forEach((relativePath) => {\n if (relativePath.includes(\"embeddings\") && relativePath.endsWith(\".xlsx\")) {\n xlsxFiles.push(relativePath);\n }\n });\n xlsxFiles.sort();\n let index = 0;\n for (const entry of xlsxFiles) {\n index += 1;\n const file = zip.file(entry);\n if (!file) continue;\n const buf = await file.async(\"nodebuffer\");\n const sheets = await sheetToRowsFromBuffer(buf);\n for (const sheet of sheets) {\n if (sheet.rows.length > 0) {\n results.push([`Embedded Sheet ${index}: ${sheet.name}`, rowsToMergedLines(sheet.rows)]);\n }\n }\n }\n return results;\n}\n\nexport async function convertDocx(source: string): Promise<[string, boolean]> {\n let zip: JSZip;\n try {\n zip = await JSZip.loadAsync(fs.readFileSync(source));\n } catch (exc) {\n throw new Error(\"source is not a valid docx zip file\");\n }\n const documentXml = zip.file(\"word/document.xml\");\n if (!documentXml) throw new Error(\"docx missing word/document.xml\");\n const xmlBytes = await documentXml.async(\"string\");\n const parsed = xmlParser.parse(xmlBytes) as OrderedNode[];\n // find <w:body> inside <w:document>\n let body: OrderedNode[] | null = null;\n const findBody = (items: unknown): void => {\n if (!isList(items)) return;\n for (const item of items) {\n if (!isDict(item)) continue;\n for (const [key, value] of Object.entries(item)) {\n if (localName(key) === \"body\" && isList(value)) {\n body = value as OrderedNode[];\n return;\n }\n if (isList(value)) findBody(value);\n }\n }\n };\n findBody(parsed);\n\n const parts: string[] = [];\n if (body === null) {\n const collectParagraphs = (items: unknown): void => {\n if (!isList(items)) return;\n for (const item of items) {\n if (!isDict(item)) continue;\n for (const [key, value] of Object.entries(item)) {\n if (localName(key) === \"p\" && isList(value)) {\n const t = paragraphText(value as OrderedNode[]);\n if (t) parts.push(t);\n } else if (isList(value)) {\n collectParagraphs(value);\n }\n }\n }\n };\n collectParagraphs(parsed);\n } else {\n for (const child of body as OrderedNode[]) {\n if (!isDict(child)) continue;\n for (const [key, value] of Object.entries(child)) {\n if (key.startsWith(\"@_\") || key === \":@\" || key === \"#text\") continue;\n if (!isList(value)) continue;\n const tag = localName(key);\n if (tag === \"p\") {\n const t = paragraphText(value as OrderedNode[]);\n if (t) parts.push(t);\n } else if (tag === \"tbl\") {\n const t = tableText(value as OrderedNode[]);\n if (t) parts.push(t);\n }\n }\n }\n }\n const embedded = await extractEmbeddedXlsx(zip);\n for (const [label, markdown] of embedded) {\n parts.push(`\\n## ${label}\\n`);\n parts.push(markdown);\n }\n return [parts.join(\"\\n\\n\"), embedded.length > 0];\n}\n\n// ---------------------------------------------------------------------------\n// JSON (script-like)\n// ---------------------------------------------------------------------------\n\nfunction assetIndex(items: unknown, idKey: string, nameKey: string, prefix: string): Map<string, string> {\n const result = new Map<string, string>();\n if (!isList(items)) return result;\n for (let index = 0; index < items.length; index++) {\n const item = items[index];\n if (!isDict(item)) continue;\n const rawId = item[idKey] ?? item[\"id\"] ?? fmtId(prefix, index + 1);\n const assetId = strOf(rawId).trim();\n const rawName = item[nameKey] ?? item[\"name\"] ?? assetId;\n const name = strOf(rawName).trim();\n if (assetId && name) result.set(assetId, name);\n }\n return result;\n}\n\nfunction refId(ref: unknown, key: string): string {\n if (typeof ref === \"string\") return ref;\n if (isDict(ref)) return strOf(ref[key] ?? ref[\"id\"]).trim();\n return \"\";\n}\n\nfunction refNames(refs: unknown, index: Map<string, string>, key: string): string[] {\n if (!isList(refs)) return [];\n const names: string[] = [];\n for (const ref of refs) {\n const name = index.get(refId(ref, key));\n if (name && !names.includes(name)) names.push(name);\n }\n return names;\n}\n\nfunction firstRefName(refs: unknown, index: Map<string, string>, key: string): string {\n const names = refNames(refs, index, key);\n return names[0] ?? \"\";\n}\n\nexport async function convertJson(source: string): Promise<[string, boolean, string]> {\n const text = readText(source).replace(/^\uFEFF/, \"\");\n const data: unknown = JSON.parse(text);\n if (!isDict(data) || !isList(data[\"episodes\"])) {\n throw new Error(\"JSON is not a script.json-like object with episodes[]\");\n }\n const actors = assetIndex(data[\"actors\"], \"actor_id\", \"actor_name\", \"act\");\n const locations = assetIndex(data[\"locations\"], \"location_id\", \"location_name\", \"loc\");\n const props = assetIndex(data[\"props\"], \"prop_id\", \"prop_name\", \"prp\");\n const parts: string[] = [];\n const title = strOf(data[\"title\"] || path.basename(source, path.extname(source))).trim();\n if (title) parts.push(`# ${title}`);\n const episodes = asList<Dict>(data[\"episodes\"]);\n for (let epIndex = 0; epIndex < episodes.length; epIndex++) {\n const episode = episodes[epIndex]!;\n if (!isDict(episode)) continue;\n const epNum =\n episodeNumberFromValue(episode[\"episode_id\"]) ||\n episodeNumberFromValue(episode[\"episode\"]) ||\n episodeNumberFromValue(episode[\"id\"]) ||\n epIndex + 1;\n const rawEpTitle = strOf(episode[\"title\"]).trim();\n let epShortTitle = cleanEpisodeShortTitle(rawEpTitle);\n if (isTechnicalEpisodeTitle(rawEpTitle)) epShortTitle = \"\";\n parts.push(epShortTitle ? `\\n\u7B2C${epNum}\u96C6\uFF1A${epShortTitle}` : `\\n\u7B2C${epNum}\u96C6`);\n const scenes = asList<Dict>(episode[\"scenes\"]);\n for (let sceneIndex = 0; sceneIndex < scenes.length; sceneIndex++) {\n const scene = scenes[sceneIndex]!;\n if (!isDict(scene)) continue;\n const locName = firstRefName(scene[\"locations\"], locations, \"location_id\") || \"\u672A\u77E5\u573A\u666F\";\n parts.push(`${epNum}-${sceneIndex + 1} \u65E5 \u5185 ${locName}`);\n const actorNames = refNames(scene[\"actors\"], actors, \"actor_id\");\n if (actorNames.length > 0) parts.push(`\u4EBA\u7269\uFF1A${actorNames.join(\"\u3001\")}`);\n const propNames = refNames(scene[\"props\"], props, \"prop_id\");\n if (propNames.length > 0) parts.push(`\u9053\u5177\uFF1A${propNames.join(\"\u3001\")}`);\n for (const action of asList<Dict>(scene[\"actions\"])) {\n if (!isDict(action)) continue;\n const content = strOf(action[\"content\"]).trim();\n if (!content) continue;\n const actorName = actors.get(strOf(action[\"actor_id\"]).trim()) ?? \"\";\n if (action[\"type\"] === \"dialogue\" && actorName) {\n parts.push(`${actorName}\uFF1A${content}`);\n } else {\n parts.push(content);\n }\n }\n }\n }\n return [parts.join(\"\\n\").trim() + \"\\n\", false, \"script\"];\n}\n\n// ---------------------------------------------------------------------------\n// Source preparation\n// ---------------------------------------------------------------------------\n\nexport async function prepareSource(sourcePath: string, workspace: string): Promise<Dict> {\n const ext = path.extname(sourcePath).toLowerCase();\n let content: string;\n let hasStoryboard = false;\n let explicitMode: string | null = null;\n if (ext === \".txt\" || ext === \".md\") {\n content = convertTxt(sourcePath);\n } else if (ext === \".json\") {\n const [text, sb, mode] = await convertJson(sourcePath);\n content = text;\n hasStoryboard = sb;\n explicitMode = mode;\n } else if (ext === \".docx\") {\n const [text, sb] = await convertDocx(sourcePath);\n content = text;\n hasStoryboard = sb;\n } else if (ext === \".xlsx\") {\n content = await convertXlsx(sourcePath);\n } else {\n throw new Error(`Unsupported file format: ${ext}`);\n }\n const sourceTextPath = path.join(workspace, \"source.txt\");\n writeText(sourceTextPath, content);\n const mode = explicitMode || (hasStoryboard ? \"storyboard\" : \"script\");\n return {\n projectName: path.basename(sourcePath, ext),\n projectPath: path.resolve(workspace),\n originalSourcePath: path.resolve(sourcePath),\n sourceTextPath: path.resolve(sourceTextPath),\n format: ext,\n mode,\n chars: Array.from(content).length,\n };\n}\n\nexport function makeSourceManifest(sourcePath: string, sourceTextPath: string, info: Dict): Dict {\n const text = readText(sourceTextPath);\n const lineStarts: number[] = [];\n let cursor = 0;\n // Mirror Python splitlines(keepends=True)\n const rawLines: string[] = [];\n let start = 0;\n let i = 0;\n while (i < text.length) {\n const ch = text[i];\n if (ch === \"\\n\") {\n rawLines.push(text.slice(start, i + 1));\n i += 1;\n start = i;\n } else if (ch === \"\\r\") {\n if (text[i + 1] === \"\\n\") {\n rawLines.push(text.slice(start, i + 2));\n i += 2;\n } else {\n rawLines.push(text.slice(start, i + 1));\n i += 1;\n }\n start = i;\n } else {\n i += 1;\n }\n }\n if (start < text.length) rawLines.push(text.slice(start));\n for (const raw of rawLines) {\n lineStarts.push(cursor);\n cursor += raw.length;\n }\n const linesNoEnd = text.split(/\\r\\n|\\r|\\n/);\n if (text.endsWith(\"\\n\") || text.endsWith(\"\\r\")) linesNoEnd.pop();\n return {\n version: 1,\n source_path: path.resolve(sourcePath),\n source_name: path.basename(sourcePath),\n source_ext: path.extname(sourcePath).toLowerCase(),\n source_sha256: sha256File(sourcePath),\n source_text_path: path.resolve(sourceTextPath),\n source_text_sha256: sha256Text(text),\n chars: text.length,\n lines: linesNoEnd.length,\n line_starts: lineStarts,\n prepare: {\n mode: info[\"mode\"],\n format: info[\"format\"],\n chars: info[\"chars\"],\n },\n };\n}\n\n// suppress unused warnings on Node Buffer/Uint8Array helpers\nvoid os;\n", "// Ingest workspace store (\u00A75/\u00A712.4). Owns the on-disk workspace: atomic writes\n// (same-dir temp + fsync + rename), pass directories, manifest and run_state.\n// All JSON is written atomically so a crash never leaves a half-written product.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nexport function atomicWrite(filePath: string, data: string | Buffer): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(filePath)}.${process.pid}.tmp`);\n const fd = fs.openSync(tmp, \"w\");\n try {\n fs.writeFileSync(fd, data);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n fs.renameSync(tmp, filePath);\n}\n\nexport function writeJson(filePath: string, value: unknown): void {\n atomicWrite(filePath, JSON.stringify(value, null, 2) + \"\\n\");\n}\n\nexport function readJson<T = unknown>(filePath: string): T {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as T;\n}\n\nexport function exists(filePath: string): boolean {\n return fs.existsSync(filePath);\n}\n\nexport class WorkspaceStore {\n constructor(readonly root: string) {}\n\n private abs(rel: string): string {\n return path.join(this.root, rel);\n }\n\n ensure(): void {\n fs.mkdirSync(this.root, { recursive: true });\n }\n\n passDir(name: string): string {\n const dir = this.abs(name);\n fs.mkdirSync(dir, { recursive: true });\n return dir;\n }\n\n readText(rel: string): string {\n return fs.readFileSync(this.abs(rel), \"utf-8\");\n }\n\n writeText(rel: string, data: string): void {\n atomicWrite(this.abs(rel), data);\n }\n\n writeJson(rel: string, value: unknown): void {\n writeJson(this.abs(rel), value);\n }\n\n readJson<T = unknown>(rel: string): T {\n return readJson<T>(this.abs(rel));\n }\n\n has(rel: string): boolean {\n return fs.existsSync(this.abs(rel));\n }\n\n path(rel: string): string {\n return this.abs(rel);\n }\n\n // Remove a unit's stale error sidecar after it succeeds (\u00A75.3).\n clearError(rel: string): void {\n const p = this.abs(rel);\n if (fs.existsSync(p)) fs.rmSync(p);\n }\n}\n", "// ingest.text-normalize task (\u00A73.3/\u00A7pass2). The cheap model converts one source\n// chunk directly into structured records. Source spans are assigned locally at\n// chunk granularity; the model never supplies or guesses them.\n\nimport { CliError, EXIT_RUNTIME } from \"../../../common.js\";\nimport type { Chunk } from \"../../../domain/ingest/chunker.js\";\nimport { JsonlParseError, parseJsonl } from \"../../../domain/ingest/jsonl-parser.js\";\nimport type { IngestRecord, SourceSpan } from \"../../../domain/ingest/records.js\";\nimport type { LlmTaskExecutor } from \"../../types.js\";\n\nexport const TEXT_NORMALIZE_SYSTEM = [\n \"\u4F60\u662F\u5267\u672C\u89C4\u8303\u5316\u5668\u3002\u628A\u7ED9\u5B9A\u7684\u6E90\u6587\u672C\u5757\u8F6C\u6362\u6210\u7ED3\u6784\u5316\u5267\u672C\u8BB0\u5F55\u3002\",\n \"\u6700\u9AD8\u4F18\u5148\u7EA7\u662F\u6B63\u6587\u96F6\u4E22\u5931\uFF1A\u539F\u6587\u4E2D\u7684\u6BCF\u4E00\u6761\u52A8\u4F5C\u3001\u73AF\u5883\u63CF\u5199\u3001\u5BF9\u767D\u3001\u5185\u5FC3\u72EC\u767D\u3001\u753B\u5916\u97F3\u3001\u5B57\u5E55\u548C\u8F6C\u573A\u90FD\u5FC5\u987B\u5B8C\u6574\u8FDB\u5165 records\u3002\u7981\u6B62\u56E0\u5185\u5BB9\u91CD\u590D\u3001\u6B21\u8981\u3001\u8FC7\u6E21\u6027\u5F3A\u3001\u7BC7\u5E45\u957F\u3001\u4F7F\u7528\u5916\u8BED\u6216\u96BE\u4EE5\u5206\u7C7B\u800C\u7701\u7565\u3002\",\n \"\u9010\u884C\u5904\u7406\u539F\u6587\uFF0C\u5E76\u5728\u8F93\u51FA\u524D\u9010\u884C\u81EA\u68C0\u6B63\u6587\u662F\u5426\u5168\u90E8\u627F\u8F7D\u3002\u4E00\u4E2A\u539F\u6587\u6BB5\u843D\u542B\u591A\u53E5\u65F6\u5FC5\u987B\u4FDD\u7559\u5168\u90E8\u53E5\u5B50\uFF1B\u53EF\u4EE5\u62C6\u6210\u591A\u6761\u8BB0\u5F55\uFF0C\u4F46\u7981\u6B62\u622A\u65AD\u3001\u6458\u8981\u3001\u5408\u5E76\u540E\u6F0F\u53E5\u6216\u53EA\u4FDD\u7559\u6BB5\u843D\u524D\u534A\u6BB5\u3002\u52A8\u4F5C\u7FFB\u8BD1\u53EA\u80FD\u6539\u53D8\u8868\u8FBE\u8BED\u8A00\uFF0C\u4E0D\u80FD\u51CF\u5C11\u4E8B\u5B9E\u3002\u4E0D\u8981\u8F93\u51FA\u81EA\u68C0\u8FC7\u7A0B\u3002\",\n \"\u8FD9\u662F\u4F9B\u4E2D\u6587\u7F16\u5267\u590D\u6838\u7684\u6807\u51C6\u7A3F\uFF1Adialogue \u548C inner_thought \u7684 content \u9010\u5B57\u4FDD\u7559\u6E90\u6587\u672C\u5B9E\u9645\u8BED\u8A00\u4E0E\u5939\u6742\u8BED\u8A00\uFF0C\u7EDD\u4E0D\u7FFB\u8BD1\uFF1B\u9664\u6B64\u4EE5\u5916\uFF0Caction\u3001transition\u3001note\u3001emotion \u4EE5\u53CA\u573A\u666F\u7684\u901A\u7528\u5730\u70B9\u63CF\u8FF0\u90FD\u4F7F\u7528\u81EA\u7136\u3001\u51C6\u786E\u7684\u7B80\u4F53\u4E2D\u6587\u3002\u4EBA\u7269\u59D3\u540D\u5728 speaker.name\u3001scene.actors\u3001action \u548C\u540E\u7EED\u8D44\u4EA7\u767B\u8BB0\u4E2D\u90FD\u5FC5\u987B\u6CBF\u7528\u6E90\u6587\u672C\u7684\u539F\u59CB\u62FC\u5199\uFF0C\u4E0D\u7FFB\u8BD1\u3001\u4E0D\u97F3\u8BD1\u3001\u4E0D\u6539\u6210\u4E2D\u6587\u540D\uFF1B\u54C1\u724C\u548C\u6CA1\u6709\u901A\u884C\u8BD1\u540D\u7684\u5176\u4ED6\u4E13\u540D\u4FDD\u7559\u539F\u6587\u3002\u4E0D\u5F97\u628A\u6574\u53E5\u5916\u8BED\u52A8\u4F5C\u6216\u73AF\u5883\u63CF\u8FF0\u539F\u6837\u7559\u5728 action \u4E2D\u3002\",\n \"\u53EA\u8F93\u51FA\u4E00\u4E2A\u6807\u51C6 JSON \u5BF9\u8C61\uFF0C\u683C\u5F0F\u5FC5\u987B\u662F {\\\"records\\\":[...]}\u3002\u5FC5\u987B\u4F7F\u7528\u53CC\u5F15\u53F7\uFF0C\u4E0D\u8981 Markdown\u3001\u4EE3\u7801\u56F4\u680F\u3001JSONL\u3001\u6CE8\u91CA\u6216\u89E3\u91CA\u3002\",\n \"records \u6309\u6E90\u6587\u672C\u53D1\u751F\u987A\u5E8F\u6392\u5217\uFF0C\u53EA\u653E\u6E90\u6587\u672C\u4E2D\u5B9E\u9645\u5B58\u5728\u7684\u5185\u5BB9\uFF1B\u4E0D\u8981\u81C6\u9020\u8FB9\u754C\uFF0C\u4E0D\u8981\u63D0\u4F9B source \u5B57\u6BB5\u3002\",\n \"\",\n \"\u4E25\u683C\u4FDD\u6301\u6E90\u6587\u672C\u987A\u5E8F\uFF0C\u7EDD\u4E0D\u91CD\u6392\uFF1A\u5757\u5F00\u5934\u82E5\u5728\u4EFB\u4F55\u300E\u96C6/\u573A\u300F\u6807\u8BB0\u4E4B\u524D\u5C31\u6709\u6B63\u6587\uFF08\u4E0A\u4E00\u5757\u6CA1\u5199\u5B8C\u7684\u620F\uFF09\uFF0C\",\n \"\u5FC5\u987B\u628A\u8FD9\u4E9B\u6B63\u6587\u539F\u4F4D\u653E\u5728 records \u6700\u524D\u9762\uFF1Bepisode \u53EA\u5728\u6E90\u6587\u672C\u660E\u786E\u96C6\u8FB9\u754C\u5904\u5199\u5165\u3002\u6807\u51C6\u5267\u672C\u6CBF\u7528\u539F\u6709\u573A\u754C\uFF1B\u5C0F\u8BF4\u548C\u975E\u6807\u51C6\u6587\u672C\u4F9D\u636E\u5730\u70B9\u5207\u6362\u3001\u660E\u663E\u8DF3\u65F6\u3001\u53D9\u4E8B\u7EBF\u5207\u6362\u3001\u660E\u786E\u8F6C\u573A\u6216\u6301\u4E45\u89C6\u89C9\u72B6\u6001\u53D8\u5316\u5EFA\u7ACB scene\u3002\",\n \"\u7EDD\u4E0D\u8981\u628A\u9760\u540E\u51FA\u73B0\u7684\u96C6\u8FB9\u754C\u63D0\u5230\u5F00\u5934\u3002\",\n \"\u573A\u53F7\uFF08\u5982 `\u573A3-2`\uFF09\u7EDD\u4E0D\u662F\u96C6\u8FB9\u754C\uFF1B\u53EA\u6709\u539F\u6587\u660E\u786E\u5199\u51FA `\u7B2CN\u96C6` \u6216 `N\u96C6` \u65F6\u624D\u80FD\u8F93\u51FA episode\u3002\",\n \"\",\n \"\u8BB0\u5F55\u7C7B\u578B\uFF1A\",\n \"- \u96C6\u8FB9\u754C\uFF1A{\\\"kind\\\":\\\"episode\\\",\\\"episode\\\":19,\\\"title\\\":\\\"\u53EF\u9009\u6807\u9898\\\"}\u3002episode \u5FC5\u987B\u53D6\u6E90\u6587\u672C\u5199\u660E\u7684\u96C6\u53F7\uFF1B\u4E66\u540D\u3001\u62EC\u53F7\u3001\u6807\u9898\u6587\u5B57\u90FD\u4E0D\u80FD\u6DF7\u8FDB episode\u3002\",\n \"- \u573A\u8FB9\u754C\uFF1A{\\\"kind\\\":\\\"scene\\\",\\\"environment\\\":{\\\"space\\\":\\\"interior\\\",\\\"time\\\":\\\"day\\\"},\\\"location\\\":{\\\"name\\\":\\\"\u5BA2\u5385\\\"},\\\"actors\\\":[],\\\"props\\\":[]}\u3002\u4E0D\u8981\u8F93\u51FA scene \u7F16\u53F7\u5B57\u6BB5\uFF0C\u7CFB\u7EDF\u4F1A\u81EA\u884C\u8FDE\u7EED\u7F16\u53F7\u3002\u6BCF\u4E2A scene \u90FD\u5FC5\u987B\u586B\u5199 environment.time\uFF0C\u53EA\u80FD\u4F7F\u7528 day|night|dawn|dusk\uFF1B\u4F9D\u6B21\u5BF9\u5E94\u65E5/\u591C/\u6668/\u660F\u3002\",\n \"- \u52A8\u4F5C/\u73AF\u5883\uFF1A{\\\"kind\\\":\\\"action\\\",\\\"content\\\":\\\"\u5FE0\u5B9E\u8F6C\u6362\u6210\u7B80\u4F53\u4E2D\u6587\u7684\u53EF\u62CD\u6444\u63CF\u8FF0\\\"}\u3002\",\n \"- \u5BF9\u767D\uFF1A{\\\"kind\\\":\\\"dialogue\\\",\\\"speaker\\\":{\\\"name\\\":\\\"\u7532\\\"},\\\"content\\\":\\\"\u539F\u8BDD\\\",\\\"emotion\\\":\\\"\u53EF\u9009\\\"}\u3002\",\n \"- \u5185\u5FC3\u72EC\u767D/\u753B\u5916\u97F3\uFF1A{\\\"kind\\\":\\\"inner_thought\\\",\\\"speaker\\\":{\\\"name\\\":\\\"\u7532\\\"},\\\"content\\\":\\\"\u539F\u8BDD\\\",\\\"emotion\\\":\\\"\u53EF\u9009\\\"}\u3002\",\n \"- \u8F6C\u573A\uFF1A{\\\"kind\\\":\\\"transition\\\",\\\"content\\\":\\\"\u5FE0\u5B9E\u8F6C\u6362\u6210\u7B80\u4F53\u4E2D\u6587\u7684\u8F6C\u573A\u6587\u5B57\\\"}\u3002\u5E38\u89C1\u683C\u5F0F\u8BCD\u4E5F\u8981\u7FFB\u8BD1\uFF0C\u4F8B\u5982 `FLASHBACK` \u2192 `\u95EA\u56DE`\u3001`BACK TO PRESENT` \u2192 `\u56DE\u5230\u73B0\u5B9E`\u3002\",\n \"- \u6279\u6CE8\uFF1A{\\\"kind\\\":\\\"note\\\",\\\"content\\\":\\\"\u5FE0\u5B9E\u8F6C\u6362\u6210\u7B80\u4F53\u4E2D\u6587\u7684\u6279\u6CE8\\\",\\\"category\\\":\\\"author_note|format_note|unclassified\\\"}\u3002\",\n \"action\u3001dialogue\u3001inner_thought\u3001transition\u3001note \u7684 content \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF1B\u4E0D\u5F97\u8F93\u51FA content \u4E3A\u7A7A\u7684\u5360\u4F4D\u8BB0\u5F55\u3002\u539F\u6587\u6CA1\u6709\u5BF9\u5E94\u6B63\u6587\u65F6\u5C31\u4E0D\u8981\u521B\u5EFA\u8BE5\u8BB0\u5F55\u3002\",\n \"\",\n \"\u8F6C\u6362\u89C4\u5219\uFF1A\",\n \" \u6E90 `\u573A3-2 \u65E5/\u5185 \u5BA2\u5385` \u2192 \u4E00\u4E2A scene\uFF1Bspace \u53EA\u7528 interior/exterior\uFF0Ctime \u53EA\u7528 day/night/dawn/dusk\u3002\u767D\u5929/\u65E5\u95F4\u5F52 day\uFF0C\u591C\u665A/\u591C\u95F4\u5F52 night\uFF0C\u6E05\u6668/\u9ECE\u660E\u5F52 dawn\uFF0C\u9EC4\u660F/\u508D\u665A\u5F52 dusk\u3002\u539F\u6587\u672A\u76F4\u63A5\u5199\u660E\u65F6\uFF0C\u6839\u636E\u7167\u660E\u3001\u4F5C\u606F\u3001\u5929\u7A7A\u548C\u4E0A\u4E0B\u6587\u5224\u65AD\uFF1B\u4E0D\u5F97\u7701\u7565\u6216\u5199\u7A7A\u4E32\u3002\",\n \" \u6E90 `\u4EBA\u7269\uFF1A\u7532\u3010\u767D\u8863,\u660F\u8FF7\u3011\uFF0C\u4E59` \u2192 scene.actors=[{\\\"name\\\":\\\"\u7532\\\",\\\"state\\\":\\\"\u767D\u8863,\u660F\u8FF7\\\"},{\\\"name\\\":\\\"\u4E59\\\"}]\u3002\",\n \" \u6E90 `\u9053\u5177\uFF1A\u5A5A\u4E66\uFF0C\u7389\u4F69` \u2192 scene.props=[{\\\"name\\\":\\\"\u5A5A\u4E66\\\"},{\\\"name\\\":\\\"\u7389\u4F69\\\"}]\u3002\",\n \" \u6E90 `\u25B3 \u7532\u63A8\u95E8\u800C\u5165\u3002` \u2192 action\uFF0Ccontent \u53BB\u6389\u683C\u5F0F\u524D\u7F00 `\u25B3`\u3002\",\n \" \u6E90 `\u7532\uFF1A\u4F60\u6765\u4E86` \u2192 dialogue\u3002\u6E90 `\u7532\uFF08\u51B7\u7B11\uFF09\uFF1A\u4F60\u6765\u4E86` \u2192 dialogue.emotion \u4E3A `\u51B7\u7B11`\u3002\",\n \" \u6E90 `\u7532OS\uFF1A\uFF08\u6050\u614C\uFF09\u4ED6\u6CA1\u6B7B\u5427\uFF1F` \u2192 inner_thought.emotion \u4E3A `\u6050\u614C`\u3002\",\n \" \u6E90 `\u3010\u5B57\u5E55\uFF1A\u56DE\u95E8\u65E5\u3011` \u2192 action\uFF1B\u753B\u9762\u6587\u5B57\u5C5E\u4E8E\u753B\u9762\u5185\u5BB9\u3002\",\n \" \u8461\u8BED\u52A8\u4F5C `Richard avan\u00E7a, agarra Emily pela roupa e a puxa para cima.` \u2192 action.content=`Richard\u4E0A\u524D\u6293\u4F4FEmily\u7684\u8863\u670D\uFF0C\u628A\u5979\u62FD\u4E86\u8D77\u6765\u3002`\u3002\",\n \" \u8461\u8BED\u52A8\u4F5C `Um prato de oferendas cai da mesa e se espalha pelo ch\u00E3o.` \u2192 action.content=`\u4E00\u76D8\u4F9B\u54C1\u4ECE\u684C\u4E0A\u6389\u843D\uFF0C\u6563\u843D\u4E00\u5730\u3002`\u3002\u4EBA\u7269\u8BF4\u51FA\u7684\u8461\u8BED\u5BF9\u767D\u4ECD\u9010\u5B57\u4FDD\u7559\uFF0C\u4E0D\u7FFB\u8BD1\uFF1BRichard\u3001Emily \u7B49\u4EBA\u7269\u540D\u59CB\u7EC8\u4FDD\u6301\u539F\u6587\u62FC\u5199\u3002\",\n \" \u540C\u4E00\u53E5\u7531\u591A\u4EBA\u540C\u65F6\u8BF4\u65F6\uFF0C\u4E3A\u6BCF\u4E2A\u8BF4\u8BDD\u4EBA\u5404\u5199\u4E00\u6761\u76F8\u90BB dialogue\uFF0Ccontent \u76F8\u540C\u3002\",\n \"\",\n \"\u6BCF\u79CD\u8BB0\u5F55\u53EA\u80FD\u4F7F\u7528\u4E0A\u9762\u5217\u51FA\u7684\u5B57\u6BB5\uFF0C\u7981\u6B62\u589E\u52A0 name\u3001text\u3001line\u3001episode_title \u7B49\u81EA\u521B\u5B57\u6BB5\u3002\",\n \"\u6B63\u6587\u53E3\u5F84\uFF1Adialogue\u3001inner_thought \u7684 content \u9010\u5B57\u5B8C\u6574\u4FDD\u7559\uFF0C\u4E0D\u6DA6\u8272\u3001\u4E0D\u6269\u5199\u3001\u4E0D\u7EA0\u9519\u3001\u4E0D\u7FFB\u8BD1\u3002action\u3001transition\u3001note \u548C emotion \u5FE0\u5B9E\u8F6C\u6362\u6210\u7B80\u4F53\u4E2D\u6587\uFF1B\u7FFB\u8BD1\u4E0D\u5F97\u6539\u53D8\u3001\u5220\u51CF\u6216\u8865\u9020\u539F\u6587\u4E8B\u5B9E\u3001\u56E0\u679C\u3001\u987A\u5E8F\u3001\u52A8\u4F5C\u7ED3\u679C\u3001\u4EBA\u7269\u72B6\u6001\u4EE5\u53CA\u5DF2\u6709\u7684\u673A\u4F4D\u3001\u666F\u522B\u548C\u955C\u5934\u8FD0\u52A8\u3002\u5C0F\u8BF4\u53D9\u8FF0\u8F6C\u6362\u4E3A\u53EF\u76F4\u63A5\u62CD\u6444\u7684 action \u65F6\u9075\u5B88\u540C\u4E00\u8FB9\u754C\u3002\u4EBA\u7269/\u9053\u5177\u7684\u5728\u573A\u53EA\u5199\u5728 scene \u7684 actors/props\u3002\",\n \"action \u76F4\u63A5\u5199\u5177\u4F53\u4EBA\u7269\u540D\uFF0C\u660E\u786E\u884C\u52A8\u8005\u3001\u52A8\u4F5C\u3001\u4F5C\u7528\u5BF9\u8C61\u3001\u7A7A\u95F4\u65B9\u5411\u548C\u53EF\u89C1\u7ED3\u679C\uFF1B\u591A\u4E2A\u5148\u540E\u53D1\u751F\u7684\u52A8\u4F5C\u3001\u53CD\u5E94\u3001\u63A5\u89E6\u3001\u9053\u5177\u53D8\u5316\u6216\u955C\u5934\u53D8\u5316\u6309\u539F\u6587\u987A\u5E8F\u5206\u522B\u627F\u8F7D\uFF0C\u4E0D\u538B\u6210\u5267\u60C5\u6982\u8FF0\u3002\u8EAB\u4EFD\u660E\u786E\u65F6\u6D88\u89E3\u4EE3\u8BCD\uFF0C\u65E0\u6CD5\u786E\u8BA4\u65F6\u4FDD\u6301\u53EF\u6838\u67E5\u63CF\u8FF0\uFF0C\u4E0D\u731C\u6D4B\u3002\u53EA\u7528\u539F\u6587\u660E\u786E\u5199\u51FA\u7684\u8868\u60C5\u3001\u89C6\u7EBF\u3001\u80A2\u4F53\u3001\u9053\u5177\u6216\u73AF\u5883\u53CD\u5E94\u8868\u8FBE\u72B6\u6001\uFF0C\u4E0D\u7528\u60C5\u7EEA\u3001\u6001\u5EA6\u6216\u5FC3\u7406\u5224\u65AD\u66FF\u4EE3\u53EF\u89C1\u4E8B\u5B9E\u3002\",\n \"location \u662F\u53EF\u72EC\u7ACB\u5E03\u7F6E\u548C\u91CD\u590D\u5F15\u7528\u7684\u7A33\u5B9A\u7269\u7406\u7A7A\u95F4\uFF1B\u4EBA\u7269\u8DE8\u95E8\u69DB\u8FDB\u5165\u53E6\u4E00\u7A7A\u95F4\u3001\u955C\u5934\u5207\u5230\u53E6\u4E00\u7A7A\u95F4\u3001\u660E\u663E\u8DF3\u65F6\u3001\u5207\u6362\u53D9\u4E8B\u7EBF\u6216\u539F\u6587\u660E\u786E\u8F6C\u573A\u65F6\u5EFA\u7ACB scene\uFF0C\u4E00\u4E2A scene \u53EA\u5199\u4E00\u4E2A\u4E3B location\u3002\u540C\u4E00\u8FDE\u7EED\u573A\u5185\u7684\u4EBA\u7269\u8FDB\u51FA\u3001\u60C5\u7EEA\u5347\u7EA7\u3001\u653B\u9632\u56DE\u5408\u3001\u6362\u88C5\u3001\u8131\u8863\u3001\u5730\u70B9\u53D7\u635F\u6216\u9053\u5177\u5F62\u6001\u53D8\u5316\u672C\u8EAB\u4E0D\u6784\u6210\u65B0 scene\uFF1B\u628A\u53D8\u5316\u8FC7\u7A0B\u5199\u5165 action\uFF0C\u540E\u7EED\u8D44\u4EA7\u6CBB\u7406\u4F1A\u7EF4\u62A4\u6301\u4E45 state\u3002\",\n \"\u540C\u5730\u70B9\u8FDE\u7EED\u8499\u592A\u5947\u4FDD\u7559\u4E00\u4E2A scene \u5E76\u7528 transition\uFF1B\u8DE8\u5730\u70B9\u8499\u592A\u5947\u6309\u526A\u8F91\u987A\u5E8F\u62C6\u6210\u591A\u4E2A scene\uFF0C\u6BCF\u573A\u586B\u5199\u81EA\u5DF1\u7684 location\u3001actors\u3001props \u548C state\u3002\",\n \"\u4EBA\u7269\u53EA\u5217\u5177\u4F53\u5355\u4EBA\u89D2\u8272\uFF1B\u5BB6\u65CF/\u673A\u6784/\u7FA4\u4F53/\u6CDB\u79F0\u4E0D\u5217\u5165 actors\u3002\u7FA4\u4F53\u558A\u8BDD\u7684 speaker \u7528 {\\\"kind\\\":\\\"group\\\"}\u3002\",\n \"\u975E\u4EBA\u7269\u53D1\u58F0\u6E90\u7684 speaker.kind \u53EA\u7528 system|broadcast|offscreen|group\uFF0C\u53EF\u7528 label \u8865\u5145\u540D\u79F0\uFF1B\u5177\u4F53\u4EBA\u7269\u59CB\u7EC8\u7528 speaker.name\u3002\",\n \"speaker.name \u5FC5\u987B\u586B\u5199\u539F\u6587\u4E2D\u80FD\u786E\u8BA4\u7684\u5177\u4F53\u4EBA\u7269\u540D\u5B57\u5E76\u4FDD\u6301\u539F\u59CB\u62FC\u5199\uFF1Bscene.actors \u4E0E action \u4E2D\u518D\u6B21\u51FA\u73B0\u8BE5\u4EBA\u7269\u65F6\u4F7F\u7528\u540C\u4E00\u62FC\u5199\u3002\u7981\u6B62\u7FFB\u8BD1\u3001\u97F3\u8BD1\u3001\u4E2D\u6587\u5316\u4EBA\u7269\u540D\uFF0C\u4E5F\u7981\u6B62\u7528\u300E\uFF1F\u300F\u300E\uFF1F\uFF1F\u300F\u300E\u672A\u77E5\u300F\u300Eunknown\u300F\u7B49\u5360\u4F4D\u540D\uFF1B\u8EAB\u4EFD\u65E0\u6CD5\u786E\u8BA4\u65F6\u6539\u7528 speaker.kind=offscreen\uFF0C\u7FA4\u4F53\u5171\u540C\u53D1\u58F0\u7528 group\u3002\",\n \"\u6BCF\u6761 dialogue \u53EA\u5728\u539F\u6587\u660E\u786E\u7ED9\u51FA\u65F6\uFF0C\u624D\u628A\u53D1\u58F0\u65B9\u5F0F\u3001\u58F0\u97F3\u6765\u6E90\u6216\u4E0D\u6539\u53D8\u8FDE\u7EED\u6027\u7684\u77ED\u4FC3\u4F34\u968F\u52A8\u4F5C\u8F6C\u6362\u6210\u7B80\u4F53\u4E2D\u6587 emotion\uFF1B\u5F71\u54CD\u8D70\u4F4D\u3001\u59FF\u52BF\u3001\u63A5\u89E6\u3001\u9053\u5177\u6216\u8FDE\u7EED\u6027\u7684\u52A8\u4F5C\u5355\u72EC\u5199 action\u3002\u539F\u6587\u6CA1\u6709\u8868\u6F14\u6216\u58F0\u97F3\u8BC1\u636E\u65F6\u7701\u7565 emotion\uFF0C\u4E0D\u6309\u8BED\u5883\u8865\u9020\u3002\",\n \"note \u53EA\u7528\u4E8E\u771F\u6B63\u65E0\u6CD5\u5F52\u5165\u5267\u672C\u3001\u4E5F\u4E0D\u5C5E\u4E8E\u753B\u9762/\u5BF9\u767D\u7684\u5185\u5BB9\u3002\u6E90\u6587\u672C\u5757\u7684\u5B9E\u8D28\u5185\u5BB9\u4E0D\u5F97\u4E22\u5931\u3002\",\n].join(\"\\n\");\n\nexport function buildNormalizeUser(chunk: Chunk): string {\n // Do NOT expose the chunk index \u2014 the model conflates a chunk number with an\n // episode number. Chunk source spans are assigned by the parser, not the model.\n const position = chunk.index === 0\n ? \"\u8FD9\u662F\u6E90\u6587\u4EF6\u5F00\u5934\uFF1B\u5C0F\u8BF4\u6216\u975E\u6807\u51C6\u6587\u672C\u4ECE\u7B2C\u4E00\u4E2A\u53EF\u786E\u8BA4\u7684\u7269\u7406\u7A7A\u95F4\u5EFA\u7ACB\u9996\u573A\u3002\"\n : \"\u8FD9\u4E2A\u7247\u6BB5\u53EF\u80FD\u627F\u63A5\u4E0A\u4E00\u7247\u6BB5\u7684\u540C\u4E00\u573A\uFF1B\u53EA\u6709\u6E90\u6587\u672C\u51FA\u73B0\u771F\u5B9E\u573A\u754C\u65F6\u624D\u5EFA\u7ACB\u65B0\u573A\u3002\";\n return [\n \"\u3010\u5F85\u89C4\u8303\u5316\u7684\u539F\u6587\u7247\u6BB5\u3011\",\n position,\n \"\u4EE5\u4E0B\u6B63\u6587\u5FC5\u987B\u9010\u884C\u3001\u9010\u53E5\u5B8C\u6574\u8FDB\u5165 records\uFF1A\u5BF9\u767D\u548C\u5185\u5FC3\u72EC\u767D\u9010\u5B57\u4FDD\u7559\u539F\u8BED\u8A00\uFF1B\u52A8\u4F5C\u3001\u73AF\u5883\u3001\u8F6C\u573A\u3001\u6279\u6CE8\u548C\u8868\u6F14\u63D0\u793A\u5FE0\u5B9E\u8F6C\u6362\u6210\u7B80\u4F53\u4E2D\u6587\uFF1B\u4EBA\u7269\u540D\u5728\u6240\u6709\u8BB0\u5F55\u4E2D\u4FDD\u6301\u539F\u6587\u62FC\u5199\uFF0C\u4E0D\u7FFB\u8BD1\u3001\u4E0D\u97F3\u8BD1\u3002\u4E0D\u5F97\u9057\u6F0F\u3001\u6458\u8981\u3001\u622A\u65AD\u6216\u8865\u9020\u3002\u8F93\u51FA\u524D\u8BF7\u81EA\u884C\u6838\u5BF9\u6BCF\u4E00\u884C\uFF0C\u4E14\u4E0D\u8981\u8F93\u51FA\u6838\u5BF9\u8FC7\u7A0B\u3002\",\n \"\",\n chunk.text,\n ].join(\"\\n\");\n}\n\nfunction runtimeError(message: string, received: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_RUNTIME,\n errorCode: \"INGEST_NORMALIZE_FAILED\",\n hint: \"Inspect the chunk error sidecar and rerun `scriptctl ingest`.\",\n data: { actual: received },\n });\n}\n\ntype NormalizeOutput = { records: unknown[] };\n\nfunction isNormalizeOutput(input: unknown): input is NormalizeOutput {\n if (typeof input !== \"object\" || input === null || Array.isArray(input)) return false;\n return Object.keys(input).length === 1 && \"records\" in input && Array.isArray(input.records);\n}\n\n// Validate provider output with the same strict parser used by the merged JSONL.\n// The model owns record semantics; the pipeline owns the trusted source span.\nexport function parseNormalizeOutput(input: unknown, chunk: Chunk): IngestRecord[] {\n if (!isNormalizeOutput(input)) {\n throw runtimeError(`chunk ${chunk.index}: output must be an object containing only records[]`, [\"invalid structured output\"]);\n }\n const source: SourceSpan = { chunk: chunk.index, line_start: chunk.core_line_start, line_end: chunk.core_line_end };\n let records: IngestRecord[];\n try {\n const jsonl = input.records.map((record) => {\n if (typeof record !== \"object\" || record === null || Array.isArray(record) || Object.hasOwn(record, \"source\")) {\n throw new JsonlParseError(\"record must be an object without source\", 1);\n }\n return JSON.stringify({ ...record, source });\n }).join(\"\\n\");\n records = parseJsonl(jsonl);\n } catch (error) {\n if (error instanceof JsonlParseError) throw runtimeError(`chunk ${chunk.index}: ${error.message}`, [error.message]);\n throw error;\n }\n if (records.length === 0 && chunk.text.trim() !== \"\") {\n throw runtimeError(`chunk ${chunk.index}: non-empty chunk produced no records`, [\"records: 0\"]);\n }\n return records;\n}\n\nexport async function runTextNormalize(\n executor: LlmTaskExecutor,\n chunk: Chunk,\n signal?: AbortSignal,\n): Promise<{ raw: string; records: IngestRecord[] }> {\n const response = await executor.generateText(\"ingest.text-normalize\", {\n system: TEXT_NORMALIZE_SYSTEM,\n user: buildNormalizeUser(chunk),\n responseFormat: \"json_object\",\n ...(signal ? { signal } : {}),\n });\n let input: unknown;\n try {\n input = JSON.parse(response.text) as unknown;\n } catch {\n throw runtimeError(`chunk ${chunk.index}: provider returned invalid JSON`, [response.text.slice(0, 500)]);\n }\n return { raw: response.text, records: parseNormalizeOutput(input, chunk) };\n}\n", "// Body-start classifier. A one-piece txt often carries planning front matter\n// before the actual screenplay: \u9879\u76EE\u5927\u7EB2 / \u89D2\u8272\u5361 / \u5B8F\u89C2\u7ED3\u6784 / \u4E00\u5361\u96C6\u7EB2. Those\n// pages normalize into stray scenes/episodes (a scene before any episode crashes\n// assemble; \u96C6\u7EB2 summaries inflate the episode count). This task judges a numbered\n// window of source lines and, if the real screenplay body begins within it,\n// reports that line number. The pipeline scans windows forward until one hits.\n//\n// Text (not tool) mode: it runs on the cheap deepseek-flash profile, which does\n// not support function calling. The model emits a single line `\u8D77\u70B9: <\u884C\u53F7>` or\n// `\u8D77\u70B9: \u65E0`, parsed deterministically here.\n\nimport type { LlmTaskExecutor } from \"../../types.js\";\n\nexport const BODY_START_SYSTEM =\n \"\u4F60\u662F\u77ED\u5267\u5267\u672C\u7684\u300C\u6B63\u6587\u8D77\u70B9\u5B9A\u4F4D\u5668\u300D\u3002\u4E00\u4EFD\u6587\u4EF6\u5E38\u5E38\u5728\u771F\u6B63\u7684\u5267\u672C\u6B63\u6587\u4E4B\u524D\uFF0C\u538B\u7740\u4E00\u5927\u6BB5**\u975E\u6B63\u6587**\u7684\u7B79\u5907\u6750\u6599\u3002\u4F60\u8981\u5224\u65AD\uFF1A**\u771F\u6B63\u7684\u5267\u672C\u6B63\u6587**\u662F\u4E0D\u662F\u5728\u6211\u7ED9\u4F60\u7684\u8FD9\u6BB5\u5E26\u884C\u53F7\u7684\u6587\u672C\u91CC\u5F00\u59CB\uFF0C\u5982\u679C\u662F\uFF0C\u62A5\u544A\u5B83\u7684\u8D77\u59CB\u884C\u53F7\u3002\" +\n \"\\n\\n\u3010\u6B63\u6587\u957F\u4EC0\u4E48\u6837\u3011\u9010\u573A\u7684\u5267\u672C\uFF1A\u4EE5\u300C\u7B2CN\u96C6\u300D\u4E3A\u96C6\u5934\uFF0C\u4E0B\u9762\u7D27\u8DDF\u300C\u573AX-Y \u65E5/\u5185 \u5730\u70B9\u300D\u8FD9\u79CD\u5E26\u573A\u6B21\u7F16\u53F7\u7684\u573A\u666F\u5934\uFF0C\u518D\u5F80\u4E0B\u662F\u300C\u4E3B\u8981\u4EBA\u7269\uFF1A/\u4EBA\u7269\uFF1A\u300D\u548C\u4E00\u6761\u6761\u4EE5 \u25B3 \u5F00\u5934\u7684\u52A8\u4F5C\u3001\u4EE5\u53CA\u5E26\u8BF4\u8BDD\u4EBA\u7684\u53F0\u8BCD\u3002\u8FD9\u624D\u662F\u6B63\u6587\u3002\" +\n \"\\n\\n\u3010\u524D\u8A00\u957F\u4EC0\u4E48\u6837\uFF0C\u7EDD\u4E0D\u7B97\u6B63\u6587\u3011\uFF1A\" +\n \"\\n- \u9879\u76EE\u57FA\u672C\u4FE1\u606F / \u7B56\u5212\u5927\u7EB2 / \u9898\u6750\u6807\u7B7E / \u4E00\u53E5\u8BDD\u6545\u4E8B / \u6838\u5FC3\u770B\u70B9\uFF1B\" +\n \"\\n- \u89D2\u8272\u5361\uFF1A\u4E00\u6BB5\u6BB5\u300C\u4EBA\u7269\u8EAB\u4EFD / \u5916\u8C8C\u548C\u670D\u9970\u7279\u70B9 / \u6027\u683C\u6807\u7B7E / \u53F0\u8BCD\u8BED\u8A00\u98CE\u683C / \u4EBA\u7269\u5C0F\u4F20\u300D\u7684\u4ECB\u7ECD\uFF1B\" +\n \"\\n- \u5B8F\u89C2\u7ED3\u6784\u5927\u7EB2\uFF1A\u300C\u9636\u6BB5\u4E00 / \u9636\u6BB5\u4E8C\u2026\u2026\u300D\u8FD9\u79CD\u6574\u6BB5\u53D9\u4E8B\u6982\u8FF0\uFF08\u8BFB\u8D77\u6765\u50CF\u5267\u60C5\u7B80\u4ECB\uFF0C\u6CA1\u6709\u573A\u6B21\u7F16\u53F7\u3001\u6CA1\u6709\u9010\u6761\u53F0\u8BCD\uFF09\uFF1B\" +\n \"\\n- \u4E00\u5361\u96C6\u7EB2\uFF1A\u4E5F\u4F1A\u5199\u300C\u7B2CN\u96C6\uFF1A\u5C0F\u6807\u9898\u300D\uFF0C\u4F46\u4E0B\u9762\u53EA\u662F**\u4E00\u53E5\u8BDD\u5230\u4E00\u6BB5\u8BDD\u7684\u5267\u60C5\u6458\u8981**\uFF0C\u6CA1\u6709\u300C\u573AX-Y\u300D\u573A\u6B21\u3001\u6CA1\u6709 \u25B3 \u52A8\u4F5C\u3001\u6CA1\u6709\u9010\u53E5\u53F0\u8BCD\u3002\u8FD9\u662F\u6700\u5BB9\u6613\u8BEF\u5224\u7684\u9677\u9631\u2014\u2014\u5B83\u6709\u300C\u7B2CN\u96C6\u300D\u4F46**\u4E0D\u662F\u6B63\u6587**\u3002\" +\n \"\\n\\n\u3010\u5224\u5B9A\u89C4\u5219\u3011\u53EA\u6709\u5F53\u4F60\u5728\u7A97\u53E3\u91CC\u770B\u5230**\u5E26\u573A\u6B21\u7F16\u53F7\uFF08\u573AX-Y\uFF09\u6216\u660E\u663E\u9010\u6761\u52A8\u4F5C/\u53F0\u8BCD\u7684\u5267\u96C6**\u65F6\uFF0C\u624D\u7B97\u6B63\u6587\u5F00\u59CB\u3002\u53D6\u6B63\u6587\u7684\u7B2C\u4E00\u884C\uFF1A\u901A\u5E38\u662F\u6B63\u6587\u90A3\u4E2A\u300C\u7B2CN\u96C6\u300D\u96C6\u5934\u6240\u5728\u884C\uFF08\u82E5\u6CA1\u6709\u96C6\u5934\u5C31\u662F\u7B2C\u4E00\u4E2A\u300C\u573AX-Y\u300D\u884C\uFF09\u3002\u5982\u679C\u6587\u4EF6\u91CC\u6709\u300C\u5267\u672C\u6B63\u6587\u300D\u300C\u5206\u96C6\u5267\u672C\u300D\u8FD9\u7C7B\u5206\u9694\u6807\u9898\uFF0C\u6B63\u6587\u5C31\u4ECE\u5B83\u4E4B\u540E\u7684\u7B2C\u4E00\u4E2A\u96C6\u5934/\u573A\u6B21\u5F00\u59CB\u3002\" +\n \"\\n\\n\u3010\u8FB9\u754C\u4E0E\u4FDD\u5B88\u3011\" +\n \"\\n- \u53EA\u62A5\u544A**\u672C\u7A97\u53E3\u5185**\u80FD\u786E\u8BA4\u7684\u884C\u53F7\uFF1B\u5982\u679C\u8FD9\u6BB5\u8FD8\u5168\u662F\u524D\u8A00\u3001\u6216\u6B63\u6587\u8FD8\u6CA1\u51FA\u73B0\uFF0C\u5C31\u62A5\u544A\u300E\u65E0\u300F\uFF0C\u6211\u4F1A\u628A\u4E0B\u4E00\u6BB5\u7ED9\u4F60\u3002\" +\n \"\\n- \u5B81\u53EF\u7A0D\u5FAE\u9760\u524D\u4E5F\u4E0D\u8981\u8DF3\u8FC7\u7B2C 1 \u96C6\uFF1A\u62FF\u4E0D\u51C6\u8BE5\u53D6\u96C6\u5934\u8FD8\u662F\u573A\u6B21\u884C\u65F6\uFF0C\u53D6\u66F4\u9760\u524D\u7684\u90A3\u4E00\u884C\u3002\" +\n \"\\n- \u884C\u53F7\u5FC5\u987B\u539F\u6837\u7167\u6284\u6211\u7ED9\u4F60\u7684\u884C\u9996\u6570\u5B57\u3002\" +\n \"\\n\\n\u3010\u8F93\u51FA\u683C\u5F0F\u3011\u53EA\u8F93\u51FA\u4E00\u884C\uFF0C\u4E0D\u8981\u4EFB\u4F55\u89E3\u91CA\uFF1A\\n- \u627E\u5230\u6B63\u6587\u8D77\u70B9\uFF1A`\u8D77\u70B9: <\u884C\u53F7>`\uFF08\u4F8B\u5982 `\u8D77\u70B9: 140`\uFF09\\n- \u672C\u7A97\u53E3\u5168\u662F\u524D\u8A00 / \u8FD8\u6CA1\u5230\u6B63\u6587\uFF1A`\u8D77\u70B9: \u65E0`\";\n\nexport interface BodyStartResult {\n found: boolean;\n line: number | null;\n}\n\n/** Parse the model's single-line reply. Lenient: finds `\u8D77\u70B9: <n>` anywhere. */\nexport function parseBodyStart(text: string): BodyStartResult {\n const m = text.match(/\u8D77\u70B9\\s*[:\uFF1A]\\s*(\\d+)/);\n if (m) return { found: true, line: Math.trunc(Number(m[1])) };\n return { found: false, line: null };\n}\n\n/** One numbered window \u2192 does the screenplay body start here, and at which line. */\nexport async function runBodyStart(\n executor: LlmTaskExecutor,\n numberedWindow: string,\n signal?: AbortSignal,\n): Promise<BodyStartResult> {\n const res = await executor.generateText(\"ingest.body-start\", {\n system: BODY_START_SYSTEM,\n user:\n \"\u4E0B\u9762\u662F\u6E90\u6587\u4EF6\u7684\u4E00\u6BB5\uFF0C\u6BCF\u884C\u4EE5\u300C\u884C\u53F7<TAB>\u5185\u5BB9\u300D\u7ED9\u51FA\u3002\u5224\u65AD\u771F\u6B63\u7684\u5267\u672C\u6B63\u6587\u662F\u5426\u5728\u8FD9\u6BB5\u91CC\u5F00\u59CB\uFF0C\u6309\u683C\u5F0F\u53EA\u56DE\u4E00\u884C\u3002\\n\\n\" +\n numberedWindow,\n ...(signal ? { signal } : {}),\n });\n return parseBodyStart(res.text);\n}\n", "// Scan the source forward in numbered windows until the LLM locates where the\n// real screenplay body begins; everything before is planning front matter and is\n// dropped before chunking. Returns a 0-based line offset to start from (0 = whole\n// file). Robust by construction: a well-formed screenplay hits in the first\n// window; a file with no detectable body scans to EOF and falls back to 0 so\n// nothing is ever silently discarded.\n\nimport { runBodyStart } from \"../../llm/tasks/ingest/body-start.js\";\nimport type { LlmTaskExecutor } from \"../../llm/types.js\";\n\nconst WINDOW = 50;\nconst OVERLAP = 10; // step = WINDOW - OVERLAP, so a \u96C6\u5934/\u573A\u6B21 split across a window edge is still seen together\n\nexport interface BodyStartScan {\n line: number; // 0-based offset into the source lines to start ingesting from\n scannedLines: number; // how far the scan read before hitting / giving up\n found: boolean;\n error?: string; // set when the scan fell back to 0 because a call threw\n}\n\nexport async function detectBodyStart(\n executor: LlmTaskExecutor,\n text: string,\n signal?: AbortSignal,\n): Promise<BodyStartScan> {\n const lines = text.split(\"\\n\");\n const step = WINDOW - OVERLAP;\n try {\n for (let start = 0; start < lines.length; start += step) {\n const end = Math.min(start + WINDOW, lines.length);\n // 1-based line numbers so they match how humans/the model count.\n const numbered = lines.slice(start, end).map((l, i) => `${start + i + 1}\\t${l}`).join(\"\\n\");\n const res = await runBodyStart(executor, numbered, signal);\n if (res.found && res.line !== null) {\n // Clamp the reported 1-based line into range, convert to 0-based.\n const idx = Math.min(Math.max(res.line - 1, 0), lines.length - 1);\n return { line: idx, scannedLines: end, found: true };\n }\n if (end >= lines.length) break;\n }\n } catch (e) {\n // A failure on this pre-step must never make ingest worse than before: fall\n // back to ingesting the whole file \u2014 but record the real error so a silent\n // fallback (front matter NOT stripped) is diagnosable in body_start.json.\n return { line: 0, scannedLines: 0, found: false, error: e instanceof Error ? e.message : String(e) };\n }\n return { line: 0, scannedLines: lines.length, found: false };\n}\n", "// Bounded-concurrency batch settle (\u00A712.3). Runs every task, never short-\n// circuits: collects each result or error so the caller can persist all success\n// checkpoints and all error sidecars before blocking the next pass.\n\nexport type Settled<T> = { index: number; ok: true; value: T } | { index: number; ok: false; error: unknown };\n\nexport async function mapSettled<I, T>(items: I[], limit: number, fn: (item: I, index: number) => Promise<T>): Promise<Settled<T>[]> {\n const results: Settled<T>[] = new Array(items.length);\n let next = 0;\n const workers = Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, async () => {\n for (;;) {\n const i = next++;\n if (i >= items.length) return;\n try {\n results[i] = { index: i, ok: true, value: await fn(items[i]!, i) };\n } catch (error) {\n results[i] = { index: i, ok: false, error };\n }\n }\n });\n await Promise.all(workers);\n return results;\n}\n", "// Deterministic governance core (\u00A79.6/\u00A79.8/\u00A79.9 minus LLM). Given the provisional\n// initial script it: (1) assigns each asset's `default` state by highest explicit\n// frequency (tie \u2192 codepoint-smallest state name) and (2) materializes inherited\n// state onto every entity reference so the final product is self-contained\n// (\u00A715.2). Identity merge / drop / audit are LLM stages layered on separately;\n// this keep-all core always produces a valid, materialized v3 doc.\n\ntype Obj = Record<string, unknown>;\nconst isObj = (v: unknown): v is Obj => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst isArr = (v: unknown): v is unknown[] => Array.isArray(v);\n\ntype StateEntry = { state_id: string; state_name: string; description: string };\n\n// Ordered entity references discovered in a document walk. Each is a live object\n// we mutate its state_id on in place.\ntype Ref = { assetId: string; holder: Obj; explicit: string | undefined };\n\nfunction assetIndex(list: unknown): Map<string, Obj> {\n const map = new Map<string, Obj>();\n if (!isArr(list)) return map;\n for (const a of list) {\n if (!isObj(a)) continue;\n const id = a.actor_id ?? a.location_id ?? a.prop_id;\n if (typeof id === \"string\") map.set(id, a);\n }\n return map;\n}\n\n// Walk the doc in order, collecting entity refs (scene cast/props, scene\n// location, dialogue speakers) as mutable holders plus their explicit state id.\nfunction collectRefs(doc: Obj): Ref[] {\n const refs: Ref[] = [];\n const push = (holder: unknown, idField: string) => {\n if (!isObj(holder) || typeof holder[idField] !== \"string\") return;\n refs.push({ assetId: holder[idField] as string, holder, explicit: typeof holder.state_id === \"string\" ? holder.state_id : undefined });\n };\n for (const ep of isArr(doc.episodes) ? doc.episodes : []) {\n if (!isObj(ep) || !isArr(ep.scenes)) continue;\n for (const sc of ep.scenes) {\n if (!isObj(sc)) continue;\n push(sc.location, \"location_id\");\n for (const a of isArr(sc.actors) ? sc.actors : []) push(a, \"actor_id\");\n for (const p of isArr(sc.props) ? sc.props : []) push(p, \"prop_id\");\n for (const ac of isArr(sc.actions) ? sc.actions : []) {\n if (isObj(ac)) push(ac.speaker, \"actor_id\");\n }\n }\n }\n return refs;\n}\n\nfunction pickDefault(states: StateEntry[], counts: Map<string, number>): string | null {\n const candidates = states.filter((s) => (counts.get(s.state_id) ?? 0) > 0);\n if (candidates.length === 0) return null;\n let best = candidates[0]!;\n for (const s of candidates.slice(1)) {\n const c = counts.get(s.state_id) ?? 0;\n const bc = counts.get(best.state_id) ?? 0;\n if (c > bc || (c === bc && s.state_name < best.state_name)) best = s;\n }\n return best.state_id;\n}\n\nexport function governDeterministic(input: unknown): Obj {\n if (!isObj(input)) throw new Error(\"govern expects a script object\");\n const doc = JSON.parse(JSON.stringify(input)) as Obj; // pure: never mutate input\n\n // A speaking actor is necessarily part of the scene cast. Some upstream\n // passes intentionally rebuild sparse scene refs; restore this structural\n // fact before state materialization so validation never sees an inline actor\n // speaker detached from the scene that contains the line.\n for (const ep of isArr(doc.episodes) ? doc.episodes : []) {\n if (!isObj(ep) || !isArr(ep.scenes)) continue;\n for (const scene of ep.scenes) {\n if (!isObj(scene)) continue;\n const sceneActors = isArr(scene.actors) ? scene.actors.filter(isObj) : [];\n const actorIds = new Set(\n sceneActors\n .map((ref) => ref.actor_id)\n .filter((actorId): actorId is string => typeof actorId === \"string\"),\n );\n for (const action of isArr(scene.actions) ? scene.actions : []) {\n if (!isObj(action) || !isObj(action.speaker) || typeof action.speaker.actor_id !== \"string\") continue;\n if (actorIds.has(action.speaker.actor_id)) continue;\n sceneActors.push({ actor_id: action.speaker.actor_id });\n actorIds.add(action.speaker.actor_id);\n }\n scene.actors = sceneActors;\n }\n }\n\n const actors = assetIndex(doc.actors);\n const locations = assetIndex(doc.locations);\n const props = assetIndex(doc.props);\n const all = new Map<string, Obj>([...actors, ...locations, ...props]);\n\n const refs = collectRefs(doc);\n\n // 1. Count explicit state usage per asset.\n const counts = new Map<string, Map<string, number>>();\n for (const ref of refs) {\n if (ref.explicit === undefined) continue;\n if (!counts.has(ref.assetId)) counts.set(ref.assetId, new Map());\n const m = counts.get(ref.assetId)!;\n m.set(ref.explicit, (m.get(ref.explicit) ?? 0) + 1);\n }\n\n // 2. Per asset: pick default winner, rebuild states[] so exactly one 'default'.\n const remap = new Map<string, Map<string, string>>(); // assetId -> (oldStateId -> newStateId)\n for (const [assetId, asset] of all) {\n const states = (isArr(asset.states) ? asset.states : []).filter(isObj) as unknown as StateEntry[];\n const local = new Map<string, string>();\n const winner = pickDefault(states, counts.get(assetId) ?? new Map());\n let out: StateEntry[];\n if (winner === null) {\n // No explicit states used: keep a single synthetic default.\n const defaultState = states.find((state) => state.state_id === \"default\");\n out = [{\n state_id: \"default\",\n state_name: defaultState?.state_name ?? \"default\",\n description: defaultState?.description ?? \"\",\n }];\n } else {\n out = [];\n for (const s of states) {\n if (s.state_id === \"default\") continue; // drop synthetic default\n if (s.state_id === winner) { local.set(s.state_id, \"default\"); out.unshift({ state_id: \"default\", state_name: s.state_name, description: s.description ?? \"\" }); }\n else { local.set(s.state_id, s.state_id); out.push({ state_id: s.state_id, state_name: s.state_name, description: s.description ?? \"\" }); }\n }\n }\n asset.states = out;\n remap.set(assetId, local);\n }\n\n // 3. Materialize: walk refs in order, inherit last explicit state per asset.\n const last = new Map<string, string>();\n for (const ref of refs) {\n const local = remap.get(ref.assetId);\n let resolved: string;\n if (ref.explicit !== undefined) {\n resolved = local?.get(ref.explicit) ?? ref.explicit;\n last.set(ref.assetId, resolved);\n } else {\n resolved = last.get(ref.assetId) ?? \"default\";\n }\n ref.holder.state_id = resolved;\n }\n\n return doc;\n}\n", "// Arc summary. When the serial context's synopsis grows past its char budget,\n// the oldest ~10 aged-out episode one-liners are folded into a single \"arc\"\n// paragraph. This compresses the FAR narrative (which the model only needs as\n// background) into a bounded chapter recap, instead of the old zero-LLM\n// concatenation that just kept growing. Cheap model (ingest-low); fires rarely.\n\nimport type { LlmTaskExecutor } from \"../../types.js\";\n\nexport const ARC_SUMMARY_SYSTEM =\n \"\u4F60\u662F\u77ED\u5267\u8FDE\u7EED\u8F6C\u5199\u91CC\u7684\u300C\u8FDC\u7AEF\u5267\u60C5\u6D53\u7F29\u5668\u300D\u3002\u6211\u4F1A\u7ED9\u4F60\u4E00\u6BB5\u8FDE\u7EED\u96C6\u533A\u95F4\u7684**\u9010\u6761\u5267\u60C5\u6897\u6982**(\u6BCF\u884C\u4E00\u96C6\u6216\u4E00\u4E2A\u66F4\u65E9\u7684\u7BC7\u7AE0)\u3002\u5B83\u4EEC\u662F\u7ED9\u6A21\u578B\u5F53**\u80CC\u666F\u524D\u60C5**\u7528\u7684\u8FDC\u7AEF\u5267\u60C5,\u4E0D\u9700\u8981\u9010\u96C6\u7EC6\u8282\u3002\" +\n \"\\n\u4F60\u7684\u4EFB\u52A1:\u628A\u5B83\u4EEC**\u6D53\u7F29\u6210\u4E00\u6BB5\u8FDE\u8D2F\u7684\u7BC7\u7AE0\u6897\u6982**,\u53EA\u4FDD\u7559:\u4E3B\u7EBF\u8D70\u5411\u3001\u5173\u952E\u8F6C\u6298\u3001\u91CD\u8981\u4EBA\u7269\u4E0E\u5176\u9635\u8425/\u76EE\u6807\u53D8\u5316\u3001\u5F71\u54CD\u540E\u7EED\u7684\u56E0\u679C\u4E0E\u4F0F\u7B14\u3002\" +\n \"\\n\u8981\u6C42:\" +\n \"\\n- \u4E00\u6BB5\u8FDE\u7EED\u6587\u5B57,**\u4E0D\u8981**\u9010\u96C6\u7F57\u5217\u3001\u4E0D\u8981\u5206\u70B9\u3001\u4E0D\u8981\u5199\u300C\u7B2CN\u96C6\u300D\u5B57\u6837\u3001\u4E0D\u8981\u4EFB\u4F55\u6807\u9898\u3002\" +\n \"\\n- \u4FDD\u7559\u51FA\u73B0\u7684**\u5173\u952E\u4EBA\u7269\u540D/\u7EC4\u7EC7\u540D/\u5730\u540D**(\u7528\u539F\u6587\u91CC\u7684\u540D\u5B57),\u4E22\u6389\u4E00\u6B21\u6027\u9F99\u5957\u548C\u7410\u788E\u52A8\u4F5C\u3002\" +\n \"\\n- \u63A7\u5236\u5728 **200\u2013320 \u5B57**,\u5B81\u53EF\u6982\u62EC\u4E5F\u4E0D\u8981\u6D41\u6C34\u8D26\u3002\" +\n \"\\n- \u53EA\u8F93\u51FA\u8FD9\u6BB5\u6897\u6982\u6B63\u6587,\u4E0D\u8981\u4EFB\u4F55\u524D\u540E\u7F00\u8BF4\u660E\u3002\";\n\n/**\n * Compress a folded run of aged synopses into one arc paragraph.\n * @param range e.g. \"\u7B2C1\u96C6\u2013\u7B2C82\u96C6\" (for context only)\n * @param foldedText the folded entries, one per line (\"<label>\uFF1A<line>\")\n */\nexport async function runArcSummary(\n executor: LlmTaskExecutor,\n range: string,\n foldedText: string,\n signal?: AbortSignal,\n): Promise<string> {\n const res = await executor.generateText(\"ingest.arc-summary\", {\n system: ARC_SUMMARY_SYSTEM,\n user: `\u628A\u4E0B\u9762 ${range} \u7684\u9010\u6761\u5267\u60C5\u6D53\u7F29\u6210\u4E00\u6BB5\u7BC7\u7AE0\u6897\u6982(200\u2013320 \u5B57,\u8FDE\u8D2F\u6210\u6BB5,\u4E0D\u8981\u9010\u96C6\u7F57\u5217):\\n\\n${foldedText}`,\n ...(signal ? { signal } : {}),\n });\n return res.text.trim();\n}\n", "import type { JsonSchema } from \"../types.js\";\n\nexport const EPISODE_TITLE_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"episode_titles\"],\n additionalProperties: false,\n properties: {\n episode_titles: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"episode\", \"title\"],\n additionalProperties: false,\n properties: { episode: { type: \"integer\" }, title: { type: \"string\" } },\n },\n },\n },\n};\n\nexport const SYNOPSIS_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"synopsis\"],\n additionalProperties: false,\n properties: { synopsis: { type: \"string\" } },\n};\n\nexport const SCRIPT_SYNOPSIS_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"synopsis\", \"theme\", \"logline\", \"style\", \"main_characters\"],\n additionalProperties: false,\n properties: {\n synopsis: { type: \"string\" },\n theme: { type: \"string\" },\n logline: { type: \"string\" },\n style: { type: \"string\" },\n main_characters: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"name\", \"role\"],\n additionalProperties: false,\n properties: { name: { type: \"string\" }, role: { type: \"string\" } },\n },\n },\n },\n};\n\nexport const ASSET_AUDIT_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"issues\"],\n additionalProperties: false,\n properties: {\n issues: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\n \"type\",\n \"asset_ids\",\n \"state_ids\",\n \"names\",\n \"evidence\",\n \"recommendation\",\n \"suggested_survivor\",\n \"action\",\n \"confidence\",\n ],\n additionalProperties: false,\n properties: {\n type: {\n type: \"string\",\n enum: [\n \"duplicate_actor\",\n \"duplicate_location\",\n \"duplicate_prop\",\n \"duplicate_state\",\n \"suspicious_singleton_state\",\n \"unused_state\",\n \"needs_human_review\",\n ],\n },\n asset_ids: { type: \"array\", items: { type: \"string\" } },\n state_ids: { type: \"array\", items: { type: \"string\" } },\n names: { type: \"array\", items: { type: \"string\" } },\n evidence: { type: \"string\" },\n recommendation: { type: \"string\" },\n suggested_survivor: { type: [\"string\", \"null\"] },\n action: { type: \"string\", enum: [\"merge\", \"delete\", \"review\"] },\n confidence: { type: \"string\", enum: [\"high\", \"medium\", \"low\"] },\n },\n },\n },\n },\n};\n\nconst STATE_REF_SCHEMA: JsonSchema = {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"asset_id\", \"state_id\"],\n additionalProperties: false,\n properties: { asset_id: { type: \"string\" }, state_id: { type: [\"string\", \"null\"] } },\n },\n};\n\nexport const STATE_BINDING_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"scenes\"],\n additionalProperties: false,\n properties: {\n scenes: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"scene_id\"],\n additionalProperties: false,\n properties: {\n scene_id: { type: \"string\" },\n actors: {\n ...STATE_REF_SCHEMA,\n items: {\n type: \"object\", required: [\"actor_id\", \"state_id\"], additionalProperties: false,\n properties: { actor_id: { type: \"string\" }, state_id: { type: [\"string\", \"null\"] } },\n },\n },\n locations: {\n ...STATE_REF_SCHEMA,\n items: {\n type: \"object\", required: [\"location_id\", \"state_id\"], additionalProperties: false,\n properties: { location_id: { type: \"string\" }, state_id: { type: [\"string\", \"null\"] } },\n },\n },\n props: {\n ...STATE_REF_SCHEMA,\n items: {\n type: \"object\", required: [\"prop_id\", \"state_id\"], additionalProperties: false,\n properties: { prop_id: { type: \"string\" }, state_id: { type: [\"string\", \"null\"] } },\n },\n },\n state_changes: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"action_index\", \"target_kind\", \"target_id\", \"to_state_id\"],\n additionalProperties: false,\n properties: {\n action_index: { type: \"integer\" },\n target_kind: { type: \"string\", enum: [\"actor\", \"location\", \"prop\"] },\n target_id: { type: \"string\" },\n from_state_id: { type: [\"string\", \"null\"] },\n to_state_id: { type: \"string\" },\n effective_from: { type: \"string\", enum: [\"before_action\", \"after_action\"] },\n },\n },\n },\n },\n },\n },\n },\n};\n\nconst DEFAULT_LOOK_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"name\", \"description\"],\n additionalProperties: false,\n properties: {\n name: { type: \"string\", enum: [\"\u5E38\u6001\"], description: \"\u5B9E\u4F53\u9996\u6B21\u767B\u8BB0\u65F6\u7684\u9ED8\u8BA4\u9020\u578B\u540D\uFF0C\u56FA\u5B9A\u4E3A\u5E38\u6001\" },\n description: { type: \"string\", description: \"\u9ED8\u8BA4\u9020\u578B\u7684\u53EF\u89C1\u5916\u89C2\uFF0C\u53EA\u5199\u5916\u8C8C\u3001\u670D\u9970\u3001\u6750\u8D28\u3001\u989C\u8272\u3001\u5E03\u666F\u6216\u5F62\u5236\uFF0C\u975E\u7A7A\" },\n },\n};\n\n// Serial per-window asset/look Delta (\u00A7 serial, ingest.episode-assets). Native\n// structured output: the model returns this object directly, so canonical names\n// never get mangled by markdown delimiters. `name` holds ONLY the pure canonical\n// name; every translation / past-life / alt name goes in `aliases` \u2014 the split\n// the markdown `\u540D | \u540D | \u63CF\u8FF0` format could not enforce.\nexport const SERIAL_DELTA_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"newEntities\", \"merges\", \"looks\", \"lookChanges\", \"subEvents\", \"summary\"],\n additionalProperties: false,\n properties: {\n newEntities: {\n type: \"array\",\n description: \"\u672C\u6BB5\u65B0\u767B\u8BB0\u7684\u5B9E\u4F53(\u4EBA\u7269/\u573A\u666F/\u9053\u5177)\u3002name=canonical\uFF0Caliases \u5217\u5168\u8FD9\u6BB5\u91CC\u5B83\u7684\u6240\u6709\u5176\u4ED6\u53EB\u6CD5\",\n items: {\n type: \"object\",\n required: [\"kind\", \"name\", \"description\", \"aliases\", \"defaultLook\"],\n additionalProperties: false,\n properties: {\n kind: { type: \"string\", enum: [\"actor\", \"location\", \"prop\"] },\n name: { type: \"string\", description: \"\u7EAF canonical \u540D\uFF0C\u4E0D\u542B\u62EC\u53F7/\u659C\u6760/\u8BD1\u540D\u5939\u6CE8/\u5BF9\u767D\u6807\u8BB0\" },\n description: { type: \"string\", description: \"\u4E00\u53E5\u8BDD\u8BF4\u660E\u8FD9\u4E2A\u5B9E\u4F53\u672C\u8EAB\u662F\u8C01/\u4EC0\u4E48\u8EAB\u4EFD/\u4EC0\u4E48\u4E1C\u897F\uFF0C\u975E\u7A7A\uFF1B\u4EBA\u7269\u53EA\u5199\u8EAB\u4EFD\u3001\u89D2\u8272\u548C\u5173\u7CFB\uFF0C\u4E0D\u5199\u670D\u88C5\u9020\u578B\" },\n aliases: { type: \"array\", items: { type: \"string\" }, description: \"\u8FD9\u6BB5\u91CC\u8BE5\u5B9E\u4F53\u7684\u6240\u6709\u5176\u4ED6\u53EB\u6CD5\uFF1A\u522B\u540D/\u8BD1\u540D/\u524D\u4E16\u540D/\u77ED\u540D\u5168\u540D/\u5BF9\u767D\u8BF4\u8BDD\u4EBA\u5728\u6B63\u6587\u91CC\u7684\u5199\u6CD5\uFF0C\u9010\u4E2A\u5355\u5217(\u7EAF\u540D\uFF0C\u4E0D\u5E26\u5BF9\u767D/\u60C5\u7EEA\u6807\u8BB0)\" },\n defaultLook: DEFAULT_LOOK_SCHEMA,\n },\n },\n },\n merges: {\n type: \"array\",\n description: \"\u672C\u6BB5\u91CC\u67D0\u4E2A\u5C1A\u672A\u767B\u8BB0\u7684\u79F0\u547C\uFF0C\u5176\u5B9E\u662F\u67D0\u4E2A\u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684\u522B\u540D\",\n items: {\n type: \"object\",\n required: [\"from\", \"into\"],\n additionalProperties: false,\n properties: {\n from: { type: \"string\", description: \"\u672C\u6BB5\u8FD9\u4E2A\u79F0\u547C(\u5C1A\u672A\u4F5C\u4E3A\u72EC\u7ACB\u5B9E\u4F53\u767B\u8BB0\u8FC7)\" },\n into: { type: \"string\", description: \"\u5B83\u6240\u6307\u7684\u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684 canonical \u540D\" },\n },\n },\n },\n looks: {\n type: \"array\",\n description: \"\u9ED8\u8BA4\u9020\u578B\u4E4B\u5916\u3001\u9700\u8981\u5355\u72EC\u590D\u73B0\u7684\u65B0\u589E\u9020\u578B\",\n items: {\n type: \"object\",\n required: [\"entity\", \"name\", \"aliases\", \"description\"],\n additionalProperties: false,\n properties: {\n entity: { type: \"string\", description: \"\u5B9E\u4F53 canonical \u540D\" },\n name: { type: \"string\", description: \"\u9020\u578B\u540D\uFF0C\u5FC5\u987B\u4E2D\u6587\uFF0C\u82F1\u6587\u4E13\u540D\u5148\u8BD1\u6210\u4E2D\u6587\" },\n aliases: { type: \"array\", items: { type: \"string\" }, description: \"\u540C\u4E49\u9020\u578B\u540D\" },\n description: { type: \"string\", description: \"\u8FD9\u5957\u5916\u89C2\u4E00\u53E5\u8BDD\" },\n },\n },\n },\n lookChanges: {\n type: \"array\",\n description: \"\u9020\u578B\u53D8\u5316\uFF1A\u53EA\u5728\u67D0\u5B9E\u4F53\u7684\u9020\u578B\u4ECE\u8FD9\u4E00\u573A\u8D77\u53D1\u751F\u53D8\u5316\u65F6\u6807\u4E00\u6761\uFF1B\u4E0D\u53D8\u7684\u573A\u4E0D\u7528\u6807(\u7CFB\u7EDF\u81EA\u52A8\u6CBF\u7528)\",\n items: {\n type: \"object\",\n required: [\"scene\", \"entity\", \"look\"],\n additionalProperties: false,\n properties: {\n scene: { type: \"string\", description: \"\u53D8\u5316\u53D1\u751F\u7684\u573A\u666F id\uFF0C\u5982 scn_012\" },\n entity: { type: \"string\", description: \"\u5B9E\u4F53 canonical \u540D\" },\n look: { type: \"string\", description: \"\u4ECE\u8FD9\u573A\u8D77\u7A7F\u7684\u9020\u578B\u540D(\u5FC5\u987B\u662F\u5DF2\u5728 looks \u91CC\u6CE8\u518C\u8FC7\u7684\u6863\u4F4D)\" },\n },\n },\n },\n subEvents: { type: \"array\", items: { type: \"string\" }, description: \"\u672C\u6BB5\u5173\u952E\u5267\u60C5\u539F\u5B50\uFF0C\u6BCF\u6761\u4E00\u53E5\u8BDD\" },\n summary: { type: \"string\", description: \"\u672C\u6BB5\u4E00\u53E5\u8BDD\u6897\u6982\" },\n },\n};\n\n// Serial VIDEO-pass structured output (\u00A710.2, ingest.video-serial). Replaces the\n// prior \"emit one markdown doc \u2192 parseSerialMd\" contract: Gemini returns THIS object\n// directly (responseMimeType application/json + responseJsonSchema). It carries\n// both the source-faithful storyboard screenplay (scenes \u2192 visual/performance/sound anchors) and incremental registry\n// maintenance (new_entities / enrich / canonicalize) + open threads. Mirrors the\n// SerialOutput interface, with environment flattened to space/time. `state`/`states`\n// descriptions forbid parens/slashes at the source \u2014 the drift that fragmented one\n// outfit into \u300C\u9ED1\u4E1D\u77ED\u88D9\uFF08\u8EAB\u7A7F\u6536\u94F6\u77ED\u8896\u300D/\u300C\u9ED1\u4E1D\u77ED\u88D9/\u7EF7\u5E26\u77ED\u88D9\u300Dunder the md format \u2014\n// with a deterministic clean pass in runVideoSerial as backstop.\nconst KIND3 = { type: \"string\", enum: [\"actor\", \"location\", \"prop\"] } as const;\nconst STATE_ITEM = { type: \"string\", description: \"\u9020\u578B\u6863\u4F4D\u540D\uFF0C\u53EA\u586B\u540D\u5B57\u672C\u8EAB\uFF1B\u7981\u6B62\u62EC\u53F7\u3001\u659C\u6760\u3001\u9017\u53F7\u6216\u63CF\u8FF0\u6027\u6587\u5B57\" } as const;\nconst DESCRIBED_STATE_ITEM = {\n type: \"object\",\n required: [\"name\", \"description\"],\n additionalProperties: false,\n properties: {\n name: STATE_ITEM,\n description: {\n type: \"string\",\n description: \"\u8BE5\u72B6\u6001\u53EF\u590D\u73B0\u7684\u6301\u7EED\u53EF\u89C1\u5916\u89C2\uFF0C\u975E\u7A7A\u3002\u4EBA\u7269\u7EFC\u5408\u591A\u4E2A\u6E05\u6670\u955C\u5934\u5E76\u4ECE\u5934\u5230\u811A\u5199\u8BE5\u9020\u578B\u7279\u6709\u7684\u5986\u53D1\u5934\u9970\u3001\u9888\u9970\u3001\u5916\u5957\u3001\u4E0A\u88C5\u3001\u4E0B\u88C5/\u8FDE\u4F53\u8863\u88D9\u3001\u889C\u7C7B\u3001\u978B\u5C65\u3001\u624B\u5957\u548C\u9970\u54C1\uFF1B\u6BCF\u4EF6\u53EF\u89C1\u5355\u54C1\u5199\u989C\u8272\u3001\u6750\u8D28/\u5149\u6CFD/\u7EB9\u7406\u3001\u7248\u578B\u677E\u7D27\u3001\u9886\u8896\u7ED3\u6784\u3001\u5F00\u5408\u3001\u8170\u7EBF\u3001\u957F\u5EA6\u3001\u4E0B\u6446\u3001\u56FE\u6848\u6587\u5B57\u3001\u6EDA\u8FB9\u91D1\u5C5E\u4EF6\u3001\u53E0\u7A7F\u5173\u7CFB\u4E0E\u6240\u5728\u4F4D\u7F6E\uFF1B\u6301\u7EED\u7834\u635F\u6C61\u6E0D\u5199\u90E8\u4F4D\u3001\u8303\u56F4\u548C\u989C\u8272\u3002\u53EA\u7701\u7565\u770B\u4E0D\u89C1\u6216\u4E0D\u80FD\u786E\u8BA4\u7684\u9879\uFF0C\u4E0D\u7528\u4E00\u53E5\u7B3C\u7EDF\u670D\u88C5\u6982\u62EC\uFF0C\u4E0D\u4ECE\u5C40\u90E8\u8865\u9020\u5168\u8EAB\u3002\u5730\u70B9\u548C\u9053\u5177\u5199\u76F8\u5BF9\u5E38\u6001\u7684\u6301\u7EED\u5916\u89C2\u5DEE\u5F02\u3002\u53EA\u5199\u753B\u9762\u4E8B\u5B9E\uFF0C\u4E0D\u5199\u52A8\u4F5C\u3001\u59FF\u6001\u3001\u60C5\u7EEA\u3001\u5FC3\u7406\u6216\u5267\u60C5\u8BC4\u4EF7\",\n },\n },\n} as const;\nconst IDENTITY_PROFILE = {\n type: \"object\",\n required: [\"apparent_gender\", \"apparent_age\", \"face_shape\", \"brows_eyes\", \"nose\", \"mouth\", \"skin_features\", \"hair\", \"build\", \"persistent_marks\", \"voice\"],\n additionalProperties: false,\n properties: {\n apparent_gender: { type: \"string\", description: \"\u753B\u9762\u5448\u73B0\u7684\u6027\u522B\uFF1B\u65E0\u6CD5\u786E\u8BA4\u586B\u7A7A\u4E32\" },\n apparent_age: { type: \"string\", description: \"\u53EF\u89C1\u5E74\u9F84\u6BB5\uFF0C\u4F7F\u7528\u7A84\u800C\u5BA1\u614E\u7684\u8303\u56F4\uFF0C\u5982\u300E\u7EA625-30\u5C81\u300F\uFF1B\u65E0\u6CD5\u786E\u8BA4\u586B\u7A7A\u4E32\" },\n face_shape: { type: \"string\", description: \"\u8138\u90E8\u8F6E\u5ED3\u3001\u98A7\u9AA8\u3001\u4E0B\u988C\u4E0E\u4E0B\u5DF4\u7684\u5BA2\u89C2\u5F62\u6001\uFF1B\u4E0D\u5199\u5BA1\u7F8E\u3001\u6C14\u8D28\u3001\u8868\u60C5\u6216\u5267\u60C5\u5F62\u6001\" },\n brows_eyes: { type: \"string\", description: \"\u7709\u5F62\u3001\u7709\u8272\u3001\u773C\u578B\u3001\u773C\u8DDD\u3001\u5355\u53CC\u773C\u76AE\u53CA\u773C\u5C3E\u7684\u9759\u6001\u5F62\u6001\uFF1B\u4E0D\u5199\u76EE\u5149\u3001\u795E\u60C5\u3001\u60C5\u7EEA\u3001\u5986\u5BB9\u3001\u9690\u5F62\u773C\u955C\u6216\u53D8\u8EAB\u989C\u8272\" },\n nose: { type: \"string\", description: \"\u9F3B\u6881\u3001\u9F3B\u5934\u3001\u9F3B\u7FFC\u7684\u5BA2\u89C2\u5F62\u6001\" },\n mouth: { type: \"string\", description: \"\u9759\u6B62\u65F6\u7684\u5507\u539A\u8584\u3001\u5507\u5CF0\u3001\u5634\u89D2\u7ED3\u6784\u548C\u53E3\u5468\u7279\u5F81\uFF1B\u4E0D\u5199\u8BF4\u8BDD\u52A8\u4F5C\u3001\u8868\u60C5\u6216\u5507\u5986\" },\n skin_features: { type: \"string\", description: \"\u7A33\u5B9A\u80A4\u8272\u3001\u9762\u90E8\u7EB9\u7406\u3001\u75E3\u3001\u96C0\u6591\u3001\u65E7\u75A4\u7B49\u8DE8\u573A\u666F\u53EF\u89C1\u7279\u5F81\uFF1B\u4E0D\u5199\u4E34\u65F6\u4F24\u75D5\u3001\u8840\u8FF9\u3001\u6C61\u6E0D\u6216\u5986\u5BB9\" },\n hair: { type: \"string\", description: \"\u7A33\u5B9A\u53D1\u8272\u3001\u53D1\u9645\u7EBF\u3001\u957F\u5EA6\u3001\u5377\u76F4\u548C\u5E38\u6001\u53D1\u578B\uFF1B\u4E0D\u5199\u5047\u53D1\u3001\u53D8\u8EAB\u5F62\u6001\u6216\u4E00\u6B21\u6027\u9020\u578B\uFF0C\u4E34\u65F6\u5DEE\u5F02\u5199\u5165 states\" },\n build: { type: \"string\", description: \"\u53EF\u7531\u753B\u9762\u786E\u8BA4\u7684\u8EAB\u9AD8\u76F8\u5BF9\u5173\u7CFB\u3001\u80A9\u5BBD\u3001\u9AA8\u67B6\u548C\u4F53\u578B\uFF1B\u4E0D\u5199\u59FF\u6001\u3001\u52A8\u4F5C\u3001\u6C14\u8D28\u6216\u5BA1\u7F8E\u8BCD\" },\n persistent_marks: { type: \"array\", items: { type: \"string\" }, description: \"\u7EB9\u8EAB\u3001\u65E7\u75A4\u3001\u75E3\u3001\u80CE\u8BB0\u3001\u56FA\u5B9A\u7A7F\u5B54\u7B49\u4E0D\u53EF\u968F\u6362\u88C5\u6458\u9664\u7684\u8EAB\u4F53\u6807\u8BB0\uFF1B\u4E0D\u5199\u8033\u73AF\u3001\u9879\u94FE\u3001\u773C\u955C\u7B49\u914D\u9970\uFF0C\u6CA1\u6709\u586B\u7A7A\u6570\u7EC4\" },\n voice: { type: \"string\", description: \"\u4ECE\u6E05\u6670\u539F\u58F0\u53EF\u786E\u8BA4\u7684\u97F3\u9AD8\u3001\u97F3\u8272\u3001\u8BED\u901F\u3001\u53E3\u97F3\u6216\u7A33\u5B9A\u53D1\u58F0\u8D28\u611F\uFF1B\u4E0D\u5199\u5F53\u4E0B\u60C5\u7EEA\u3001\u6001\u5EA6\u6216\u89D2\u8272\u6027\u683C\uFF0C\u542C\u4E0D\u6E05\u586B\u7A7A\u4E32\" },\n },\n} as const;\nexport const VIDEO_SERIAL_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"synopsis\", \"scenes\", \"registry_delta\", \"open_threads\"],\n additionalProperties: false,\n properties: {\n synopsis: { type: \"string\", description: \"\u672C\u96C6\u5267\u60C5\u6897\u6982\uFF0C\u6309\u53D1\u751F\u987A\u5E8F\uFF0C200-300 \u5B57\u7EAF\u6587\u672C\" },\n scenes: {\n type: \"array\",\n description: \"\u672C\u96C6\u6240\u6709\u573A\u666F\u5355\u5143\uFF0C\u6309\u65F6\u95F4\u987A\u5E8F\u6392\u5217\u3002\u573A\u5185\u5C3D\u91CF\u5FE0\u5B9E\u8FD8\u539F\u539F\u7247\u5206\u955C\uFF1A\u6BCF\u6B21\u5207\u955C\u3001\u8FDE\u7EED\u955C\u5934\u5185\u7684\u6444\u5F71\u53D8\u5316\u3001\u53EF\u89C1\u8868\u6F14\u548C\u58F0\u97F3\u4E8B\u4EF6\u6309\u5B9E\u9645\u65F6\u95F4\u4EA4\u9519\u4FDD\u7559\uFF0C\u91CD\u590D\u955C\u5934\u4E5F\u4E0D\u53BB\u91CD\uFF1B\u5730\u70B9\u3001\u660E\u663E\u65F6\u6BB5\u6216\u53D9\u4E8B\u7EBF\u53D8\u5316\u65F6\u62C6\u573A\uFF0C\u666E\u901A\u5207\u955C\u4E0D\u5355\u72EC\u62C6 scene\uFF1B\u540C\u4E00\u8FDE\u7EED\u573A\u5185\u7684\u4EBA\u7269\u9020\u578B\u53D8\u5316\u4FDD\u7559\u5728\u540C\u4E00\u573A\uFF1B\u8DE8\u5730\u70B9\u8499\u592A\u5947\u62C6\u6210\u591A\u4E2A\u77ED\u573A\",\n items: {\n type: \"object\",\n required: [\"space\", \"time\", \"timeRange\", \"location\", \"characters\", \"props\", \"shots\", \"voices\"],\n additionalProperties: false,\n properties: {\n space: { type: \"string\", description: \"\u5185\u666F\u586B\u300C\u5185\u300D/\u5916\u666F\u586B\u300C\u5916\u300D\uFF1B\u4E0D\u786E\u5B9A\u586B\u7A7A\u4E32\" },\n time: {\n type: \"string\",\n enum: [\"\u65E5\", \"\u591C\", \"\u6668\", \"\u660F\"],\n description: \"\u672C\u573A\u5FC5\u987B\u9009\u62E9\u4E00\u4E2A\u65F6\u6BB5\uFF1A\u767D\u5929/\u65E5\u95F4\u586B\u300C\u65E5\u300D\uFF0C\u591C\u665A/\u591C\u95F4\u586B\u300C\u591C\u300D\uFF0C\u6E05\u6668/\u9ECE\u660E\u586B\u300C\u6668\u300D\uFF0C\u9EC4\u660F/\u508D\u665A\u586B\u300C\u660F\u300D\u3002\u7ED3\u5408\u7167\u660E\u3001\u4F5C\u606F\u3001\u5929\u7A7A\u548C\u5267\u60C5\u4E0A\u4E0B\u6587\u5224\u65AD\uFF0C\u4E0D\u5F97\u7559\u7A7A\",\n },\n timeRange: { type: \"string\", description: \"\u672C\u573A\u8D77\u6B62\u65F6\u95F4 MM:SS-MM:SS\uFF1BSS \u5FC5\u987B\u4E3A 00-59\uFF0C\u6574\u5206\u949F\u5199\u6210\u4E0B\u4E00\u5206\u949F\u7684 :00\uFF0C\u7981\u6B62\u5199 :60\" },\n location: { type: \"string\", description: \"\u672C\u573A\u552F\u4E00\u7A33\u5B9A\u4E3B\u7A7A\u95F4\u5730\u70B9\u540D\uFF0C\u6CBF\u7528\u89C4\u8303\u540D\uFF1B\u5BA2\u5385/\u5367\u5BA4/\u536B\u751F\u95F4/\u5927\u5385/\u5E7F\u573A/\u821E\u53F0/\u540E\u53F0\u5206\u522B\u5EFA\u5730\u70B9\uFF0C\u76F8\u5173\u7A7A\u95F4\u7528\u300E\u8C6A\u5B85\u00B7\u5BA2\u5385\u300F\u5F0F\u547D\u540D\" },\n characters: {\n type: \"array\",\n description: \"\u672C\u573A\u5728\u573A\u7684\u5177\u4F53\u5355\u4EBA\u89D2\u8272\uFF08\u7FA4\u4F17\u4E0D\u5217\uFF09\u3002\u540C\u4E00\u89D2\u8272\u53EA\u80FD\u51FA\u73B0\u4E00\u6B21\uFF1B\u5176 states \u586B\u672C\u573A\u51FA\u73B0\u8FC7\u7684\u5168\u90E8\u7A33\u5B9A\u9020\u578B/\u72B6\u6001\u96C6\u5408\",\n items: {\n type: \"object\",\n required: [\"name\", \"states\"],\n additionalProperties: false,\n properties: {\n name: { type: \"string\", description: \"\u89D2\u8272\u89C4\u8303\u540D\" },\n states: { type: \"array\", items: STATE_ITEM, description: \"\u672C\u573A\u8BE5\u89D2\u8272\u51FA\u73B0\u8FC7\u7684\u5168\u90E8\u9020\u578B/\u72B6\u6001\u540D\u96C6\u5408\u3002\u6BCF\u4E2A\u72B6\u6001\u662F\u6574\u5957\u7740\u88C5\u6863\u4F4D\u540D\uFF0C\u53EA\u586B\u540D\u5B57\u672C\u8EAB\uFF1B\u7981\u6B62\u62EC\u53F7\u3001\u659C\u6760\u3001\u9017\u53F7\u6216\u63CF\u8FF0\u6587\u5B57\uFF08\u9519\u8BEF\uFF1A\u300E\u9ED1\u4E1D\u77ED\u88D9\uFF08\u8EAB\u7A7F\u6536\u94F6\u77ED\u8896\uFF09\u300F\u300E\u9ED1\u4E1D\u77ED\u88D9/\u7EF7\u5E26\u77ED\u88D9\u300F\uFF1B\u6B63\u786E\uFF1A\u300E\u9ED1\u4E1D\u77ED\u88D9\u300F\uFF09\u3002\u540C\u4E00\u5957\u9020\u578B\u6CBF\u7528\u5DF2\u77E5\u8BBE\u5B9A\u91CC\u7684\u65E2\u6709\u540D\uFF1B\u6CA1\u6362\u88C5\u6216\u770B\u4E0D\u6E05\u586B\u7A7A\u6570\u7EC4\u3002\u4E0D\u5F97\u4E3A\u540C\u4E00\u89D2\u8272\u62C6\u6210\u591A\u6761\u8BB0\u5F55\" },\n // Retired experiment: identity_evidence/state_evidence used to\n // be requested here. Evidence is now a deterministic post-ingest\n // sidecar derived from final Action timestamps.\n },\n },\n },\n props: { type: \"array\", items: { type: \"string\" }, description: \"\u672C\u573A\u5728\u573A\u7684\u5173\u952E\u9053\u5177\u540D\" },\n shots: {\n type: \"array\",\n description: \"\u672C\u573A\u72EC\u7ACB\u7684\u9010\u955C\u6E05\u5355\uFF0C\u4E0E\u58F0\u97F3\u5206\u5F00\u76D8\u70B9\u3002\u539F\u7247\u6BCF\u6B21\u5207\u955C\u90FD\u5FC5\u987B\u6709\u4E00\u6761\uFF0C\u91CD\u590D\u955C\u5934\u4E5F\u4E0D\u53BB\u91CD\uFF1B\u8FDE\u7EED\u955C\u5934\u5185\u7684\u6444\u5F71\u6216\u8868\u6F14\u53D8\u5316\u53E6\u589E\u4E00\u6761\u3002\u4E0D\u56E0\u4E3A\u53F0\u8BCD\u8FDE\u7EED\u6216\u5267\u60C5\u76EE\u7684\u76F8\u540C\u800C\u7701\u7565\u5206\u955C\",\n items: {\n type: \"object\",\n required: [\"ts\", \"camera\", \"visual\"],\n additionalProperties: false,\n properties: {\n ts: { type: \"string\", description: \"\u672C\u955C\u5934\u6216\u955C\u5185\u53D8\u5316\u771F\u6B63\u5F00\u59CB\u7684\u65F6\u95F4\u6233 MM:SS\uFF08\u5206:\u79D2\uFF09\uFF1BSS \u5FC5\u987B\u4E3A 00-59\uFF0C\u6574\u5206\u949F\u5199\u6210\u4E0B\u4E00\u5206\u949F\u7684 :00\uFF0C\u7981\u6B62\u5199 :60\" },\n camera: { type: \"string\", description: \"\u672C\u955C\u5934\u53EF\u786E\u8BA4\u7684\u5207\u6362\u5173\u7CFB\u3001\u666F\u522B\u3001\u89D2\u5EA6\u3001\u673A\u4F4D\u3001\u8FD0\u955C\u3001\u6784\u56FE\u3001\u7126\u70B9\u548C\u753B\u9762\u4E3B\u4F53\uFF1B\u53EA\u5199\u539F\u7247\u80FD\u786E\u8BA4\u7684\u6444\u5F71\u4E8B\u5B9E\uFF0C\u4E0D\u63A8\u6D4B\u955C\u5934\u53C2\u6570\u6216\u62CD\u6444\u610F\u56FE\" },\n visual: { type: \"string\", description: \"\u672C\u955C\u5934\u5B9E\u9645\u53EF\u89C1\u7684\u73AF\u5883\u3001\u4EBA\u7269\u5360\u4F4D\u4E0E\u7AD9\u4F4D\u3001\u59FF\u6001\u3001\u9762\u5411\u3001\u89C6\u7EBF\u3001\u8868\u60C5\u3001\u63A5\u89E6\u3001\u52A8\u4F5C\u5BF9\u8C61\u3001\u9053\u5177\u548C\u7ED3\u679C\uFF1B\u53EA\u5199\u753B\u9762\u4E8B\u5B9E\uFF0C\u4E0D\u7528\u60C5\u7EEA\u3001\u6001\u5EA6\u6216\u5FC3\u7406\u6982\u62EC\" },\n },\n },\n },\n voices: {\n type: \"array\",\n description: \"\u672C\u573A\u72EC\u7ACB\u7684\u58F0\u97F3\u6E05\u5355\u3002\u5B8C\u6574\u4FDD\u7559\u51FA\u955C\u5BF9\u767D\u3001\u753B\u5916\u5BF9\u767D\u3001\u89D2\u8272\u5185\u5FC3\u72EC\u767D/\u81EA\u8FF0\u3001\u5BA2\u89C2\u65C1\u767D\u3001\u7535\u8BDD/\u5E7F\u64AD/\u8BBE\u5907\u58F0\u548C\u7FA4\u4F53\u58F0\u3002\u53F0\u8BCD\u8DE8\u955C\u65F6\u6309\u81EA\u7136\u8BED\u53E5\u62C6\u5206\uFF0C\u4E0D\u5F97\u628A\u8DE8\u591A\u4E2A\u955C\u5934\u7684\u591A\u53E5\u53F0\u8BCD\u5408\u5E76\u6210\u4E00\u6761\",\n items: {\n type: \"object\",\n required: [\"kind\", \"speaker\", \"parenthetical\", \"ts\", \"content\"],\n additionalProperties: false,\n properties: {\n kind: { type: \"string\", enum: [\"dlg\", \"think\"], description: \"dlg=\u4EBA\u7269\u5BF9\u4ED6\u4EBA\u8BF4\u51FA\u7684\u58F0\u97F3\u6216\u5BA2\u89C2\u65C1\u767D\uFF1Bthink=\u97F3\u8F68\u5B9E\u9645\u5305\u542B\u3001\u660E\u786E\u5C5E\u4E8E\u67D0\u89D2\u8272\u7684\u5185\u5FC3\u72EC\u767D/\u7B2C\u4E00\u4EBA\u79F0\u81EA\u8FF0\" },\n speaker: { type: \"string\", description: \"\u8BF4\u8BDD\u4EBA\u89C4\u8303\u540D\uFF1B\u5BA2\u89C2\u53D9\u8FF0\u8005\u6216\u8EAB\u4EFD\u4E0D\u660E\u65C1\u767D\u7528\u300Ebroadcast:\u65C1\u767D\u300F\uFF0C\u5E7F\u64AD\u7528\u300Ebroadcast:\u540D\u300F\uFF0C\u65E0\u6CD5\u533A\u5206\u6210\u5458\u7684\u7FA4\u4F53\u5171\u540C\u53D1\u58F0\u7528\u300Egroup:\u7FA4\u4F53\u540D\u300F\" },\n parenthetical: { type: \"string\", description: \"\u53EF\u786E\u8BA4\u7684\u53D1\u58F0\u65B9\u5F0F\u3001\u58F0\u97F3\u6765\u6E90\uFF0C\u6216\u4E0E\u53F0\u8BCD\u540C\u65F6\u53D1\u751F\u7684\u77ED\u4FC3\u53EF\u89C1\u8868\u6F14\uFF1B\u6CA1\u6709\u5219\u586B\u7A7A\u4E32\u3002\u6444\u5F71\u8C03\u5EA6\u548C\u5F71\u54CD\u8FDE\u7EED\u6027\u7684\u52A8\u4F5C\u5C5E\u4E8E shots\uFF0C\u4E0D\u5199\u5728\u8FD9\u91CC\uFF1B\u4E0D\u7528\u62BD\u8C61\u60C5\u7EEA\u3001\u6001\u5EA6\u6216\u5FC3\u7406\u6807\u7B7E\" },\n ts: { type: \"string\", description: \"\u672C\u6BB5\u58F0\u97F3\u771F\u6B63\u5F00\u59CB\u7684\u65F6\u95F4\u6233 MM:SS\uFF08\u5206:\u79D2\uFF09\uFF1BSS \u5FC5\u987B\u4E3A 00-59\uFF0C\u6574\u5206\u949F\u5199\u6210\u4E0B\u4E00\u5206\u949F\u7684 :00\uFF0C\u7981\u6B62\u5199 :60\" },\n content: { type: \"string\", description: \"\u9010\u5B57\u4FDD\u7559\u97F3\u8F68\u5B9E\u9645\u8BED\u8A00\u548C\u5939\u6742\u8BED\u8A00\uFF0C\u4E0D\u7FFB\u8BD1\u3001\u4E0D\u6539\u5199\u3001\u4E0D\u7528\u7FFB\u8BD1\u5B57\u5E55\u66FF\u6362\u5916\u8BED\u539F\u58F0\" },\n },\n },\n },\n },\n },\n },\n registry_delta: {\n type: \"object\",\n description: \"\u5BF9\u5DF2\u77E5\u8BBE\u5B9A\u7684\u589E\u91CF\u7EF4\u62A4\u3002\u5DF2\u6709\u4E14\u65E0\u65B0\u4FE1\u606F\u7684\u5B9E\u4F53\u4E00\u4E2A\u5B57\u90FD\u522B\u5199\",\n required: [\"new_entities\", \"enrich\", \"canonicalize\"],\n additionalProperties: false,\n properties: {\n new_entities: {\n type: \"array\",\n description: \"\u672C\u96C6\u9996\u6B21\u51FA\u73B0\u3001\u4E14\u5DF2\u77E5\u8BBE\u5B9A\u91CC\u6CA1\u6709\u7684\u5B9E\u4F53\u3002\u5FC5\u987B\u8986\u76D6 scenes.location\u3001scenes.characters\u3001scenes.props \u548C\u4EBA\u7269 voices.speaker \u4E2D\u6240\u6709\u65E0\u6CD5\u89E3\u6790\u5230\u5DF2\u77E5\u8BBE\u5B9A\u6216 canonicalize \u76EE\u6807\u7684\u540D\u79F0\uFF1B\u53EA\u767B\u8BB0\u5177\u4F53\u5355\u4EBA\u89D2\u8272\u3001\u7A33\u5B9A\u5730\u70B9\u548C\u5173\u952E\u9053\u5177\uFF0C\u7FA4\u4F17\u4E0D\u767B\u8BB0\",\n items: {\n type: \"object\",\n required: [\"name\", \"kind\", \"status\", \"importance\", \"recognition_anchors\", \"identity_profile\", \"appearance\", \"role\", \"states\", \"aliases\"],\n additionalProperties: false,\n properties: {\n name: { type: \"string\", description: \"\u89C4\u8303\u540D\uFF1B\u8BA4\u4E0D\u51FA\u4E14\u65E0\u672C\u540D\u7684\u4EBA\u7528\u300E\u7A33\u5B9A\u5916\u89C2\u7279\u5F81+\u5E74\u9F84\u6BB5+\u6027\u522B\u300F\u6784\u6210\u4E0D\u542B\u59D3\u7684\u63CF\u8FF0\u540D\uFF0C\u7EDD\u4E0D\u7F16\u5E26\u59D3\u5047\u540D\" },\n kind: KIND3,\n status: { type: \"string\", enum: [\"canonical\", \"provisional\"], description: \"canonical=\u8EAB\u4EFD\u5DF2\u786E\u8BA4\uFF1Bprovisional=\u8BA4\u4E0D\u51FA/\u672A\u70B9\u540D\uFF0C\u5F85\u540E\u7EED\u7528\u76F4\u63A5\u547D\u540D\u8BC1\u636E\u5347\u7EA7\u89C4\u8303\u540D\" },\n importance: { type: \"string\", enum: [\"featured\", \"background\"] },\n recognition_anchors: { type: \"array\", items: { type: \"string\" }, description: \"\u4EBA\u7269\u586B\u5199 3-6 \u6761\u8DE8\u96C6\u91CD\u8BA4\u951A\u70B9\uFF0C\u6BCF\u6761\u7EC4\u5408\u81F3\u5C11\u4E24\u4E2A\u53EF\u5728 identity_profile \u627E\u5230\u4F9D\u636E\u7684\u7A33\u5B9A\u7279\u5F81\uFF1B\u7981\u6B62\u670D\u88C5\u3001\u53F7\u7801\u3001\u5E3D\u5B50\u3001\u773C\u955C/\u914D\u9970\u3001\u5986\u5BB9\u3001\u8868\u60C5\u52A8\u4F5C\u3001\u4E34\u65F6\u4F24\u75D5\u6C61\u6E0D\u3001\u5267\u60C5\u8EAB\u4EFD\u80FD\u529B\u5173\u7CFB\u3001\u53D8\u8EAB\u5F62\u6001\u6216\u573A\u666F\u7269\u4EF6\uFF1B\u5730\u70B9/\u9053\u5177\u586B\u7A7A\u6570\u7EC4\" },\n identity_profile: IDENTITY_PROFILE,\n appearance: { type: \"string\", description: \"\u5730\u70B9/\u9053\u5177\u7684\u7A33\u5B9A\u53EF\u89C1\u63CF\u8FF0\uFF0C\u4EBA\u7269\u586B\u7A7A\u4E32\u3002\u5730\u70B9\u5199\u7A7A\u95F4\u7ED3\u6784\u3001\u6750\u8D28\u3001\u8272\u5F69\u548C\u56FA\u5B9A\u9648\u8BBE\uFF1B\u9053\u5177\u5199\u5F62\u5236\u3001\u6750\u8D28\u3001\u989C\u8272\u548C\u5C3A\u5BF8\u5173\u7CFB\" },\n role: { type: \"string\", description: \"\u5B9E\u4F53\u7684\u8EAB\u4EFD\u3001\u5173\u7CFB\u6216\u7528\u9014\uFF0C\u975E\u7A7A\uFF1B\u53EA\u5199\u539F\u7247\u53EF\u786E\u8BA4\u7684\u8BBE\u5B9A\" },\n states: { type: \"array\", items: DESCRIBED_STATE_ITEM, description: \"\u672C\u96C6\u8BE5\u5B9E\u4F53\u51FA\u73B0\u7684\u6301\u4E45\u89C6\u89C9\u72B6\u6001\u3002\u6BCF\u9879\u540C\u65F6\u7ED9\u51FA\u7B80\u6D01\u7A33\u5B9A\u72B6\u6001\u540D\u4E0E\u4ECE\u591A\u4E2A\u6E05\u6670\u955C\u5934\u6C47\u603B\u7684\u53EF\u590D\u73B0\u8BE6\u7EC6\u63CF\u8FF0\uFF1B\u6CA1\u6709\u72EC\u7ACB\u72B6\u6001\u586B\u7A7A\u6570\u7EC4\" },\n aliases: { type: \"array\", items: { type: \"string\" }, description: \"\u672C\u96C6\u89C1\u5230\u7684\u5176\u5B83\u79F0\u547C\" },\n },\n },\n },\n enrich: {\n type: \"array\",\n description: \"\u5BF9\u5DF2\u77E5\u8BBE\u5B9A\u91CC\u5DF2\u6709\u5B9E\u4F53\u7684\u8865\u5145/\u66F4\u6B63\uFF0C\u53EA\u5199\u53D1\u751F\u53D8\u5316\u7684\u5B57\u6BB5\uFF1B\u65E0\u53D8\u5316\u7684\u5B57\u6BB5\u586B\u7A7A\u4E32/\u7A7A\u6570\u7EC4\uFF0C\u6574\u4F53\u65E0\u53D8\u5316\u7684\u5B9E\u4F53\u4E0D\u8981\u51FA\u73B0\",\n items: {\n type: \"object\",\n required: [\"name\", \"add_recognition_anchors\", \"identity_profile_patch\", \"appearance\", \"role\", \"add_aliases\", \"add_states\"],\n additionalProperties: false,\n properties: {\n name: { type: \"string\", description: \"\u5DF2\u77E5\u5B9E\u4F53\u7684\u89C4\u8303\u540D\" },\n add_recognition_anchors: { type: \"array\", items: { type: \"string\" }, description: \"\u672C\u96C6\u65B0\u589E\u3001\u4E14\u6BCF\u4E2A\u8BCD\u90FD\u80FD\u7531 identity_profile \u7A33\u5B9A\u5B57\u6BB5\u652F\u6301\u7684\u9AD8\u533A\u5206\u5EA6\u4EBA\u7269\u91CD\u8BA4\u951A\u70B9\uFF1B\u7981\u6B62\u670D\u88C5\u914D\u9970\u3001\u8868\u60C5\u52A8\u4F5C\u3001\u4E34\u65F6\u5916\u89C2\u3001\u5267\u60C5\u8BBE\u5B9A\u548C\u53D8\u8EAB\u5F62\u6001\uFF1B\u6CA1\u6709\u586B\u7A7A\u6570\u7EC4\" },\n identity_profile_patch: IDENTITY_PROFILE,\n appearance: { type: \"string\", description: \"\u5730\u70B9/\u9053\u5177\u66F4\u51C6\u786E\u7684\u7A33\u5B9A\u5916\u89C2\uFF1B\u4EBA\u7269\u6216\u65E0\u66F4\u65B0\u586B\u7A7A\u4E32\" },\n role: { type: \"string\", description: \"\u66F4\u660E\u786E\u7684\u8EAB\u4EFD\uFF1B\u65E0\u66F4\u65B0\u586B\u7A7A\u4E32\" },\n add_aliases: { type: \"array\", items: { type: \"string\" }, description: \"\u672C\u96C6\u65B0\u51FA\u73B0\u7684\u79F0\u547C\" },\n add_states: { type: \"array\", items: DESCRIBED_STATE_ITEM, description: \"\u672C\u96C6\u9996\u6B21\u51FA\u73B0\u7684\u65B0\u72B6\u6001\uFF0C\u6216\u672C\u96C6\u4ECE\u66F4\u591A\u89D2\u5EA6\u83B7\u5F97\u4E86\u66F4\u6E05\u6670\u7EC6\u8282\u7684\u65E2\u6709\u72B6\u6001\uFF1B\u65E2\u6709\u72B6\u6001\u9010\u5B57\u6CBF\u7528\u5176 name\uFF0C\u4EE5\u540C\u540D\u9879\u8865\u5168\u6216\u66F4\u65B0\u8BE6\u7EC6 description\uFF0C\u4E0D\u53E6\u5EFA\u8FD1\u4E49\u72B6\u6001\" },\n },\n },\n },\n canonicalize: {\n type: \"array\",\n description: \"\u4EC5\u51ED\u672C\u96C6\u76F4\u63A5\u51FA\u73B0\u7684\u4E66\u9762\u6B63\u5F0F\u59D3\u540D\u6216\u53F0\u8BCD\u672C\u540D\uFF0C\u628A\u5DF2\u77E5\u4EBA\u7269\u7684\u63CF\u8FF0\u540D\u3001\u7B80\u79F0\u6216\u4E0D\u5B8C\u6574\u59D3\u540D\u5347\u7EA7\u4E3A\u66F4\u51C6\u786E\u7684\u89C4\u8303\u540D\uFF1B\u5267\u60C5\u63A8\u65AD\u4E0D\u80FD\u5355\u72EC\u4F5C\u4E3A\u6539\u540D\u8BC1\u636E\",\n items: {\n type: \"object\",\n required: [\"from_name\", \"canonical_name\", \"evidence\"],\n additionalProperties: false,\n properties: {\n from_name: { type: \"string\", description: \"\u5DF2\u77E5\u8BBE\u5B9A\u4E2D\u7684\u5F53\u524D\u89C4\u8303\u540D\u6216\u65E2\u6709\u522B\u540D\" },\n canonical_name: { type: \"string\", description: \"\u4E66\u9762\u6B63\u5F0F\u59D3\u540D\u6216\u53F0\u8BCD\u76F4\u63A5\u8BF4\u51FA\u7684\u672C\u540D\" },\n evidence: { type: \"string\", description: \"\u76F4\u63A5\u547D\u540D\u8BC1\u636E\uFF0C\u5FC5\u987B\u5305\u542B MM:SS \u65F6\u95F4\u6233\u4EE5\u53CA\u753B\u9762\u539F\u6587\u6216\u542C\u5230\u7684\u539F\u8BDD\" },\n },\n },\n },\n },\n },\n open_threads: {\n type: \"object\",\n required: [\"opened\", \"closed\"],\n additionalProperties: false,\n properties: {\n opened: { type: \"array\", description: \"\u672C\u96C6\u65B0\u5F00\u3001\u5C1A\u672A\u4EA4\u4EE3\u7ED3\u679C\u7684\u60AC\u5FF5/\u5173\u7CFB\u53D8\u5316\", items: { type: \"object\", required: [\"text\"], additionalProperties: false, properties: { text: { type: \"string\" } } } },\n closed: { type: \"array\", description: \"\u672C\u96C6\u4EA4\u4EE3\u4E86\u7ED3\u679C\u3001\u8981\u5173\u95ED\u7684\u5DF2\u77E5\u7EBF\u7D22 id\uFF08\u5982 t3_1\uFF09\", items: { type: \"object\", required: [\"ref\"], additionalProperties: false, properties: { ref: { type: \"string\" } } } },\n },\n },\n },\n};\n\n// Name-fix repair (\u00A7 ingest.name-fix): for each body name that resolved to no\n// registry entity, the model either merges it into an existing canonical or\n// declares it a genuinely new entity. Same two acts as the serial pass, no scenes.\nexport const NAME_FIX_SCHEMA: JsonSchema = {\n type: \"object\",\n required: [\"merges\", \"newEntities\"],\n additionalProperties: false,\n properties: {\n merges: {\n type: \"array\",\n description: \"\u672A\u767B\u8BB0\u540D\u5B57\u5176\u5B9E\u662F\u67D0\u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684\u522B\u540D\",\n items: {\n type: \"object\",\n required: [\"from\", \"into\"],\n additionalProperties: false,\n properties: {\n from: { type: \"string\", description: \"\u8FD9\u4E2A\u672A\u767B\u8BB0\u7684\u540D\u5B57\" },\n into: { type: \"string\", description: \"\u5B83\u6240\u6307\u7684\u5DF2\u767B\u8BB0\u5B9E\u4F53 canonical \u540D\" },\n },\n },\n },\n newEntities: {\n type: \"array\",\n description: \"\u786E\u5B9E\u662F\u5168\u65B0\u5B9E\u4F53\u7684\u540D\u5B57\uFF0C\u5404\u767B\u8BB0\u4E00\u6761\",\n items: {\n type: \"object\",\n required: [\"kind\", \"name\", \"description\", \"aliases\", \"defaultLook\"],\n additionalProperties: false,\n properties: {\n kind: { type: \"string\", enum: [\"actor\", \"location\", \"prop\"] },\n name: { type: \"string\", description: \"\u7EAF canonical \u540D\" },\n description: { type: \"string\", description: \"\u4E00\u53E5\u8BDD\u8EAB\u4EFD\uFF0C\u975E\u7A7A\uFF1B\u4EBA\u7269\u4E0D\u5199\u670D\u88C5\u9020\u578B\" },\n aliases: { type: \"array\", items: { type: \"string\" }, description: \"\u5176\u4ED6\u53EB\u6CD5\" },\n defaultLook: DEFAULT_LOOK_SCHEMA,\n },\n },\n },\n },\n};\n", "// ingest.episode-assets task (\u00A7 serial). The front gives ONLY the body (scenes +\n// dialogue/action, speakers by name) \u2014 no pre-extracted cast/props/look. Walking\n// episodes IN ORDER with a running context that starts EMPTY, the model discovers\n// entities, \u9020\u578B (looks), identity merges, and \u2014 per scene \u2014 who is\n// present, where, and in which look. Output is a structured Delta via native\n// tool-calling (SERIAL_DELTA_SCHEMA): `name` and `aliases` are separate fields, so\n// a canonical name can never be mangled by a markdown `\u540D | \u540D` delimiter \u2014 the\n// failure mode where a model that wrote `\u5927\u9AA8\u5934\uFF08Big Bones / Marcus Vale\uFF09` got\n// fragmented into ghost entities. Tool mode \u2192 serial profile must call functions.\n\nimport { emptyDelta, type Delta } from \"../../../domain/ingest/serial-context.js\";\nimport { SERIAL_DELTA_SCHEMA } from \"../schemas.js\";\nimport type { LlmTaskExecutor } from \"../../types.js\";\n\nexport const EPISODE_ASSETS_SYSTEM = [\n \"\u4F60\u662F\u5267\u672C\u8D44\u4EA7/\u9020\u578B\u6807\u6CE8\u5668\u3002\u524D\u6BB5\u53EA\u7ED9\u4E86\u6B63\u6587\uFF08\u573A\u666F\u3001\u53F0\u8BCD\u3001\u52A8\u4F5C\uFF09\uFF0C**\u6CA1\u6709\u4EFB\u4F55\u73B0\u6210\u7684\u4EBA\u7269/\u9053\u5177/\u9020\u578B\u6E05\u5355**\u2014\u2014\u8D44\u4EA7\u4E0E\u9020\u578B\u5168\u90E8\u7531\u4F60\u4ECE\u6B63\u6587\u91CC\u9010\u96C6\u53D1\u73B0\u3001\u9010\u96C6\u7EF4\u62A4\u3002\",\n \"\u7ED3\u5408\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\uFF08\u5230\u76EE\u524D\u4E3A\u6B62\u4F60\u5DF2\u5EFA\u7ACB\u7684\u767B\u8BB0\uFF09\u4E0E\u3010\u672C\u6BB5\u6B63\u6587\u3011\uFF0C\u8C03\u7528 `emit_delta` \u5DE5\u5177\u8FD4\u56DE\u4E00\u4E2A\u7ED3\u6784\u5316\u5BF9\u8C61\u8986\u76D6\u8FD9\u4E00\u6574\u6BB5\u7684\u6240\u6709\u51B3\u7B56\u3002\u7A7A\u6570\u7EC4\u5C31\u4F20 `[]`\u3002\",\n \"**\u3010\u672C\u6BB5\u6B63\u6587\u3011\u53EF\u80FD\u5305\u542B\u82E5\u5E72\u96C6**\uFF08\u6BCF\u96C6\u4EE5 `# ep_NNN` \u5F00\u5934\uFF09\uFF1B\u628A\u5B83\u4EEC\u5F53\u4F5C\u8FDE\u7EED\u63A8\u8FDB\u7684\u4E00\u6BB5\u6574\u4F53\u5904\u7406\uFF0C\u8DE8\u96C6\u6CBF\u7528\u540C\u4E00 canonical \u540D\u5B57\u3002\",\n \"\u59CB\u7EC8\u4F7F\u7528\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\u91CC\u7684\u65E2\u6709 canonical \u540D\u5B57\uFF1B\u540C\u4E00\u4E2A\u4EBA\u5168\u5267\u4FDD\u6301\u540C\u4E00\u540D\u5B57\u3002\",\n \"\u4EBA\u7269 canonical \u540D\u5FC5\u987B\u91C7\u7528\u3010\u672C\u6BB5\u6B63\u6587\u3011scene.actors \u6216 speaker \u4E2D\u51FA\u73B0\u7684\u539F\u6587\u59D3\u540D\u62FC\u5199\uFF1B\u5916\u8BED\u59D3\u540D\u4FDD\u6301\u5916\u8BED\u539F\u540D\uFF0C\u4E0D\u7FFB\u8BD1\u3001\u4E0D\u97F3\u8BD1\u3001\u4E0D\u6539\u6210\u4E2D\u6587\u540D\u3002\u79F0\u8C13\u3001\u7B80\u79F0\u548C\u8BD1\u540D\u53EA\u653E aliases \u6216 merges\uFF0C\u4E0D\u80FD\u53D6\u4EE3\u5DF2\u7ECF\u51FA\u73B0\u7684\u539F\u6587\u5168\u540D\u3002\",\n \"\",\n \"**newEntities \u2014\u2014 \u672C\u6BB5\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\u91CC\u8FD8\u6CA1\u6709\u7684\u5B9E\u4F53\uFF0C\u6BCF\u4E2A\u767B\u8BB0\u4E00\u6761**\uFF1A\",\n \" \u00B7 name = \u7EAF canonical \u540D\uFF0C**\u7EDD\u4E0D\u542B\u62EC\u53F7/\u659C\u6760/\u8BD1\u540D\u5939\u6CE8/\u5BF9\u767D\u6807\u8BB0**\uFF08\u4E0D\u8981 name=\u300EMarcus Vale\uFF08\u9A6C\u5E93\u65AF\u00B7\u7EF4\u5C14\uFF09\u300F\u6216\u300EMarcus Vale\uFF0C\u9B42\u8BED\u300F\uFF0C\u800C\u662F name=\u300EMarcus Vale\u300F\uFF09\u3002\u4EBA\u540D\u91C7\u7528\u6B63\u6587\u91CC\u51FA\u73B0\u7684\u539F\u6587\u5B8C\u6574\u59D3\u540D\u62FC\u5199\uFF08`Emily Cole` \u4E0D\u5F97\u6539\u6210 `\u827E\u7C73\u4E3D\u00B7\u79D1\u5C14`\uFF1B\u300E\u82CF\u82E5\u96EA\u300F\u4E0D\u7F29\u6210\u300E\u82E5\u96EA\u300F\uFF09\u3002\",\n \" \u00B7 aliases = \u8FD9\u6BB5\u91CC\u8BE5\u5B9E\u4F53\u7684**\u6240\u6709\u5176\u4ED6\u53EB\u6CD5**\uFF0C\u9010\u4E2A\u5355\u5217\uFF08\u7EAF\u540D\uFF0C\u522B\u5E26\u300E\uFF08\u5FC3\uFF09\u300F\u300E\uFF1A\u300F\u300E\uFF0C\u9B42\u8BED\u300F\u8FD9\u7C7B\u5BF9\u767D/\u60C5\u7EEA\u6807\u8BB0\uFF09\uFF1A\u522B\u540D\u3001\u8BD1\u540D\u3001\u524D\u4E16\u540D\u3001\u77ED\u540D/\u5168\u540D\u3001\u82F1\u6587\u539F\u540D\uFF0C**\u5C24\u5176\u5BF9\u767D\u8BF4\u8BDD\u4EBA\u5728\u6B63\u6587\u91CC\u7684\u5199\u6CD5**\u3002\u6B63\u6587\u8BF4\u8BDD\u4EBA\u5199\u300E\u4F0A\u6587\u00B7\u5E03\u9C81\u514B\u65AF\u300F\u800C\u4F60 canonical \u662F\u300E\u5927\u725B\u300F\u2192 \u628A\u300E\u4F0A\u6587\u00B7\u5E03\u9C81\u514B\u65AF\u300F\u653E\u8FDB aliases\uFF1B\u5199\u300E\u5927\u9AA8\u300F\u800C canonical \u662F\u300E\u5927\u9AA8\u5934\u300F\u2192 aliases \u653E\u300E\u5927\u9AA8\u300F\u3002\u7CFB\u7EDF\u9760 aliases \u628A\u6B63\u6587\u91CC\u7684\u8BF4\u8BDD\u4EBA/\u79F0\u547C\u5F52\u5230\u4F60\u8FD9\u4E2A\u5B9E\u4F53\uFF0C**aliases \u6F0F\u4E86\u5C31\u4F1A\u65B0\u9020\u91CD\u590D\u9B3C\u5F71**\u3002\",\n \" \u00B7 **\u540C\u4E00\u4E2A\u5B9E\u4F53\u53EA\u767B\u8BB0\u4E00\u6761\uFF0C\u7EDD\u4E0D\u62C6\u6210\u591A\u6761**\u3002**\u4E0D\u540C\u7684\u89D2\u8272\u7EDD\u4E0D\u4E92\u76F8\u5217\u4E3A\u522B\u540D**\u2014\u2014\u54EA\u6015\u5173\u7CFB\u5BC6\u5207\u3001\u5E38\u540C\u6846\uFF1A\u5927\u725B \u548C \u4E39\u5C3C\u00B7\u514B\u7F57\u65AF \u662F\u4E24\u4E2A\u4EBA\uFF0C\u522B\u628A\u4E39\u5C3C\u7684\u540D\u5B57\u5199\u8FDB\u5927\u725B\u7684 aliases\uFF0C\u53CD\u4E4B\u4EA6\u7136\u3002\u5224\u636E\uFF1Aaliases \u53EA\u653E**\u540C\u4E00\u4E2A\u4EBA/\u7269**\u7684\u4E0D\u540C\u53EB\u6CD5\uFF0C\u4E0D\u653E\u53E6\u4E00\u4E2A\u89D2\u8272\u3002\",\n \" \u00B7 kind=actor/location/prop\u3002\",\n \" \u00B7 description=\u4E00\u53E5\u8BDD\u8BF4\u660E**\u8FD9\u4E2A\u5B9E\u4F53\u672C\u8EAB\u662F\u8C01 / \u4EC0\u4E48\u8EAB\u4EFD / \u4EC0\u4E48\u4E1C\u897F**\uFF0C\u975E\u7A7A\u3002\u4EBA\u7269\u53EA\u5199\u8EAB\u4EFD\u3001\u89D2\u8272\u3001\u5173\u7CFB\uFF0C\u4E0D\u5199\u670D\u88C5\u9020\u578B\uFF1B\u7EDD\u4E0D\u5199\u5B83\u6240\u5904\u7684\u573A\u666F / \u73AF\u5883 / \u5730\u70B9 / \u5F53\u65F6\u5728\u53D1\u751F\u4EC0\u4E48\u3002\u539F\u6587\u6709\u8EAB\u4EFD\u4FE1\u606F\u5C31\u7167\u6284 / \u6982\u62EC\uFF1B\u539F\u6587\u6CA1\u5199\u5C31\u636E\u53F0\u8BCD / \u79F0\u547C / \u620F\u4EFD\u8865\u4E00\u53E5\u6700\u7B80\u8EAB\u4EFD\uFF08\u5982\u300E\u82CF\u5BB6\u4E2D\u95F4\u4EBA\u300F\u300E\u6025\u8BCA\u62A4\u58EB\u300F\u300E\u8D75\u957F\u6CB3\u7684\u624B\u4E0B\u300F\uFF09\u3002\u573A\u666F\u5199\u7A7A\u95F4\u7528\u9014\uFF1B\u9053\u5177\u5199\u7269\u4EF6\u7528\u9014\u3002\",\n \" \u00B7 defaultLook=\u5B9E\u4F53\u9996\u6B21\u767B\u8BB0\u65F6\u5FC5\u586B\u7684**\u9ED8\u8BA4\u9020\u578B**\uFF1Aname \u56FA\u5B9A\u5199\u300E\u5E38\u6001\u300F\uFF1Bdescription \u5199\u53EF\u76F4\u63A5\u7528\u4E8E\u89C6\u89C9\u590D\u73B0\u7684\u5916\u8C8C\u3001\u670D\u9970\u3001\u6750\u8D28\u3001\u989C\u8272\u3001\u5E03\u666F\u6216\u5F62\u5236\uFF0C\u975E\u7A7A\u3002\u4EBA\u7269\u8EAB\u4EFD\u4E0E\u5173\u7CFB\u4E0D\u80FD\u62FF\u6765\u5145\u5F53\u9020\u578B\u63CF\u8FF0\u3002\u4F18\u5148\u91C7\u7528\u539F\u6587\u660E\u786E\u63CF\u5199\uFF1B\u539F\u6587\u4FE1\u606F\u4E0D\u8DB3\u65F6\uFF0C\u7ED3\u5408\u5B9E\u4F53\u8EAB\u4EFD\u4E0E\u540C\u573A\u89C6\u89C9\u4FE1\u606F\u8865\u6210\u6700\u7B80\u3001\u7A33\u5B9A\u3001\u53EF\u753B\u7684\u5E38\u6001\u9020\u578B\u3002\",\n \" \u00B7 **\u767B\u8BB0\u8303\u56F4**\uFF1A\u4EBA\u7269\u2014\u2014\u767B\u8BB0\u6BCF\u4E2A\u80FD\u72EC\u7ACB\u8BF4\u8BDD\u3001\u62FF\u53D6\u6216\u4EA4\u63A5\u9053\u5177\u3001\u63A8\u52A8\u52A8\u4F5C\u7684\u5177\u4F53\u5355\u4EBA\u89D2\u8272\uFF1B\u4F17\u4EBA\u3001\u7FA4\u4F17\u3001\u8DEF\u4EBA\u3001\u8F7F\u592B4\u540D\u7B49\u65E0\u6CD5\u533A\u5206\u6210\u5458\u7684\u7FA4\u4F53\u4E0D\u767B\u8BB0\u4E3A actor\uFF0C\u7FA4\u4F53\u5171\u540C\u53D1\u58F0\u7531\u6B63\u6587\u7684 group speaker \u627F\u8F7D\u3002\u5730\u70B9\u2014\u2014\u6BCF\u4E2A\u53EF\u72EC\u7ACB\u5E03\u7F6E\u548C\u91CD\u590D\u5F15\u7528\u7684\u7A33\u5B9A\u7269\u7406\u7A7A\u95F4\u5404\u767B\u8BB0\u4E00\u6B21\uFF1B\u5BA2\u5385\u3001\u5367\u5BA4\u3001\u536B\u751F\u95F4\u3001\u5927\u5385\u3001\u5E7F\u573A\u3001\u821E\u53F0\u3001\u540E\u53F0\u5206\u522B\u767B\u8BB0\uFF0C\u76F8\u5173\u7A7A\u95F4\u7528\u300E\u8C6A\u5B85\u00B7\u5BA2\u5385\u300F\u300E\u8C6A\u5B85\u00B7\u5367\u5BA4\u300F\u8868\u8FBE\u5F52\u5C5E\u3002\u5730\u70B9\u5176\u5B83\u5199\u6CD5\u7528 merges \u5F52\u4E00\u3002\u9053\u5177\u2014\u2014**\u53EA\u767B\u8BB0\u5173\u952E\u9053\u5177**\uFF1A\u2460\u5267\u60C5\u5173\u952E\uFF08\u4FE1\u7269/\u7EBF\u7D22/\u63A8\u52A8\u60C5\u8282\uFF0C\u5982\u7B2C\u4E00\u96C6\u4E22\u4E86\u7B2C\u4E09\u96C6\u5BFB\u56DE\u7684\u624B\u673A\uFF09\u6216 \u2461\u8DE8\u22652\u573A\u9700\u7A33\u5B9A\u590D\u73B0\u3001\u8981\u7F8E\u672F\u4FDD\u6301\u4E00\u81F4\u7684\u7269\u4EF6\uFF1B\u4E00\u6B21\u6027/\u7EAF\u529F\u80FD/\u89C6\u89C9\u65E0\u9700\u8FFD\u8E2A\u7684\uFF08\u968F\u624B\u6253\u7535\u8BDD\u7684\u624B\u673A\u3001\u80CC\u666F\u676F\u5B50/\u8DEF\u4EBA\u8F66\uFF09\u4E0D\u767B\u8BB0\u3002\",\n \" \u00B7 \u5DF2\u767B\u8BB0\u8FC7\u7684\u5B9E\u4F53\u4E0D\u8981\u91CD\u590D\u767B\u8BB0\uFF1B\u82E5\u5B83\u8FD9\u6BB5\u6709\u4E86\u65B0\u53EB\u6CD5\uFF0C\u7528 merges \u8865\uFF0C\u4E0D\u7528\u5728 newEntities \u518D\u5217\u4E00\u904D\u3002\",\n \"**merges \u2014\u2014 \u672C\u6BB5\u5192\u51FA\u4E00\u4E2A\u79F0\u547C\uFF0C\u5176\u5B9E\u662F\u67D0\u4E2A\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\u91CC\u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684\u522B\u540D\uFF08\u5C1A\u672A\u767B\u8BB0\u8FC7\u8FD9\u4E2A\u79F0\u547C\uFF09**\uFF1A{from: \u672C\u6BB5\u8FD9\u4E2A\u79F0\u547C, into: \u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684 canonical}\u3002\u5224\u636E\uFF1A(1) \u5B57\u9762\u53D8\u4F53\uFF08\u5927\u9AA8=\u5927\u9AA8\u5934=\u5927\u9AA8\uFF08BigBull\uFF09\u3001\u82CF\u82E5\u96EA=\u82E5\u96EA\uFF09\uFF1B(2) \u5267\u60C5\u63A8\u65AD\u540C\u4E00\uFF08\u4E0A\u4E0B\u6587/\u5916\u89C2/\u5173\u7CFB/\u8FDE\u7EED\u52A8\u4F5C\uFF0C\u5982\u524D\u6587\u300E\u5C0F\u9AA8\u300F\u672C\u6BB5\u70B9\u540D\u300E\u6770\u514B\u00B7\u83B1\u5FB7\u300F\uFF09\u3002**\u53EA\u6709\u5F53 from \u786E\u5B9E\u662F into \u7684\u53E6\u4E00\u53EB\u6CD5\u65F6\u624D merge\uFF1B\u540D\u5B57\u6216\u5916\u89C2\u76F8\u4F3C\u4F46\u662F\u4E0D\u540C\u89D2\u8272\uFF08\u5982\u540C\u4E3A\u9AB7\u9AC5\u4F46\u8EAB\u4EFD\u4E0D\u540C\uFF09\u7EDD\u4E0D merge\u3002** from \u5DF2\u7ECF\u662F\u72EC\u7ACB\u767B\u8BB0\u7684\u5B9E\u4F53\u65F6\uFF0C\u4E0D\u8981 merge\uFF08\u7CFB\u7EDF\u4E0D\u4F1A\u5408\u5E76\u4E24\u4E2A\u5DF2\u767B\u8BB0\u5B9E\u4F53\uFF09\u3002\",\n \" \u00B7 **\u5730\u70B9\u540C\u6837\u8981 merge\u2014\u2014\u5224\u636E\u4E00\u6837\uFF1A\u662F\u4E0D\u662F\u540C\u4E00\u4E2A\u573A**\u3002\u540C\u4E00\u4E2A\u5730\u65B9\u7684\u4E0D\u540C\u5199\u6CD5\u8981\u5408\u6210\u4E00\u6761\uFF1A\u2460\u5B57\u9762\u53D8\u4F53\uFF08\u300E\u8F66\u8F6E\u65C1\u300F\u300E\u77FF\u8F66\u8F66\u8F6E\u65C1\u300F\u300E\u77FF\u8F66\u8F66\u8F6E\u300F\u662F\u540C\u4E00\u5904\uFF1B\u5E26\u4E0D\u5E26\u5E73\u53F0/\u533A\u57DF\u524D\u7F00\u5982\u300EDawnfall Online - \u68FA\u6728\u94FA\u300F=\u300E\u68FA\u6728\u94FA\u300F\uFF09\uFF1B\u2461\u5267\u60C5\u786E\u5B9A\u540C\u4E00\u5904\uFF08\u540C\u4E00\u573A\u620F\u5728\u540C\u4E00\u7A7A\u95F4\u53D1\u751F\uFF09\u3002**\u4E0D\u662F\u540C\u4E00\u4E2A\u573A\u5C31\u5404\u81EA\u72EC\u7ACB**\uFF08\u77FF\u8F68\u4FEE\u9020\u94FA \u548C \u68FA\u6728\u94FA \u662F\u4E24\u4E2A\u5730\u65B9\uFF0C\u4E0D\u5408\uFF09\u3002\u522B\u56E0\u4E3A\u5199\u6CD5\u5E26\u4E86\u957F\u524D\u7F00\u5C31\u5F53\u6210\u65B0\u5730\u70B9\u3002\",\n \"**\u6B63\u6587\u91CC\u6BCF\u4E2A\u548C\u5DF2\u767B\u8BB0 canonical \u5199\u6CD5\u4E0D\u540C\u7684\u540D\u5B57\uFF0C\u90FD\u8981\u7528 merges \u5F52\u8FC7\u53BB**\u2014\u2014\u7CFB\u7EDF\u4F1A\u7167 merges + aliases \u628A\u6B63\u6587\uFF08\u5BF9\u767D\u8BF4\u8BDD\u4EBA\u3001\u65C1\u767D\u6587\u672C\uFF09\u91CC\u7684\u8FD9\u4E9B\u5199\u6CD5\u76F4\u63A5\u6539\u5199\u6210 canonical\u3002**\u6F0F\u6389\u67D0\u4E2A\u5199\u6CD5\uFF0C\u5B83\u5C31\u4F1A\u53D8\u6210\u4E00\u4E2A\u6E38\u79BB\u7684\u91CD\u590D\u5B9E\u4F53\u3002** \u6240\u4EE5\u672C\u6BB5\u6B63\u6587\u91CC\u51FA\u73B0\u7684\u6BCF\u4E2A\u4EBA\u540D/\u79F0\u547C\uFF0C\u8981\u4E48\u672C\u8EAB\u5C31\u662F\u67D0 canonical\uFF0C\u8981\u4E48\u5728 aliases/merges \u91CC\u767B\u8BB0\u8FC7\u3002\",\n \"looks\uFF1A\u9ED8\u8BA4\u9020\u578B\u4E4B\u5916\u3001\u9700\u8981\u5355\u72EC\u590D\u73B0\u7684\u65B0\u589E\u9020\u578B\u3002entity=\u5B9E\u4F53 canonical \u540D\uFF1Bname=\u9020\u578B\u540D\uFF1Baliases=\u540C\u4E49\u9020\u578B\u540D\uFF1Bdescription=\u8FD9\u5957\u5916\u89C2\u4E00\u53E5\u8BDD\u3002\",\n \" **\u590D\u7528\u4F18\u5148\u2014\u2014\u9020\u578B\u9ED8\u8BA4\u4ECE\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\u91CC\u8BE5\u5B9E\u4F53\u5DF2\u5217\u51FA\u7684\u9020\u578B\u6E05\u5355\u91CC\u9009\u4E00\u4E2A\uFF0C\u9010\u5B57\u7167\u6284\u90A3\u4E2A\u5DF2\u6709\u9020\u578B\u540D**\u3002\u9664\u975E\u672C\u6BB5\u5916\u89C2\u4E0E\u6240\u6709\u5DF2\u6709\u9020\u578B\u90FD\u6709\u5B9E\u8D28\u5DEE\u5F02\uFF08\u6362\u4E86\u6574\u5957\u8863\u670D/\u573A\u666F\u88AB\u6BC1/\u9053\u5177\u660E\u663E\u6539\u5F62\uFF09\uFF0C\u624D\u65B0\u5F00\u4E00\u6761\u9020\u578B\u3002\u4E0D\u8981\u56E0\u4E3A\u672C\u6BB5\u539F\u6587\u7528\u8BCD\u4E0D\u540C\u5C31\u53E6\u9020\u8FD1\u4E49\u65B0\u540D\u2014\u2014\u5DF2\u77E5\u8BBE\u5B9A\u91CC\u5DF2\u6709\u300E\u9ED1\u8272\u8FDE\u5E3D\u536B\u8863\u300F\uFF0C\u672C\u6BB5\u53C8\u89C1\u9ED1\u8272\u536B\u8863\uFF0C\u7167\u6284\u300E\u9ED1\u8272\u8FDE\u5E3D\u536B\u8863\u300F\u5373\u53EF\uFF1B\u540C\u4E49\u6362\u540D\u53EA\u4F1A\u628A\u540C\u4E00\u5957\u8863\u670D\u62C6\u6210\u591A\u5F20\u56FE\u3002\",\n \" \u9ED8\u8BA4\u9020\u578B\u53EA\u5199\u5728 newEntities.defaultLook\uFF0C\u4E0D\u8981\u5728 looks \u91CC\u91CD\u590D\uFF1Blooks \u53EA\u767B\u8BB0\u6362\u88C5\u3001\u53D8\u8EAB\u3001\u573A\u666F\u88AB\u6BC1\u3001\u9053\u5177\u7834\u635F/\u53D1\u5149\u7B49\u989D\u5916\u9020\u578B\u3002\u4EBA\u7269=\u6574\u4F53\u626E\u76F8\uFF1B\u573A\u666F=\u73AF\u5883\u5916\u89C2\uFF1B\u9053\u5177=\u7269\u4EF6\u5916\u89C2\u3002\",\n \" \u9020\u578B\u540D=\u9700\u8981\u7F8E\u672F\u5355\u72EC\u753B\u4E00\u5F20\u56FE\u7684\u5916\u89C2\u6863\u4F4D\uFF08\u5E38\u6001\u3001\u5A5A\u670D\u3001\u897F\u88C5\u3001\u9F99\u5F62\uFF1B\u573A\u666F\u7684 \u767D\u5929/\u591C\u665A/\u88AB\u6BC1\uFF1B\u9053\u5177\u7684 \u7834\u635F/\u53D1\u5149\uFF09\u3002**\u9020\u578B\u540D\u5FC5\u987B\u7528\u4E2D\u6587**\uFF1A\u6B63\u6587\u91CC\u7684\u82F1\u6587\u4E13\u540D\uFF08\u5957\u88C5/\u804C\u4E1A/\u5F62\u6001\u540D\uFF0C\u5982 Sean's Revenge\u3001Flamecaster\u3001Grave Priest\u3001Shieldguard\uFF09\u4E00\u5F8B\u8BD1\u6210\u4E2D\u6587\u518D\u4F5C\u9020\u578B\u540D\uFF08\u8096\u6069\u7684\u590D\u4EC7\u5957\u88C5\u3001\u7130\u672F\u5E08\u3001\u5893\u796D\u53F8\u3001\u76FE\u536B\uFF09\u3002\",\n \" description=\u8FD9\u5957\u5916\u89C2\u957F\u4EC0\u4E48\u6837\u7684\u4E00\u53E5\u8BDD\uFF08\u4F18\u5148\u7528\u539F\u6587\u63CF\u5199\uFF1A\u670D\u9970/\u989C\u8272/\u53D1\u578B/\u914D\u9970\uFF0C\u6216\u573A\u666F\u5E03\u666F/\u9053\u5177\u5F62\u5236\uFF09\u3002**\u5E38\u6001 description \u4E0D\u80FD\u7559\u7A7A\u3002\u7EDD\u4E0D\u5199\u5FC3\u60C5/\u8EAB\u4F53\u72B6\u51B5/\u80D6\u7626**\uFF08\u6EE1\u8138\u6CEA\u75D5\u3001\u6124\u6012\u3001\u865A\u5F31\u6FD2\u6B7B\u3001\u53D7\u4F24\u3001\u660F\u8FF7\u3001\u6D88\u7626\u2014\u2014\u8FD9\u4E9B\u4E0D\u662F\u9020\u578B\uFF1B\u5224\u636E\uFF1A\u6362\u6210\u5B83\uFF0C\u7F8E\u672F\u8981\u4E0D\u8981\u53E6\u753B\u4E00\u5F20\u56FE\uFF09\u3002\",\n \"**lookChanges \u2014\u2014 \u9020\u578B\u53D8\u5316\uFF08\u7A00\u758F\uFF0C\u53EA\u6807\u53D8\u5316\u5904\uFF09**\uFF1A\u67D0\u4E2A\u5B9E\u4F53\u7684\u9020\u578B\u4ECE\u67D0\u4E00\u573A\u8D77\u53D8\u4E86\uFF0C\u5C31\u6807\u4E00\u6761 {scene, entity, look}\u3002scene=\u53D8\u5316\u53D1\u751F\u7684\u573A\u666Fid\uFF08scn_012\uFF09\uFF1Bentity=canonical \u540D\uFF1Blook=\u4ECE\u8FD9\u573A\u8D77\u7A7F\u7684\u9020\u578B\uFF08\u5FC5\u987B\u662F\u4F60\u5728 looks \u91CC\u6CE8\u518C\u8FC7\u7684\u6863\u4F4D\u540D\uFF09\u3002\",\n \" \u00B7 **\u53EA\u6807\u9020\u578B\u771F\u7684\u6539\u53D8\u7684\u90A3\u4E00\u573A**\uFF08\u6362\u88C5/\u53D8\u8EAB/\u53D7\u635F/\u56DE\u5F52\u65E5\u5E38\uFF09\u3002\u4F8B\uFF1A\u5927\u9AA8\u5934\u5728 scn_050 \u53D8\u8EAB\u7130\u672F\u5E08 \u2192 {scene:scn_050, entity:\u5927\u9AA8\u5934, look:\u7130\u672F\u5E08\u6001}\uFF1B\u540E\u9762\u82E5\u6362\u56DE\u5E38\u6001\uFF0C\u5728\u90A3\u4E00\u573A\u518D\u6807 {..., look:\u5E38\u6001}\u3002\",\n \" \u00B7 \u6CA1\u53D8\u5316\u7684\u573A**\u4E0D\u7528\u6807**\u2014\u2014\u7CFB\u7EDF\u81EA\u52A8\u6CBF\u7528\u4E0A\u4E00\u6B21\u7684\u9020\u578B\u4E00\u76F4\u5230\u4E0B\u4E00\u6B21\u53D8\u5316\u3002\u9996\u6B21\u51FA\u73B0\u9ED8\u8BA4\u5E38\u6001\uFF0C\u4E5F\u4E0D\u7528\u7279\u610F\u6807\u3002\",\n \" \u00B7 \u4F60**\u4E0D\u9700\u8981**\u5217\u51FA\u6BCF\u4E00\u573A\u8C01\u5728\u573A\u2014\u2014\u8C01\u5728\u573A\u7CFB\u7EDF\u76F4\u63A5\u4ECE\u6B63\u6587\uFF08\u5BF9\u767D\u8BF4\u8BDD\u4EBA\u3001\u65C1\u767D\uFF09\u8BFB\uFF0C\u4F60\u53EA\u7BA1\u6CE8\u518C\u5B9E\u4F53\u3001\u5F52\u4E00\u540D\u5B57\u3001\u6807\u9020\u578B\u53D8\u5316\u3002\",\n \"subEvents\uFF1A\u672C\u6BB5\u5173\u952E\u5267\u60C5\u539F\u5B50\uFF0C\u6BCF\u6761\u4E00\u53E5\u8BDD\uFF08\u7EF4\u62A4\u5267\u60C5\u7406\u89E3\u4E0E\u538B\u7F29\uFF09\u3002\",\n \"summary\uFF1A\u672C\u6BB5\u4E00\u53E5\u8BDD\u6897\u6982\uFF1B\u82E5\u672C\u6BB5\u542B\u591A\u96C6\uFF0C\u6982\u62EC\u4E3A\u6574\u6BB5\u4E00\u53E5\u8BDD\u3002\",\n].join(\"\\n\");\n\nexport function buildEpisodeAssetsUser(contextMd: string, bodyMd: string): string {\n return [\n \"\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\uFF08\u622A\u81F3\u4E0A\u4E00\u6BB5\u4F60\u5DF2\u5EFA\u7ACB\u7684\u767B\u8BB0\uFF1B\u5F00\u7BC7\u65F6\u4E3A\u7A7A\uFF09\",\n contextMd.trim() || \"\uFF08\u7A7A\uFF0C\u4ECE\u8FD9\u4E00\u6BB5\u5F00\u59CB\u5EFA\u7ACB\uFF09\",\n \"\",\n \"\u3010\u672C\u6BB5\u6B63\u6587\u3011\uFF08\u53EF\u80FD\u542B\u591A\u96C6\uFF0C\u6BCF\u96C6\u4EE5 `# ep_NNN` \u5F00\u5934\uFF09\",\n bodyMd.trim(),\n ].join(\"\\n\");\n}\n\nexport async function runEpisodeAssets(executor: LlmTaskExecutor, contextMd: string, bodyMd: string, signal?: AbortSignal): Promise<{ delta: Delta; raw: string }> {\n const response = await executor.generateTool(\"ingest.episode-assets\", {\n system: EPISODE_ASSETS_SYSTEM,\n user: buildEpisodeAssetsUser(contextMd, bodyMd),\n tool: { name: \"emit_delta\", description: \"\u8FD4\u56DE\u672C\u6BB5\u7684\u8D44\u4EA7/\u9020\u578B/\u573A\u666F Delta\", inputSchema: SERIAL_DELTA_SCHEMA },\n ...(signal ? { signal } : {}),\n });\n return { delta: toDelta(response.input), raw: JSON.stringify(response.input) };\n}\n\n// Schema-validated tool input \u2192 Delta. The schema guarantees shape, so this is a\n// straight, defensive projection: entity `aliases` become immediate merges into\n// the canonical name (so translations/past-life/alt names fold in), and look\n// name+aliases become the `names[]` list (names[0]=canonical) applyDelta expects.\n//\n// Models (and some tool bridges) still occasionally emit array fields as JSON\n// *strings* (double-encoded), sometimes with unescaped quotes inside. Historically\n// `arr()` treated any non-array as `[]` and serial silently dropped every entity /\n// look for that window. We now re-parse stringified arrays and **throw** on shape\n// failure so the window can retry instead of shipping an empty registry.\nconst KIND = new Set([\"actor\", \"location\", \"prop\"]);\nconst isObj = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst str = (v: unknown): string => (typeof v === \"string\" ? v.trim() : \"\");\n\nfunction requiredString(value: unknown, field: string): string {\n const parsed = str(value);\n if (!parsed) throw new SerialDeltaShapeError(`${field}: expected non-empty string`);\n return parsed;\n}\n\nfunction parseDefaultLook(value: unknown, field: string): { name: string; description: string } {\n if (!isObj(value)) throw new SerialDeltaShapeError(`${field}: expected object`);\n const name = requiredString(value.name, `${field}.name`);\n if (name !== \"\u5E38\u6001\") throw new SerialDeltaShapeError(`${field}.name: expected \u5E38\u6001`);\n return { name, description: requiredString(value.description, `${field}.description`) };\n}\n\n/** Thrown when a serial delta field is not a usable array (incl. failed re-parse). */\nexport class SerialDeltaShapeError extends Error {\n readonly code = \"serial_delta_shape\" as const;\n constructor(message: string) {\n super(message);\n this.name = \"SerialDeltaShapeError\";\n }\n}\n\n/**\n * Best-effort repair when the model double-encodes an array as a JSON string and\n * uses bare `\"` as Chinese quotation marks inside values\n * (e.g. `\u5E02\u4E2D\u5FC3\"\u91D1\u9CDE\"\u5546\u4E1A\u5730\u76AE`, `\u7687\u51A0\"\u4E16\u7EAA\u4E4B\u661F\"`). Strict JSON.parse fails; we\n * walk the text as JSON-ish strings and escape interior `\"` that cannot close a\n * value (next non-ws is not `,` `}` `]` `:` or EOF). Only applied after a strict\n * parse fails \u2014 callers must not use this on already-valid JSON.\n */\nexport function repairDoubleEncodedJson(raw: string): string {\n let out = \"\";\n let inString = false;\n for (let i = 0; i < raw.length; i++) {\n const c = raw[i]!;\n if (!inString) {\n out += c;\n if (c === '\"') inString = true;\n continue;\n }\n if (c === \"\\\\\" && i + 1 < raw.length) {\n out += c + raw[i + 1];\n i++;\n continue;\n }\n if (c === '\"') {\n let j = i + 1;\n while (j < raw.length && /\\s/.test(raw[j]!)) j++;\n const next = j < raw.length ? raw[j]! : \"\";\n // Structural close of a JSON string (key or value).\n if (next === \"\" || next === \",\" || next === \"}\" || next === \"]\" || next === \":\") {\n out += c;\n inString = false;\n } else {\n // Interior bare quote (Chinese quotation marks etc.) \u2192 escape.\n out += '\\\\\"';\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction parseJsonArrayString(t: string, field: string): unknown[] {\n const tryParse = (s: string): unknown => JSON.parse(s);\n let parsed: unknown;\n try {\n parsed = tryParse(t);\n } catch (first) {\n const repaired = repairDoubleEncodedJson(t);\n if (repaired === t) {\n throw new SerialDeltaShapeError(\n `${field}: expected JSON array string, parse failed: ${first instanceof Error ? first.message : String(first)}`,\n );\n }\n try {\n parsed = tryParse(repaired);\n } catch (second) {\n throw new SerialDeltaShapeError(\n `${field}: expected JSON array string, parse failed after quote-repair: ${second instanceof Error ? second.message : String(second)}`,\n );\n }\n }\n if (!Array.isArray(parsed)) {\n throw new SerialDeltaShapeError(`${field}: expected JSON array string, got ${typeof parsed}`);\n }\n return parsed;\n}\n\n/**\n * Coerce a tool field to an array. Accepts real arrays, null/undefined/\"\" \u2192 [],\n * and JSON-encoded array strings (double-encoding, with quote-repair). Anything\n * else throws \u2014 never silently collapses to [].\n */\nexport function coerceJsonArray(v: unknown, field: string): unknown[] {\n if (v == null) return [];\n if (Array.isArray(v)) return v;\n if (typeof v === \"string\") {\n const t = v.trim();\n if (!t) return [];\n return parseJsonArrayString(t, field);\n }\n throw new SerialDeltaShapeError(`${field}: expected array, got ${typeof v}`);\n}\n\n// Deterministic backstop for the one thing the model still slips on: a canonical\n// name carrying an inline paren annotation \u2014 `\u5927\u9AA8\u5934\uFF08Big Bones / Marcus Vale\uFF09`,\n// `\u94F6\u857E\u4E1D(SilverLace)`. The schema asks for name/aliases split, but a few leak\n// through, so we split mechanically here (100% reliable, model-independent): the\n// text before the first paren is the clean name; the paren's inner content, split\n// on / , \u3001; separators, is preserved as aliases (never discarded \u2014 an inline\n// annotation is the source explicitly declaring the alias mapping). Tolerates an\n// unclosed paren (`\u5927\u9AA8\uFF08Big Bones`). A leading paren (no name before it) is left\n// whole \u2014 it isn't a name annotation.\nconst PAREN_RE = /[\uFF08(]([^\uFF09)]*)[\uFF09)]?/;\nfunction splitParen(raw: string): { name: string; aliases: string[] } {\n const s = str(raw);\n const m = PAREN_RE.exec(s);\n if (!m) return { name: s, aliases: [] };\n const name = s.slice(0, m.index).trim();\n if (!name) return { name: s, aliases: [] };\n const aliases = (m[1] ?? \"\").split(/[/\uFF0F,\uFF0C\u3001;\uFF1B]/).map((x) => x.trim()).filter(Boolean);\n return { name, aliases };\n}\nconst cleanName = (raw: unknown): string => splitParen(str(raw)).name;\n\nfunction asDeltaObject(input: unknown): Record<string, unknown> | null {\n if (isObj(input)) return input;\n if (typeof input === \"string\") {\n const t = input.trim();\n if (!t) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(t);\n } catch (e) {\n throw new SerialDeltaShapeError(\n `delta: top-level JSON string failed to parse: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n if (!isObj(parsed)) {\n throw new SerialDeltaShapeError(`delta: top-level JSON string must be an object, got ${typeof parsed}`);\n }\n return parsed;\n }\n return null;\n}\n\nexport function toDelta(input: unknown): Delta {\n const d = emptyDelta();\n const obj = asDeltaObject(input);\n if (!obj) return d;\n for (const e of coerceJsonArray(obj.newEntities, \"newEntities\")) {\n if (!isObj(e)) continue;\n const kind = str(e.kind);\n const { name, aliases: parenAliases } = splitParen(str(e.name));\n if (!KIND.has(kind) || !name) continue;\n const description = requiredString(e.description, `newEntities.${name}.description`);\n const defaultLook = parseDefaultLook(e.defaultLook, `newEntities.${name}.defaultLook`);\n // Every \u53EB\u6CD5 \u2192 clean alias. A declared alias may ITSELF carry a paren\n // (`\u65E7\u836F\u7BB1\uFF08\u5E26\u4E09\u89D2\u5212\u75D5\uFF09`) \u2014 split it, else the polluted form registers as an\n // alias and its extra length promotes it to canonical (fuller-name rule).\n const aliasNames = [...parenAliases];\n for (const a of coerceJsonArray(e.aliases, \"newEntities.aliases\")) {\n const { name: base, aliases: inner } = splitParen(str(a));\n if (base) aliasNames.push(base);\n aliasNames.push(...inner);\n }\n const aliases = [...new Set(aliasNames.filter((a) => a && a !== name))];\n d.newEntities.push({ name, kind: kind as \"actor\" | \"location\" | \"prop\", description, aliases, defaultLook });\n }\n for (const m of coerceJsonArray(obj.merges, \"merges\")) {\n if (!isObj(m)) continue;\n const from = cleanName(m.from);\n const into = cleanName(m.into);\n if (from && into && from !== into) d.merges.push({ from, into });\n }\n for (const l of coerceJsonArray(obj.looks, \"looks\")) {\n if (!isObj(l)) continue;\n const entity = cleanName(l.entity);\n const name = cleanName(l.name);\n if (!entity || !name) continue;\n const names = [name, ...coerceJsonArray(l.aliases, \"looks.aliases\").map(cleanName).filter(Boolean)];\n d.looks.push({ entity, names, description: requiredString(l.description, `looks.${entity}.${name}.description`) });\n }\n for (const c of coerceJsonArray(obj.lookChanges, \"lookChanges\")) {\n if (!isObj(c)) continue;\n const scene = str(c.scene);\n const entity = cleanName(c.entity);\n const look = cleanName(c.look);\n if (scene && entity && look) d.lookChanges.push({ scene, entity, look });\n }\n d.subEvents = coerceJsonArray(obj.subEvents, \"subEvents\").map(str).filter(Boolean);\n d.summary = str(obj.summary);\n return d;\n}\n", "// ingest.name-fix task (\u00A7 serial repair). After the serial pass, some names appear\n// in the body but resolve to NO registry entity \u2014 the model missed a merge. Rather\n// than mint ghost assets, we ask once: for each such name, is it another\u53EB\u6CD5 of an\n// already-registered entity (\u2192 merge), or a genuinely new entity (\u2192 newEntity)?\n// Output is a Delta with only newEntities + merges. New entities carry their\n// required default look inline. Tool mode.\n\nimport type { Delta } from \"../../../domain/ingest/serial-context.js\";\nimport { NAME_FIX_SCHEMA } from \"../schemas.js\";\nimport type { LlmTaskExecutor } from \"../../types.js\";\nimport { SerialDeltaShapeError, toDelta } from \"./episode-assets.js\";\n\nexport const NAME_FIX_SYSTEM = [\n \"\u4F60\u662F\u5267\u672C\u5B9E\u4F53\u5F52\u4E00\u4FEE\u590D\u5668\u3002\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\u662F\u5DF2\u5EFA\u7ACB\u7684\u5B9E\u4F53\u767B\u8BB0\uFF08register\uFF09\u3002\u4E0B\u9762\u3010\u5F85\u5F52\u4E00\u540D\u5B57\u3011\u662F\u6B63\u6587\u91CC\u51FA\u73B0\u3001\u4F46\u8FD8\u6CA1\u80FD\u5BF9\u5E94\u5230 register \u91CC\u4EFB\u4F55\u5B9E\u4F53\u7684\u540D\u5B57\u3002\",\n \"\u5BF9**\u6BCF\u4E00\u4E2A**\u5F85\u5F52\u4E00\u540D\u5B57\uFF0C\u5224\u65AD\u5B83\u662F\u4E0D\u662F register \u91CC\u67D0\u4E2A\u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684\u53E6\u4E00\u79CD\u53EB\u6CD5\uFF1A\",\n \" \u00B7 **\u662F**\uFF08\u5B57\u9762\u53D8\u4F53\u5982 \u5927\u9AA8=\u5927\u9AA8\u5934\u3001\u82CF\u82E5\u96EA=\u82E5\u96EA\uFF1B\u6216\u5267\u60C5/\u8EAB\u4EFD\u80FD\u786E\u5B9A\u662F\u540C\u4E00\u4E2A\uFF0C\u5982\u524D\u4E16\u540D/\u5316\u540D/\u5168\u540D\u77ED\u540D\uFF09\u2192 \u653E\u8FDB `merges`\uFF1A{from: \u8FD9\u4E2A\u540D\u5B57, into: \u5DF2\u767B\u8BB0\u5B9E\u4F53\u7684 canonical}\u3002\",\n \" \u00B7 **\u4E0D\u662F**\uFF08\u5B83\u786E\u5B9E\u662F register \u91CC\u4ECE\u6CA1\u767B\u8BB0\u8FC7\u7684\u4E00\u4E2A\u65B0\u5B9E\u4F53\uFF09\u2192 \u653E\u8FDB `newEntities`\uFF1A{kind, name(\u7EAF canonical), description(\u4E00\u53E5\u8BDD\u8EAB\u4EFD), aliases, defaultLook:{name:'\u5E38\u6001', description:\u53EF\u89C1\u5916\u89C2}}\u3002\",\n \"\u65B0\u4EBA\u7269\u7684 canonical name \u76F4\u63A5\u4F7F\u7528\u3010\u5F85\u5F52\u4E00\u540D\u5B57\u3011\u91CC\u7684\u539F\u6587\u59D3\u540D\u62FC\u5199\uFF1B\u5916\u8BED\u59D3\u540D\u4E0D\u7FFB\u8BD1\u3001\u4E0D\u97F3\u8BD1\u3001\u4E0D\u6539\u6210\u4E2D\u6587\u540D\u3002\",\n \"\u4EBA\u7269 description \u53EA\u5199\u8EAB\u4EFD\u3001\u89D2\u8272\u548C\u5173\u7CFB\uFF1BdefaultLook.description \u5199\u5916\u8C8C\u3001\u670D\u9970\u7B49\u53EF\u76F4\u63A5\u590D\u73B0\u7684\u9ED8\u8BA4\u9020\u578B\uFF0C\u4E24\u8005\u4E0D\u80FD\u4E92\u76F8\u4EE3\u66FF\u3002\",\n \"**\u4E0D\u540C\u89D2\u8272\u7EDD\u4E0D\u4E92\u76F8\u5F53\u522B\u540D**\u3002\u62FF\u4E0D\u51C6\u662F\u54EA\u4E00\u4E2A\u5DF2\u6709\u5B9E\u4F53\u65F6\uFF0C\u5B81\u53EF\u5F53\u65B0\u5B9E\u4F53\u767B\u8BB0\uFF0C\u4E5F\u4E0D\u8981 merge \u9519\u4EBA\u3002\",\n \"\u5730\u70B9\u540C\u7406\uFF1A\u540C\u4E00\u4E2A\u5730\u65B9\u7684\u4E0D\u540C\u5199\u6CD5\uFF08\u5E26\u4E0D\u5E26\u5E73\u53F0/\u533A\u57DF\u524D\u7F00\u3001\u300E\u8F66\u8F6E\u65C1\u300F=\u300E\u77FF\u8F66\u8F66\u8F6E\u65C1\u300F\uFF09merge \u5230\u5DF2\u6709\u90A3\u6761\uFF1B\u786E\u5B9E\u662F\u65B0\u5730\u65B9\u624D newEntity\u3002\",\n \"\u53EA\u8F93\u51FA merges \u548C newEntities \u4E24\u9879\uFF0C\u8986\u76D6**\u6BCF\u4E00\u4E2A**\u5F85\u5F52\u4E00\u540D\u5B57\u3002\",\n].join(\"\\n\");\n\nexport function buildNameFixUser(contextMd: string, names: string[]): string {\n return [\n \"\u3010\u5DF2\u77E5\u8BBE\u5B9A\u3011\uFF08\u5DF2\u767B\u8BB0\u7684\u5B9E\u4F53\uFF09\",\n contextMd.trim() || \"\uFF08\u7A7A\uFF09\",\n \"\",\n \"\u3010\u5F85\u5F52\u4E00\u540D\u5B57\u3011\uFF08\u6B63\u6587\u91CC\u51FA\u73B0\u4F46\u672A\u5BF9\u5E94\u5230\u4EFB\u4F55\u5DF2\u767B\u8BB0\u5B9E\u4F53\uFF0C\u9010\u4E2A\u5904\u7406\uFF09\",\n names.map((n) => `- ${n}`).join(\"\\n\"),\n ].join(\"\\n\");\n}\n\n// Runs the fix and returns a Delta carrying only its newEntities + merges.\nexport async function runNameFix(executor: LlmTaskExecutor, contextMd: string, names: string[], signal?: AbortSignal): Promise<{ delta: Delta; raw: string }> {\n const response = await executor.generateTool(\"ingest.name-fix\", {\n system: NAME_FIX_SYSTEM,\n user: buildNameFixUser(contextMd, names),\n tool: { name: \"emit_fix\", description: \"\u628A\u5F85\u5F52\u4E00\u540D\u5B57 merge \u5230\u5DF2\u6709\u6216\u767B\u8BB0\u4E3A\u65B0\u5B9E\u4F53\", inputSchema: NAME_FIX_SCHEMA },\n ...(signal ? { signal } : {}),\n });\n return { delta: nameFixToDelta(response.input, names), raw: JSON.stringify(response.input) };\n}\n\nconst nameKey = (value: string): string => value.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n\nexport function nameFixToDelta(input: unknown, names: string[] = []): Delta {\n const delta = toDelta(input);\n const covered = new Set<string>();\n for (const merge of delta.merges) covered.add(nameKey(merge.from));\n for (const entity of delta.newEntities) {\n covered.add(nameKey(entity.name));\n for (const alias of entity.aliases) covered.add(nameKey(alias));\n }\n const missing = names.filter((name) => !covered.has(nameKey(name)));\n if (missing.length) {\n throw new SerialDeltaShapeError(`name-fix did not cover: ${missing.join(\"\u3001\")}`);\n }\n return delta;\n}\n", "// Serial governance orchestrator (\u00A7 serial), incremental. Input is the name-based\n// body (assembled NameScript) \u2014 NOT the roster. It walks episodes IN ORDER with a\n// context that starts EMPTY: per episode the model reads that episode's body plus\n// the context-so-far and reports discovered entities / \u9020\u578B / and per\n// scene who is present in which look. Nothing is seeded from the front's extracted\n// assets/states.\n//\n// The final v3 is built FROM the accumulated registry: the serial scene refs are\n// injected into the body, assignProvisionalIds mints ids + assets, the registry's\n// descriptions/looks are overlaid, and governDeterministic materializes.\n// Per-episode md checkpoint + transient-retry as before.\n\nimport { CliError, EXIT_INPUT } from \"../../common.js\";\nimport {\n assignProvisionalIds,\n type NameScript,\n type NameScene,\n type StructuralIdentityKeys,\n} from \"../../domain/ingest/assembler.js\";\nimport { governDeterministic } from \"../../domain/ingest/govern.js\";\nimport { emptyContext, applyDelta, compact, pendingArcFold, applyArcFold, synopsisLabel, render, resolveCanon, findEntity, baseLook, estimateTokens, packEpisodes, isCrowdName, type GlobalContext, type Delta } from \"../../domain/ingest/serial-context.js\";\nimport { runArcSummary } from \"../../llm/tasks/ingest/arc-summary.js\";\nimport { runEpisodeAssets, toDelta, SerialDeltaShapeError } from \"../../llm/tasks/ingest/episode-assets.js\";\nimport { runNameFix, nameFixToDelta } from \"../../llm/tasks/ingest/name-fix.js\";\nimport type { Importance } from \"../../domain/script/shared/types.js\";\nimport type { LlmTaskExecutor } from \"../../llm/types.js\";\n\nexport interface SerialCheckpoint {\n // Keyed by the window's [startEp, endEp] range (a window covers 1+ contiguous\n // episodes parsed together); resume re-packs identically and hits the cache.\n readUpdate(startEp: number, endEp: number): string | undefined;\n writeStep(startEp: number, endEp: number, contextMd: string, updateMd: string): void;\n // Arc summaries are keyed by the folded episode range so resume replays them\n // from cache (no repeated LLM); the range is deterministic (pure compaction).\n readArc?(startEp: number, endEp: number): string | undefined;\n writeArc?(startEp: number, endEp: number, summaryMd: string): void;\n // Per-window name-fix repair (raw tool JSON), keyed by the window range so\n // resume replays it from cache like the window update itself.\n readNameFix?(startEp: number, endEp: number): string | undefined;\n writeNameFix?(startEp: number, endEp: number, raw: string): void;\n}\nexport interface SerialWindowTiming { startEp: number; endEp: number; ms: number; cached: boolean; index: number; total: number; totalEpisodes: number }\nexport interface SerialGovernOptions {\n executor: LlmTaskExecutor;\n signal?: AbortSignal;\n checkpoint?: SerialCheckpoint;\n force?: boolean;\n windowTokens?: number;\n // Original front matter (\u89D2\u8272\u5361/\u8BBE\u5B9A) that pass0 stripped, capped \u2014 fed to the\n // model as \u539F\u6587\u8BBE\u5B9A reference so descriptions can lean on the source's own wording.\n sourceRef?: string;\n // Fired after each window (parsed or cached), with its wall-clock ms \u2014 drives\n // the live timing/ETA in `view --watch` and `ingest status`.\n onWindow?: (t: SerialWindowTiming) => void;\n}\nexport interface SerialGovernResult {\n doc: Record<string, unknown>;\n identityKeys: StructuralIdentityKeys;\n episodes: number;\n reused: number;\n}\n\ntype Obj = Record<string, unknown>;\nconst isObj = (v: unknown): v is Obj => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst isArr = (v: unknown): v is unknown[] => Array.isArray(v);\n\n// featured iff an asset appears at \u22652 points in the global action stream AND those\n// points span \u2265 this many actions apart \u2014 a real recurring presence, not a single\n// scene's chatter. Tunable after observing results.\nconst FEATURED_MIN_SPAN = 5;\nconst norm = (s: string): string => s.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n// A checkpointed window is the tool's raw JSON. Top-level parse failure \u2192 null so\n// the caller can re-run the window instead of projecting an empty Delta (the old\n// `{}` fallback silently wiped entity/look registration for that window).\nconst parseRaw = (raw: string): unknown | null => {\n try { return JSON.parse(raw); } catch { return null; }\n};\n\n// Include serial_delta_shape so double-encoded / unparseable array fields re-call\n// the model instead of shipping an empty registry for the window.\n// A successful HTTP response can still omit the forced tool call, return an empty\n// body, or stop before the structured payload is complete. Those are transient\n// generation failures in an ingest window, just like a timeout: retry the same\n// semantic unit before asking the outer caller to resume the whole workspace.\nconst RETRYABLE = new Set([\n \"timeout\",\n \"rate_limited\",\n \"request_failed\",\n \"endpoint\",\n \"empty_response\",\n \"invalid_response\",\n \"truncated\",\n \"serial_delta_shape\",\n]);\nconst isRetryable = (e: unknown): boolean =>\n !!e && typeof e === \"object\" && \"code\" in e && RETRYABLE.has(String((e as { code: unknown }).code));\nconst sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\nconst winLabel = (startEp: number, endEp: number): string => (startEp === endEp ? `episode ${startEp}` : `episodes ${startEp}-${endEp}`);\n\nasync function windowUpdate(executor: LlmTaskExecutor, startEp: number, endEp: number, contextMd: string, bodyMd: string, signal?: AbortSignal): Promise<{ delta: Delta; raw: string }> {\n for (let attempt = 1; ; attempt++) {\n try {\n return await runEpisodeAssets(executor, contextMd, bodyMd, signal);\n } catch (e) {\n if (isRetryable(e) && attempt < 3 && !signal?.aborted) { await sleep(3000 * attempt); continue; }\n throw new CliError(`serial govern failed at ${winLabel(startEp, endEp)}.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SERIAL_FAILED\",\n hint: e instanceof SerialDeltaShapeError\n ? `Model returned a malformed serial delta (${e.message}). Rerun \\`scriptctl ingest\\` (optionally --force) to retry ${winLabel(startEp, endEp)}.`\n : `Rerun \\`scriptctl ingest\\` to resume from ${winLabel(startEp, endEp)} (earlier windows are cached).`,\n data: { actual: [e instanceof Error ? e.message : String(e)] },\n });\n }\n }\n}\n\nfunction assertNameFixTargets(ctx: GlobalContext, delta: Delta): void {\n const missing = delta.merges\n .map((merge) => merge.into)\n .filter((target) => !findEntity(ctx, target));\n if (missing.length) {\n throw new SerialDeltaShapeError(`name-fix merge target is not registered: ${[...new Set(missing)].join(\"\u3001\")}`);\n }\n}\n\n// Name-fix is required for every unresolved actor/location. A structurally valid\n// but incomplete repair is retried in the same window instead of reaching govern\n// as an asset with empty semantics.\nasync function nameFixRetry(\n executor: LlmTaskExecutor,\n startEp: number,\n endEp: number,\n contextMd: string,\n names: string[],\n ctx: GlobalContext,\n signal?: AbortSignal,\n): Promise<{ delta: Delta; raw: string }> {\n for (let attempt = 1; ; attempt++) {\n try {\n const produced = await runNameFix(executor, contextMd, names, signal);\n assertNameFixTargets(ctx, produced.delta);\n return produced;\n } catch (e) {\n if (isRetryable(e) && attempt < 3 && !signal?.aborted) { await sleep(3000 * attempt); continue; }\n throw new CliError(`serial name repair failed at ${winLabel(startEp, endEp)}.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SERIAL_NAME_FIX_FAILED\",\n hint: e instanceof SerialDeltaShapeError\n ? `Model returned an incomplete name repair (${e.message}). Rerun \\`scriptctl ingest\\` to retry ${winLabel(startEp, endEp)}.`\n : `Rerun \\`scriptctl ingest\\` to resume from ${winLabel(startEp, endEp)} (earlier windows are cached).`,\n data: { actual: [e instanceof Error ? e.message : String(e)] },\n });\n }\n }\n}\n\nexport async function runSerialGovern(body: NameScript, opts: SerialGovernOptions): Promise<SerialGovernResult> {\n const ctx = emptyContext();\n const episodes = body.episodes ?? [];\n let reused = 0;\n\n // Pack contiguous episodes into token-bounded windows and parse each window in\n // one call. Bodies + token sizes are precomputed so packing is deterministic.\n const bodies = episodes.map(renderEpisodeBody);\n const windows = packEpisodes(bodies.map(estimateTokens), opts.windowTokens);\n\n for (let index = 0; index < windows.length; index++) {\n const [startEp, endEp] = windows[index]!;\n const contextMd = render(ctx, endEp);\n // Each body already opens with `# ep_NNN`, so the model sees the episode splits.\n const bodyMd = bodies.slice(startEp - 1, endEp).join(\"\\n\\n\");\n\n // Prepend the source \u539F\u6587\u8BBE\u5B9A reference (static) to what the model sees; the\n // checkpoint trace stores only the registry contextMd (the ref is redundant 23\u00D7).\n const promptCtx = opts.sourceRef ? `# \u539F\u6587\u8BBE\u5B9A\uFF08\u53C2\u8003\uFF0C\u6765\u81EA\u539F\u7A3F\u5F00\u5934\uFF09\\n${opts.sourceRef}\\n\\n${contextMd}` : contextMd;\n\n const t0 = Date.now();\n // The checkpoint stores the window's raw tool JSON; resume re-projects it to a\n // Delta (deterministic), so a cached window costs no model call. Corrupt or\n // shape-invalid cache (double-encoded garbage, unescaped quotes) is re-run \u2014\n // never applied as an empty Delta.\n const cached = opts.force ? undefined : opts.checkpoint?.readUpdate(startEp, endEp);\n let delta: Delta;\n let cachedHit = false;\n if (cached !== undefined) {\n const parsed = parseRaw(cached);\n try {\n if (parsed == null) throw new SerialDeltaShapeError(\"checkpoint top-level JSON is unparseable\");\n delta = toDelta(parsed);\n cachedHit = true;\n reused++;\n opts.executor.recordReuse(\"ingest.episode-assets\");\n } catch (e) {\n if (!(e instanceof SerialDeltaShapeError)) throw e;\n const produced = await windowUpdate(opts.executor, startEp, endEp, promptCtx, bodyMd, opts.signal);\n delta = produced.delta;\n opts.checkpoint?.writeStep(startEp, endEp, contextMd, produced.raw);\n }\n } else {\n const produced = await windowUpdate(opts.executor, startEp, endEp, promptCtx, bodyMd, opts.signal);\n delta = produced.delta;\n opts.checkpoint?.writeStep(startEp, endEp, contextMd, produced.raw);\n }\n applyDelta(ctx, delta, startEp, endEp);\n\n // Name-fix repair, IN THIS WINDOW (whichever window meets an unregistered name\n // fixes it here, not in a giant final pass). After applying this window's delta,\n // any actor/location the body names but the registry still can't resolve is a\n // missed merge \u2014 ask the model (merge-into-existing or new) and apply, so the\n // registry is complete before we move on. Best-effort: a gateway failure skips\n // the fix for this window (names ship as-is) rather than aborting the run.\n const unresolved = collectUnresolved(episodes.slice(startEp - 1, endEp), ctx);\n if (unresolved.length) {\n const cachedFix = opts.force ? undefined : opts.checkpoint?.readNameFix?.(startEp, endEp);\n if (cachedFix !== undefined) {\n const parsedFix = parseRaw(cachedFix);\n try {\n if (parsedFix == null) throw new SerialDeltaShapeError(\"name-fix checkpoint top-level JSON is unparseable\");\n const fixDelta = nameFixToDelta(parsedFix, unresolved);\n assertNameFixTargets(ctx, fixDelta);\n applyDelta(ctx, fixDelta, startEp, endEp);\n reused++;\n opts.executor.recordReuse(\"ingest.name-fix\");\n } catch (e) {\n if (!(e instanceof SerialDeltaShapeError)) throw e;\n const produced = await nameFixRetry(opts.executor, startEp, endEp, render(ctx, endEp), unresolved, ctx, opts.signal);\n opts.checkpoint?.writeNameFix?.(startEp, endEp, produced.raw);\n applyDelta(ctx, produced.delta, startEp, endEp);\n }\n } else {\n const produced = await nameFixRetry(opts.executor, startEp, endEp, render(ctx, endEp), unresolved, ctx, opts.signal);\n opts.checkpoint?.writeNameFix?.(startEp, endEp, produced.raw);\n applyDelta(ctx, produced.delta, startEp, endEp);\n }\n }\n\n compact(ctx);\n // Fold the far synopsis into arc summaries when over budget. Deterministic\n // range \u2192 cached by [startEp, endEp] so resume never re-summarizes.\n for (let group = pendingArcFold(ctx); group; group = pendingArcFold(ctx)) {\n const startEp = group[0]!.startEp;\n const endEp = group[group.length - 1]!.endEp;\n const cachedArc = opts.force ? undefined : opts.checkpoint?.readArc?.(startEp, endEp);\n let summary: string;\n if (cachedArc !== undefined) {\n summary = cachedArc;\n reused++;\n opts.executor.recordReuse(\"ingest.arc-summary\");\n }\n else {\n const foldedText = group.map((g) => `${synopsisLabel(g)}\uFF1A${g.line}`).join(\"\\n\");\n summary = await runArcSummary(opts.executor, `\u7B2C${startEp}\u96C6\u2013\u7B2C${endEp}\u96C6`, foldedText, opts.signal);\n opts.checkpoint?.writeArc?.(startEp, endEp, summary);\n }\n applyArcFold(ctx, summary);\n }\n opts.onWindow?.({ startEp, endEp, ms: Date.now() - t0, cached: cachedHit, index, total: windows.length, totalEpisodes: episodes.length });\n }\n\n const finalized = finalize(body, ctx);\n return {\n ...finalized,\n episodes: episodes.length,\n reused,\n };\n}\n\n// Body ACTOR/LOCATION names (in the given episodes) that resolve to no registry\n// entity \u2014 a missed merge worth repairing (a real character/place the serial pass\n// forgot to register). PROPS are excluded on purpose: the body lists every\n// incidental object, but the registry deliberately keeps only \u5173\u952E\u9053\u5177, so an\n// unregistered prop is a background object we DROP (finalize skips it), not a fix.\nfunction collectUnresolved(eps: NameScript[\"episodes\"], ctx: GlobalContext): string[] {\n const set = new Set<string>();\n const check = (name: string | undefined): void => {\n if (!name) return;\n const canon = resolveCanon(ctx, name);\n if (isCrowdName(canon)) return;\n if (!findEntity(ctx, canon)) set.add(canon);\n };\n for (const ep of eps) {\n for (const sc of ep.scenes) {\n check(sc.location?.name);\n for (const a of sc.actors) check(a.name);\n for (const ac of sc.actions) if (ac.speaker && \"name\" in ac.speaker) check(ac.speaker.name);\n }\n }\n return [...set];\n}\n\nconst SPACE: Record<string, string> = { interior: \"\u5185\", exterior: \"\u5916\" };\nconst TIME: Record<string, string> = { day: \"\u65E5\", night: \"\u591C\" };\n\n// Render one episode's body as readable \u6B63\u6587 \u2014 scene id + time/space + the source's\n// declared \u5730\u70B9/\u5728\u573A/\u9053\u5177 (so the model can lean on the original text's own names +\n// descriptions) + the action/dialogue lines (speaker by name). Inline descriptions\n// live in the action text; the model still emits its own scene presence refs.\nexport function renderEpisodeBody(ep: { episode_id: string; title?: string; scenes: NameScene[] }): string {\n const out: string[] = [`# ${ep.episode_id}${ep.title ? ` ${ep.title}` : \"\"}`];\n for (const sc of ep.scenes) {\n out.push(`## ${sc.scene_id}`);\n const env = [SPACE[sc.environment?.space ?? \"\"], TIME[sc.environment?.time ?? \"\"]].filter(Boolean).join(\" \");\n if (env) out.push(`\u65F6\u7A7A\uFF1A${env}`);\n if (sc.location?.name) out.push(`\u5730\u70B9\uFF1A${sc.location.name}`);\n if (sc.actors.length) out.push(`\u5728\u573A\uFF1A${sc.actors.map((a) => a.name).join(\"\u3001\")}`);\n if (sc.props.length) out.push(`\u9053\u5177\uFF1A${sc.props.map((p) => p.name).join(\"\u3001\")}`);\n for (const ac of sc.actions) {\n const sp = ac.speaker ? (\"name\" in ac.speaker ? ac.speaker.name : `[${ac.speaker.kind}]`) : \"\";\n const emo = ac.emotion ? `\uFF08${ac.emotion}\uFF09` : \"\";\n if (ac.type === \"dialogue\") out.push(`${sp}${emo}\uFF1A${ac.content}`);\n else if (ac.type === \"inner_thought\") out.push(`${sp}\uFF08\u5FC3\uFF09${emo}\uFF1A${ac.content}`);\n else if (ac.type === \"transition\") out.push(`\u3010\u8F6C\u573A\u3011${ac.content}`);\n else out.push(ac.content);\n }\n }\n return out.join(\"\\n\");\n}\n\n// Build the final v3 doc from the body + accumulated registry. Inject serial scene\n// refs (canonical names + look as state), mint ids via assignProvisionalIds, overlay\n// registry description/aliases/look-descriptions, then materialize.\nfunction finalize(\n body: NameScript,\n ctx: GlobalContext,\n): { doc: Record<string, unknown>; identityKeys: StructuralIdentityKeys } {\n const doc: NameScript = JSON.parse(JSON.stringify(body));\n // The BODY (from normalize) is the source of who's on screen and every dialogue\n // line \u2014 the model's job was only to build the registry + correct the names. So\n // here we resolve every body-written name to its registry canonical (this IS the\n // \"correct the transcript\" step), rewrite dialogue text likewise, and derive each\n // scene's \u9020\u578B from the sparse lookChanges carried forward. The model's scene\n // presence lists are NOT used.\n const carry = new Map<string, string>(); // canonical \u2192 current \u9020\u578B (continuity)\n for (const ep of doc.episodes) {\n for (const sc of ep.scenes) {\n // register is the source of truth: keep only refs that resolve to a\n // registered entity. Unregistered names are dropped (an unregistered prop is a\n // background object; any actor/location worth keeping was fixed by name-fix).\n const reg = (n: string): boolean => !!findEntity(ctx, n);\n const loc = sc.location ? resolveCanon(ctx, sc.location.name) : null;\n let actors = dedupeNames(sc.actors.map((a) => resolveCanon(ctx, a.name)).filter((n) => !isCrowdName(n) && reg(n)));\n const props = dedupeNames(sc.props.map((p) => resolveCanon(ctx, p.name)).filter(reg));\n const speaking: string[] = [];\n for (const ac of sc.actions) {\n if (ac.speaker && \"name\" in ac.speaker) {\n const canon = resolveCanon(ctx, ac.speaker.name);\n if (isCrowdName(canon)) ac.speaker = { kind: \"group\", label: canon };\n else { ac.speaker.name = canon; if (reg(canon)) speaking.push(canon); }\n }\n // ponytail: \u53EA\u5F52\u4E00 speaker\uFF0C\u6B63\u6587 content \u9010\u5B57\u4FDD\u7559\u3002\u522B\u540D\u5B57\u7B26\u4E32\u66FF\u6362\u4F1A\n // \u53CC\u66FF\uFF08\u5723\u5178\u2192\u82F1\u96C4\u5723\u5178 \u547D\u4E2D\u5DF2\u6709 \u82F1\u96C4\u5723\u5178\uFF09\u5E76\u8BEF\u6539\u753B\u9762/\u5B57\u5E55\u539F\u6587\uFF08RELIC\u3001\n // CHRONICLE OF HEROES \u7B49 UI \u5B57\u9762\uFF09\u3002\u8981\u6062\u590D\u6B63\u6587\u6539\u540D\u987B\u505A\u5B9E\u4F53\u611F\u77E5\u66FF\u6362\uFF0C\u975E\u6734\u7D20 split/join\u3002\n }\n for (const canon of speaking) if (!actors.some((n) => norm(n) === norm(canon))) actors.push(canon); // speaker \u21D2 present\n // \u9020\u578B: apply this scene's changes to the carry, then stamp each ref (inherit).\n for (const lc of ctx.lookChanges[sc.scene_id] ?? []) carry.set(resolveCanon(ctx, lc.entity), lc.look);\n sc.location = loc && reg(loc) ? stateRef(ctx, loc, carry) : null;\n sc.actors = actors.map((n) => stateRef(ctx, n, carry));\n sc.props = props.map((n) => stateRef(ctx, n, carry));\n }\n }\n\n const assigned = assignProvisionalIds(doc);\n const script = assigned.script;\n overlay(script, ctx);\n applyImportance(script); // deterministic: override model/registry tiers by on-screen span\n const governed = governDeterministic(script);\n renameSyntheticDefault(governed);\n assertDescriptions(governed);\n return { doc: governed, identityKeys: assigned.identityKeys };\n}\n\nconst RESET = \"\u5E38\u6001\";\n\n// De-dupe a list of already-resolved canonical names, keeping first-seen order.\nfunction dedupeNames(names: string[]): string[] {\n const seen = new Set<string>();\n return names.filter((n) => { const k = norm(n); if (!n || seen.has(k)) return false; seen.add(k); return true; });\n}\n\n// A canonical name + its \u9020\u578B for a scene: the carried look, else the entity's\n// baseline \u5E38\u6001. Every on-screen ref binds a state (never null/\u672A\u6807\u6CE8).\nfunction stateRef(ctx: GlobalContext, canon: string, carry: Map<string, string>): { name: string; state?: string } {\n const e = findEntity(ctx, canon);\n const look = carry.get(canon) ?? (e ? baseLook(e) : undefined) ?? RESET;\n return { name: canon, state: look };\n}\n\n// Assets with no discovered look keep a synthetic default whose name leaked as the\n// literal \"default\"; relabel it to \u5E38\u6001 for a meaningful baseline.\nfunction renameSyntheticDefault(script: Obj): void {\n for (const listKey of [\"actors\", \"locations\", \"props\"] as const) {\n for (const asset of isArr(script[listKey]) ? (script[listKey] as unknown[]) : []) {\n if (!isObj(asset)) continue;\n for (const st of isArr(asset.states) ? asset.states : []) {\n if (isObj(st) && st.state_id === \"default\" && st.state_name === \"default\") st.state_name = \"\u5E38\u6001\";\n }\n }\n }\n}\n\n// Stamp registry descriptions, aliases, and per-look state descriptions onto the\n// minted assets. Importance is derived later from the complete action stream.\nfunction overlay(script: Obj, ctx: GlobalContext): void {\n for (const [listKey, nameKey] of [[\"actors\", \"actor_name\"], [\"locations\", \"location_name\"], [\"props\", \"prop_name\"]] as const) {\n for (const asset of isArr(script[listKey]) ? (script[listKey] as unknown[]) : []) {\n if (!isObj(asset)) continue;\n const e = findEntity(ctx, String(asset[nameKey]));\n const states = isArr(asset.states) ? asset.states : [];\n if (e) {\n if (e.description) asset.description = e.description;\n if (e.aliases.length) asset.aliases = [...new Set([...(isArr(asset.aliases) ? (asset.aliases as string[]) : []), ...e.aliases])];\n const baseName = baseLook(e); // baseline (\u5E38\u6001) look NAME for the synthetic default state\n const baseDesc = baseName ? (e.looks.find((l) => norm(l.name) === norm(baseName))?.description ?? \"\") : \"\";\n for (const st of states) {\n if (!isObj(st)) continue;\n if (st.state_id === \"default\") { if (baseDesc) st.description = baseDesc; continue; }\n const look = e.looks.find((l) => norm(l.name) === norm(String(st.state_name)));\n if (look?.description) st.description = look.description;\n }\n }\n }\n }\n}\n\n// Deterministic importance (\u00A7 replaces the model's judgment call). Walk the whole\n// doc as one ordered action stream; every asset records the action index of each\n// point it's \"on screen\" \u2014 a dialogue/inner-thought speaker at that action, or a\n// member of a scene's cast/props/location (counted at the scene's first action).\n// featured iff it surfaces at \u22652 points spanning \u2265 FEATURED_MIN_SPAN actions apart;\n// everything else background. Fully overrides whatever overlay stamped.\nfunction applyImportance(script: Obj): void {\n const first = new Map<string, number>(); // assetId \u2192 first on-screen action index\n const last = new Map<string, number>(); // assetId \u2192 last on-screen action index\n const count = new Map<string, number>(); // assetId \u2192 number of on-screen points\n let idx = 0;\n const mark = (id: unknown): void => {\n if (typeof id !== \"string\") return;\n if (!first.has(id)) first.set(id, idx);\n last.set(id, idx);\n count.set(id, (count.get(id) ?? 0) + 1);\n };\n for (const ep of isArr(script.episodes) ? script.episodes : []) {\n if (!isObj(ep) || !isArr(ep.scenes)) continue;\n for (const sc of ep.scenes) {\n if (!isObj(sc)) continue;\n // Scene membership (cast/props/location) counts at the scene's first action.\n const members: unknown[] = [\n ...(isArr(sc.actors) ? sc.actors : []),\n ...(isArr(sc.props) ? sc.props : []),\n ...(isObj(sc.location) ? [sc.location] : []),\n ];\n const memberIds = members.filter(isObj).map((m) => m.actor_id ?? m.prop_id ?? m.location_id);\n for (const id of memberIds) mark(id);\n for (const ac of isArr(sc.actions) ? sc.actions : []) {\n if (isObj(ac) && isObj(ac.speaker) && typeof ac.speaker.actor_id === \"string\") mark(ac.speaker.actor_id);\n idx++; // every action advances the global stream, speaker or not\n }\n }\n }\n const featured = (id: string): boolean =>\n (count.get(id) ?? 0) >= 2 && (last.get(id)! - first.get(id)!) >= FEATURED_MIN_SPAN;\n for (const [listKey, idKey] of [[\"actors\", \"actor_id\"], [\"props\", \"prop_id\"]] as const) {\n for (const asset of isArr(script[listKey]) ? (script[listKey] as unknown[]) : []) {\n if (!isObj(asset)) continue;\n asset.importance = (featured(String(asset[idKey])) ? \"featured\" : \"background\") as Importance;\n }\n }\n // Locations are always featured \u2014 every place that reaches the script is worth a\n // background plate; there is no \"\u9F99\u5957 location\" to skip.\n for (const asset of isArr(script.locations) ? (script.locations as unknown[]) : []) {\n if (isObj(asset)) asset.importance = \"featured\" as Importance;\n }\n}\n\n// Final invariant after governDeterministic has rebuilt state ids: identity and\n// look descriptions must already be complete. Missing content is an ingest error;\n// identity text is never copied into a look to manufacture completeness.\nfunction assertDescriptions(script: Obj): void {\n const nonEmpty = (v: unknown): string => (typeof v === \"string\" ? v.trim() : \"\");\n for (const [listKey, nameKey] of [[\"actors\", \"actor_name\"], [\"locations\", \"location_name\"], [\"props\", \"prop_name\"]] as const) {\n for (const asset of isArr(script[listKey]) ? (script[listKey] as unknown[]) : []) {\n if (!isObj(asset)) continue;\n const assetName = String(asset[nameKey] ?? \"\");\n const states = isArr(asset.states) ? asset.states : [];\n if (!nonEmpty(asset.description)) {\n throw new CliError(`Ingested asset \"${assetName}\" is missing its identity description.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"ASSET_DESCRIPTION_MISSING\",\n hint: \"Rerun `scriptctl ingest --force` so the serial asset window can regenerate this entity.\",\n });\n }\n for (const st of states) {\n if (!isObj(st) || nonEmpty(st.description)) continue;\n const stateName = String(st.state_name ?? \"\");\n throw new CliError(`Ingested asset \"${assetName}\" has no visual description for look \"${stateName}\".`, {\n exitCode: EXIT_INPUT,\n errorCode: st.state_id === \"default\" ? \"DEFAULT_LOOK_DESCRIPTION_MISSING\" : \"LOOK_DESCRIPTION_MISSING\",\n hint: \"Rerun `scriptctl ingest --force` so the serial asset window can regenerate this look.\",\n });\n }\n }\n }\n}\n", "// Pure whole-script asset audit projection. The LLM never receives the full\n// screenplay body: it gets one compact global roster with canonical names,\n// aliases, descriptions, state usage counts and a few concrete references.\n\ntype Obj = Record<string, unknown>;\nconst isObj = (value: unknown): value is Obj => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst asArr = (value: unknown): unknown[] => Array.isArray(value) ? value : [];\nconst asStr = (value: unknown): string => typeof value === \"string\" ? value.trim() : \"\";\n\nexport type AuditAssetKind = \"actor\" | \"location\" | \"prop\";\nexport type AssetAuditIssueType =\n | \"duplicate_actor\"\n | \"duplicate_location\"\n | \"duplicate_prop\"\n | \"duplicate_state\"\n | \"suspicious_singleton_state\"\n | \"unused_state\"\n | \"needs_human_review\";\nexport type AssetAuditAction = \"merge\" | \"delete\" | \"review\";\nexport type AssetAuditConfidence = \"high\" | \"medium\" | \"low\";\n\nexport interface AssetAuditStateSnapshot {\n address: string;\n state_id: string;\n state_name: string;\n description: string;\n format_key: string;\n reference_count: number;\n episode_count: number;\n scene_count: number;\n references: string[];\n frequency_flag: \"unused\" | \"singleton\" | null;\n}\n\nexport interface AssetAuditAssetSnapshot {\n kind: AuditAssetKind;\n id: string;\n name: string;\n aliases: string[];\n description: string;\n importance: string;\n format_key: string;\n alias_format_keys: string[];\n reference_count: number;\n episode_count: number;\n scene_count: number;\n references: string[];\n states: AssetAuditStateSnapshot[];\n}\n\nexport interface AssetAuditSnapshot {\n title: string;\n actors: AssetAuditAssetSnapshot[];\n locations: AssetAuditAssetSnapshot[];\n props: AssetAuditAssetSnapshot[];\n}\n\nexport interface AssetAuditIssue {\n type: AssetAuditIssueType;\n asset_ids: string[];\n state_ids: string[];\n names: string[];\n evidence: string;\n recommendation: string;\n suggested_survivor: string | null;\n action: AssetAuditAction;\n confidence: AssetAuditConfidence;\n}\n\ninterface MutableState extends AssetAuditStateSnapshot {\n episodeIds: Set<string>;\n sceneIds: Set<string>;\n}\n\ninterface MutableAsset extends AssetAuditAssetSnapshot {\n states: MutableState[];\n episodeIds: Set<string>;\n sceneIds: Set<string>;\n stateById: Map<string, MutableState>;\n}\n\n// Formatting-only key used as deterministic evidence, not as an identity\n// verdict. It folds Unicode compatibility forms, case, whitespace, punctuation\n// and separators (`\u6797\u6709\u7CAE` = `\u6797 \u6709\u7CAE`); semantic variants such as aliases,\n// transcription mistakes and Simplified/Traditional forms remain for the model.\nexport function assetAuditFormatKey(value: string): string {\n return value.normalize(\"NFKC\").toLowerCase().replace(/[\\p{White_Space}\\p{P}\\p{S}]+/gu, \"\");\n}\n\nconst KIND_META = {\n actor: { list: \"actors\", id: \"actor_id\", name: \"actor_name\" },\n location: { list: \"locations\", id: \"location_id\", name: \"location_name\" },\n prop: { list: \"props\", id: \"prop_id\", name: \"prop_name\" },\n} as const;\n\nconst pushUnique = (list: string[], value: string, limit = 8): void => {\n if (!value || list.includes(value) || list.length >= limit) return;\n list.push(value);\n};\n\nexport function buildAssetAuditSnapshot(doc: unknown): AssetAuditSnapshot {\n const root = isObj(doc) ? doc : {};\n const byKind: Record<AuditAssetKind, MutableAsset[]> = { actor: [], location: [], prop: [] };\n const byId = new Map<string, MutableAsset>();\n\n for (const kind of [\"actor\", \"location\", \"prop\"] as const) {\n const meta = KIND_META[kind];\n for (const raw of asArr(root[meta.list])) {\n if (!isObj(raw)) continue;\n const id = asStr(raw[meta.id]);\n const name = asStr(raw[meta.name]);\n if (!id) continue;\n const aliases = [...new Set(asArr(raw.aliases).map(asStr).filter(Boolean))];\n const stateById = new Map<string, MutableState>();\n const states: MutableState[] = [];\n for (const stateRaw of asArr(raw.states)) {\n if (!isObj(stateRaw)) continue;\n const stateId = asStr(stateRaw.state_id);\n if (!stateId) continue;\n const stateName = asStr(stateRaw.state_name);\n const state: MutableState = {\n address: `${id}/${stateId}`,\n state_id: stateId,\n state_name: stateName,\n description: asStr(stateRaw.description),\n format_key: assetAuditFormatKey(stateName),\n reference_count: 0,\n episode_count: 0,\n scene_count: 0,\n references: [],\n frequency_flag: null,\n episodeIds: new Set(),\n sceneIds: new Set(),\n };\n states.push(state);\n stateById.set(stateId, state);\n }\n const asset: MutableAsset = {\n kind,\n id,\n name,\n aliases,\n description: asStr(raw.description),\n importance: asStr(raw.importance),\n format_key: assetAuditFormatKey(name),\n alias_format_keys: aliases.map(assetAuditFormatKey),\n reference_count: 0,\n episode_count: 0,\n scene_count: 0,\n references: [],\n states,\n episodeIds: new Set(),\n sceneIds: new Set(),\n stateById,\n };\n byKind[kind].push(asset);\n byId.set(id, asset);\n }\n }\n\n const stateIdsOf = (ref: Obj): string[] => {\n const plural = asArr(ref.state_ids).map(asStr).filter(Boolean);\n if (plural.length > 0) return [...new Set(plural)];\n const singular = asStr(ref.state_id);\n return singular ? [singular] : [];\n };\n\n const addReference = (\n kind: AuditAssetKind,\n id: string,\n stateIds: string[],\n episodeId: string,\n sceneId: string,\n addr: string,\n ): void => {\n const asset = byId.get(id);\n if (!asset || asset.kind !== kind) return;\n asset.reference_count += 1;\n asset.episodeIds.add(episodeId);\n asset.sceneIds.add(`${episodeId}/${sceneId}`);\n pushUnique(asset.references, addr);\n const resolvedStateIds = stateIds.length > 0\n ? stateIds\n : asset.stateById.has(\"default\")\n ? [\"default\"]\n : [];\n for (const stateId of resolvedStateIds) {\n const state = asset.stateById.get(stateId);\n if (!state) continue;\n state.reference_count += 1;\n state.episodeIds.add(episodeId);\n state.sceneIds.add(`${episodeId}/${sceneId}`);\n pushUnique(state.references, addr);\n }\n };\n\n for (const episodeRaw of asArr(root.episodes)) {\n if (!isObj(episodeRaw)) continue;\n const episodeId = asStr(episodeRaw.episode_id) || \"<episode>\";\n for (const sceneRaw of asArr(episodeRaw.scenes)) {\n if (!isObj(sceneRaw)) continue;\n const sceneId = asStr(sceneRaw.scene_id) || \"<scene>\";\n const sceneAddr = `${episodeId}/${sceneId}`;\n if (isObj(sceneRaw.location)) {\n addReference(\n \"location\",\n asStr(sceneRaw.location.location_id),\n stateIdsOf(sceneRaw.location),\n episodeId,\n sceneId,\n `${sceneAddr}.location`,\n );\n }\n for (const ref of asArr(sceneRaw.actors)) {\n if (isObj(ref)) {\n addReference(\n \"actor\",\n asStr(ref.actor_id),\n stateIdsOf(ref),\n episodeId,\n sceneId,\n `${sceneAddr}.actors`,\n );\n }\n }\n for (const ref of asArr(sceneRaw.props)) {\n if (isObj(ref)) {\n addReference(\n \"prop\",\n asStr(ref.prop_id),\n stateIdsOf(ref),\n episodeId,\n sceneId,\n `${sceneAddr}.props`,\n );\n }\n }\n asArr(sceneRaw.actions).forEach((actionRaw, actionIndex) => {\n if (!isObj(actionRaw) || !isObj(actionRaw.speaker)) return;\n const actorId = asStr(actionRaw.speaker.actor_id);\n if (actorId) {\n addReference(\n \"actor\",\n actorId,\n stateIdsOf(actionRaw.speaker),\n episodeId,\n sceneId,\n `${sceneAddr}#${actionIndex + 1}.speaker`,\n );\n }\n });\n }\n }\n\n const finish = (asset: MutableAsset): AssetAuditAssetSnapshot => {\n asset.episode_count = asset.episodeIds.size;\n asset.scene_count = asset.sceneIds.size;\n for (const state of asset.states) {\n state.episode_count = state.episodeIds.size;\n state.scene_count = state.sceneIds.size;\n state.frequency_flag = state.state_id === \"default\"\n ? null\n : state.scene_count === 0\n ? \"unused\"\n : state.scene_count === 1\n ? \"singleton\"\n : null;\n }\n return {\n kind: asset.kind,\n id: asset.id,\n name: asset.name,\n aliases: asset.aliases,\n description: asset.description,\n importance: asset.importance,\n format_key: asset.format_key,\n alias_format_keys: asset.alias_format_keys,\n reference_count: asset.reference_count,\n episode_count: asset.episode_count,\n scene_count: asset.scene_count,\n references: asset.references,\n states: asset.states.map((state) => ({\n address: state.address,\n state_id: state.state_id,\n state_name: state.state_name,\n description: state.description,\n format_key: state.format_key,\n reference_count: state.reference_count,\n episode_count: state.episode_count,\n scene_count: state.scene_count,\n references: state.references,\n frequency_flag: state.frequency_flag,\n })),\n };\n };\n\n return {\n title: asStr(root.title),\n actors: byKind.actor.map(finish),\n locations: byKind.location.map(finish),\n props: byKind.prop.map(finish),\n };\n}\n", "// Whole-script semantic asset audit. Unlike per-episode extraction, this task\n// sees the final global roster and only reports suspected duplicates/anomalies;\n// it never mutates or merges the script by itself.\n\nimport {\n type AssetAuditAction,\n type AssetAuditConfidence,\n type AssetAuditIssue,\n type AssetAuditIssueType,\n type AssetAuditSnapshot,\n} from \"../../../domain/ingest/asset-audit.js\";\nimport type { LlmTaskExecutor } from \"../../types.js\";\nimport { ASSET_AUDIT_SCHEMA } from \"../schemas.js\";\n\nconst ASSET_INPUT_COLUMNS = [\"id\", \"name\", \"aliases\", \"importance\", \"refs\", \"episodes\", \"scenes\", \"format_key\", \"description\", \"evidence_refs\"];\nconst STATE_INPUT_COLUMNS = [\"address\", \"name\", \"refs\", \"episodes\", \"scenes\", \"frequency\", \"format_key\", \"description\", \"evidence_refs\"];\n\nexport const ASSET_AUDIT_SYSTEM = [\n \"\u4F60\u6B63\u5728\u5BF9\u4E00\u90E8\u5DF2\u7ECF\u5B8C\u6210\u89E3\u6790\u7684\u5B8C\u6574\u5267\u672C\u8FDB\u884C\u5168\u5C40\u8D44\u4EA7\u4E00\u81F4\u6027\u5BA1\u8BA1\u3002\u76EE\u6807\u662F\u53D1\u73B0\u540C\u4E00\u5B9E\u4F53\u88AB\u91CD\u590D\u5EFA\u6863\u3001\u540C\u4E00\u7A33\u5B9A\u89C6\u89C9\u72B6\u6001\u88AB\u91CD\u590D\u62C6\u5206\uFF0C\u4EE5\u53CA\u503C\u5F97\u4EBA\u5DE5\u91CD\u70B9\u590D\u6838\u7684\u4F4E\u9891\u5F02\u5E38\u72B6\u6001\u3002\",\n \"\u8F93\u5165\u662F\u5B8C\u6574\u8D44\u4EA7\u767B\u8BB0\u7684\u7D27\u51D1\u884C\u5F0F\u5FEB\u7167\uFF0C\u4E0D\u662F JSON\u3002\u7B2C\u4E00\u884C ASSET_AUDIT_SNAPSHOT_V1 \u662F\u534F\u8BAE\u7248\u672C\uFF1Btitle|<\u5267\u540D> \u662F\u5267\u540D\uFF1BA_COLUMNS/S_COLUMNS \u662F\u5217\u5B9A\u4E49\uFF0C\u4E0D\u662F\u8D44\u4EA7\u6570\u636E\uFF1B[actors:N]\u3001[locations:N]\u3001[props:N] \u5206\u522B\u5F00\u59CB\u4EBA\u7269\u3001\u5730\u70B9\u3001\u9053\u5177\u5206\u533A\uFF0CN \u662F\u8BE5\u5206\u533A\u8D44\u4EA7\u6570\u5E76\u51B3\u5B9A\u5176\u4E2D A \u884C\u7684\u8D44\u4EA7\u7C7B\u578B\u3002\",\n `A \u884C\u8868\u793A\u4E00\u9879\u8D44\u4EA7\u3002\u53BB\u6389\u5F00\u5934\u7684 A \u540E\uFF0C\u5404\u5217\u4ECE\u5DE6\u5230\u53F3\u56FA\u5B9A\u4E3A\uFF1A${ASSET_INPUT_COLUMNS.join(\" | \")}\u3002id \u662F\u8D44\u4EA7 ID\uFF1Bname \u662F\u89C4\u8303\u540D\uFF1Baliases \u662F\u522B\u540D\u5217\u8868\uFF1Bimportance \u662F\u91CD\u8981\u5EA6\uFF1Brefs/episodes/scenes \u662F\u5F15\u7528\u6B21\u6570\u3001\u8986\u76D6\u96C6\u6570\u3001\u8986\u76D6\u573A\u6570\uFF1Bformat_key \u662F\u4EC5\u6D88\u9664\u683C\u5F0F\u566A\u58F0\u7684\u540D\u79F0\u952E\uFF1Bdescription \u662F\u8D44\u4EA7\u63CF\u8FF0\uFF1Bevidence_refs \u662F\u5C11\u91CF\u5B9E\u9645\u5F15\u7528\u4F4D\u7F6E\u3002`,\n `S \u884C\u8868\u793A\u72B6\u6001\u5E76\u96B6\u5C5E\u4E8E\u540C\u4E00\u5206\u533A\u4E2D\u7D27\u90BB\u5176\u4E0A\u7684 A \u884C\u3002\u53BB\u6389\u5F00\u5934\u7684 S \u540E\uFF0C\u5404\u5217\u4ECE\u5DE6\u5230\u53F3\u56FA\u5B9A\u4E3A\uFF1A${STATE_INPUT_COLUMNS.join(\" | \")}\u3002address \u662F <asset_id>/<state_id> \u5F62\u5F0F\u7684\u5168\u5C40\u72B6\u6001\u5730\u5740\uFF1Bname \u662F\u72B6\u6001\u540D\uFF1Brefs/episodes/scenes \u542B\u4E49\u540C\u4E0A\uFF1Bfrequency \u4E3A unused\u3001singleton \u6216 -\uFF1Bdescription \u662F\u72B6\u6001\u89C6\u89C9\u63CF\u8FF0\uFF1Bevidence_refs \u662F\u8BE5\u72B6\u6001\u7684\u5B9E\u9645\u5F15\u7528\u4F4D\u7F6E\u3002`,\n \"\u89E3\u6790\u89C4\u5219\uFF1A\u53EA\u5728\u672A\u8F6C\u4E49\u7684 | \u5904\u5206\u5217\uFF0C\u53EA\u5728\u672A\u8F6C\u4E49\u7684 ; \u5904\u5206\u9694 aliases/evidence_refs \u5217\u8868\uFF1B- \u8868\u793A\u7A7A\u503C\u6216\u65E0\u9891\u7387\u6807\u8BB0\uFF1B\\\\|\u3001\\\\;\u3001\\\\n\u3001\\\\\\\\ \u5206\u522B\u8868\u793A\u5B57\u6BB5\u5185\u5BB9\u4E2D\u7684\u7AD6\u7EBF\u3001\u5206\u53F7\u3001\u6362\u884C\u548C\u53CD\u659C\u6760\u3002\u4E0D\u8981\u628A A_COLUMNS/S_COLUMNS \u5F53\u4F5C\u5B9E\u4F53\uFF0C\u4E5F\u4E0D\u8981\u628A S \u884C\u8DE8\u8D44\u4EA7\u5F52\u5C5E\u3002\",\n \"format_key \u53EA\u6298\u53E0\u7A7A\u767D\u3001\u6807\u70B9\u3001\u5927\u5C0F\u5199\u3001\u5168\u534A\u89D2\u7B49\u683C\u5F0F\u5DEE\u5F02\uFF0C\u662F\u53EC\u56DE\u8BC1\u636E\u800C\u4E0D\u662F\u540C\u4E00\u5B9E\u4F53\u7684\u6700\u7EC8\u7ED3\u8BBA\u3002\",\n \"\",\n \"\u4E00\u3001\u4EBA\u7269\u8EAB\u4EFD\u4E00\u81F4\u6027\",\n \"\u68C0\u67E5\u540C\u4E00\u4E2A\u4EBA\u7269\u662F\u5426\u56E0\u540D\u79F0\u8868\u8FBE\u4E0D\u540C\u88AB\u767B\u8BB0\u6210\u591A\u4E2A actor\u3002\u5DEE\u5F02\u5305\u62EC\u4F46\u4E0D\u9650\u4E8E\uFF1A\u7A7A\u683C\u3001\u6807\u70B9\u3001\u5927\u5C0F\u5199\u3001\u5168\u534A\u89D2\u3001\u7B80\u7E41\u4F53\uFF1B\u5168\u540D\u3001\u7B80\u79F0\u3001\u6635\u79F0\u3001\u79F0\u8C13\u3001\u804C\u4F4D\u3001\u65E7\u540D\u3001\u5316\u540D\u3001\u8BD1\u540D\u3001\u97F3\u8BD1\uFF1B\u5206\u8BCD\u5DEE\u5F02\u3001\u8F7B\u5FAE\u9519\u522B\u5B57\u3001\u8F6C\u5F55\u8BEF\u5DEE\uFF1B\u540D\u79F0\u9644\u5E26\u8EAB\u4EFD\u3001\u60C5\u7EEA\u3001\u5BF9\u767D\u6216\u72B6\u6001\u8BF4\u660E\uFF1B\u524D\u671F\u8EAB\u4EFD\u672A\u660E\u3001\u540E\u671F\u53C8\u4EE5\u771F\u540D\u91CD\u65B0\u767B\u8BB0\u3002\",\n \"\u4F8B\u5982\u300E\u6797\u6709\u7CAE\u300F\u548C\u300E\u6797 \u6709\u7CAE\u300F\u53EA\u662F\u683C\u5F0F\u4E0D\u540C\uFF0C\u4F46\u4E0D\u80FD\u53EA\u6309\u540D\u79F0\u76F8\u4F3C\u5EA6\u5408\u5E76\u3002\u5FC5\u987B\u7EFC\u5408\u4EBA\u7269\u5173\u7CFB\u3001\u5267\u60C5\u8EAB\u4EFD\u3001\u5916\u8C8C\u63CF\u8FF0\u3001\u884C\u4E3A\u8F68\u8FF9\u3001\u5BF9\u767D\u5F52\u5C5E\u3001\u51FA\u73B0\u4F4D\u7F6E\u548C\u8DE8\u96C6\u8FDE\u7EED\u6027\u5224\u65AD\u3002\u59D3\u540D\u76F8\u4F3C\u3001\u8EAB\u4EFD\u76F8\u8FD1\u6216\u7ECF\u5E38\u540C\u6846\u7684\u4E0D\u540C\u4EBA\u7269\u7EDD\u4E0D\u80FD\u8BEF\u5408\u3002\",\n \"\",\n \"\u4E8C\u3001\u89C6\u89C9\u72B6\u6001\u4E00\u81F4\u6027\",\n \"\u5728\u540C\u4E00\u4E2A\u4EBA\u7269\u3001\u5730\u70B9\u6216\u9053\u5177\u5185\u90E8\uFF0C\u68C0\u67E5\u662F\u5426\u56E0\u63CF\u8FF0\u65B9\u5F0F\u3001\u989C\u8272\u7C92\u5EA6\u3001\u63AA\u8F9E\u8BE6\u7565\u6216\u89C2\u5BDF\u89D2\u5EA6\u4E0D\u540C\uFF0C\u628A\u540C\u4E00\u4E2A\u7A33\u5B9A\u89C6\u89C9\u72B6\u6001\u62C6\u6210\u591A\u4E2A state\u3002\u91CD\u70B9\u5173\u6CE8\u540C\u4E49/\u8FD1\u4E49\u72B6\u6001\u3001\u540C\u4E00\u5957\u670D\u88C5\u88AB\u91CD\u65B0\u547D\u540D\u3001\u4EC5\u5149\u7EBF\u6216\u5C40\u90E8\u7EC6\u8282\u9020\u6210\u7684\u5DEE\u5F02\uFF0C\u4EE5\u53CA\u72B6\u6001\u540D\u6DF7\u5165\u60C5\u7EEA\u3001\u52A8\u4F5C\u6216\u573A\u666F\u8BF4\u660E\u3002\",\n \"\u5224\u65AD\u6807\u51C6\u4E0D\u662F\u540D\u79F0\u662F\u5426\u4E00\u81F4\uFF0C\u800C\u662F\u662F\u5426\u771F\u7684\u9700\u8981\u5206\u522B\u5236\u4F5C\u72EC\u7ACB\u3001\u53EF\u590D\u7528\u7684\u89C6\u89C9\u53C2\u8003\u8D44\u4EA7\u3002\u89C6\u89C9\u4E3B\u4F53\u548C\u6301\u7EED\u5916\u89C2\u4E00\u81F4\u65F6\u5EFA\u8BAE\u5F52\u5E76\uFF1B\u660E\u786E\u6362\u88C5\u3001\u53D8\u8EAB\u3001\u635F\u6BC1\u3001\u6301\u7EED\u4F24\u52BF\u6216\u5176\u4ED6\u6301\u7EED\u6027\u53D8\u5316\u5219\u4FDD\u6301\u72EC\u7ACB\u3002\",\n \"\",\n \"\u4E09\u3001\u4F4E\u9891\u4E0E\u5F02\u5E38\u72B6\u6001\",\n \"\u91CD\u70B9\u68C0\u67E5\u975E default \u4E14\u672A\u88AB\u5F15\u7528\u3001\u53EA\u5728\u4E00\u4E2A\u573A\u666F\u51FA\u73B0\u3001\u51FA\u73B0\u540E\u7ACB\u5373\u6062\u590D\u539F\u72B6\u6001\u3001\u4E0E\u524D\u540E\u72B6\u6001\u51E0\u4E4E\u76F8\u540C\u6216\u5B9E\u9645\u5C5E\u4E8E\u60C5\u7EEA/\u59FF\u52BF/\u52A8\u4F5C/\u5149\u7EBF/\u77AC\u65F6\u8FC7\u7A0B\u7684\u72B6\u6001\u3002\u4F4E\u9891\u4E0D\u7B49\u4E8E\u9519\u8BEF\uFF1A\u660E\u786E\u5BF9\u5E94\u5173\u952E\u6362\u88C5\u3001\u5267\u60C5\u4E8B\u4EF6\u3001\u6301\u7EED\u4F24\u52BF\u3001\u53D8\u8EAB\u6216\u5FC5\u8981\u89C6\u89C9\u53D8\u5316\u65F6\u5E94\u4FDD\u7559\uFF0C\u4E0D\u8981\u8F93\u51FA\u4E3A\u95EE\u9898\u3002\u8BC1\u636E\u4E0D\u8DB3\u65F6 action=review\u3002\",\n \"\",\n \"\u56DB\u3001\u5730\u70B9\u4E0E\u9053\u5177\u4E00\u81F4\u6027\",\n \"\u68C0\u67E5\u540C\u4E00\u4E2A\u7269\u7406\u5730\u70B9\u6216\u540C\u4E00\u4EF6\u5177\u4F53\u9053\u5177\u662F\u5426\u56E0\u540D\u79F0\u3001\u524D\u540E\u7F00\u3001\u5F52\u5C5E\u63CF\u8FF0\u3001\u7B80\u79F0\u3001\u7B80\u7E41\u4F53\u3001\u8F6C\u5F55\u5DEE\u5F02\u6216\u89C2\u5BDF\u89D2\u5EA6\u4E0D\u540C\u800C\u91CD\u590D\u767B\u8BB0\u3002\u533A\u5206\u540C\u4E00\u5730\u70B9\u7684\u4E0D\u540C\u540D\u79F0\u4E0E\u540C\u4E00\u5EFA\u7B51\u4E2D\u7684\u4E0D\u540C\u72EC\u7ACB\u7A7A\u95F4\uFF0C\u4E5F\u533A\u5206\u540C\u4E00\u4EF6\u5177\u4F53\u9053\u5177\u4E0E\u540C\u7C7B\u4F46\u5B9E\u9645\u4E0D\u540C\u7684\u591A\u4EF6\u9053\u5177\u3002\",\n \"\u8FD9\u91CC\u68C0\u67E5\u548C\u5EFA\u8BAE\u5408\u5E76\u7684\u662F\u91CD\u590D location \u8D44\u4EA7\uFF0C\u4E0D\u662F scene\u3002\u76F8\u540C\u5730\u70B9\u53EF\u4EE5\u627F\u8F7D\u591A\u4E2A\u4E0D\u540C\u5267\u60C5\u573A\u6B21\uFF0C\u4E0D\u80FD\u56E0\u4E3A\u5730\u70B9\u76F8\u540C\u5C31\u5408\u5E76 scene\u3002\",\n \"\",\n \"\u4E94\u3001\u5BA1\u8BA1\u8FB9\u754C\u4E0E\u8F93\u51FA\",\n \"\u53EA\u5F15\u7528\u8F93\u5165\u4E2D\u771F\u5B9E\u5B58\u5728\u7684 asset/state id\uFF1B\u53EA\u8F93\u51FA\u786E\u5B9E\u53EF\u7591\u3001\u9700\u8981\u5408\u5E76/\u5220\u9664/\u4EBA\u5DE5\u786E\u8BA4\u7684\u9879\u76EE\uFF0C\u786E\u8BA4\u5408\u7406\u7684\u8D44\u4EA7\u6216\u4F4E\u9891\u72B6\u6001\u4E0D\u8981\u8F93\u51FA\u3002\u4E0D\u8981\u76F4\u63A5\u4FEE\u6539\u5267\u672C\u3002\",\n \"\u6BCF\u4E2A\u95EE\u9898\u5FC5\u987B\u7ED9\u51FA\u5177\u4F53\u8BC1\u636E\u548C\u64CD\u4F5C\u5EFA\u8BAE\u3002\u9AD8\u7F6E\u4FE1\u5EA6\u4ECD\u53EA\u662F\u5EFA\u8BAE\uFF1B\u5B58\u5728\u51B2\u7A81\u6216\u65E0\u6CD5\u786E\u8BA4\u65F6 action=review\u3001confidence=low \u6216 medium\u3002\",\n \"\u8C03\u7528 emit_asset_audit \u5DE5\u5177\u8FD4\u56DE\u5BA1\u8BA1\u7ED3\u679C\u3002\",\n \"state_ids \u5FC5\u987B\u586B\u5199\u8F93\u5165\u91CC\u7684\u5B8C\u6574\u72B6\u6001 address\uFF08<asset_id>/<state_id>\uFF09\uFF0C\u4E0D\u80FD\u53EA\u5199\u53EF\u80FD\u5728\u591A\u4E2A\u8D44\u4EA7\u4E0B\u91CD\u590D\u7684\u5C40\u90E8 state_id\u3002\",\n \"\u6CA1\u6709\u95EE\u9898\u65F6 issues \u4F20\u7A7A\u6570\u7EC4\u3002\",\n].join(\"\\n\");\n\nconst ISSUE_TYPES = new Set<AssetAuditIssueType>([\n \"duplicate_actor\",\n \"duplicate_location\",\n \"duplicate_prop\",\n \"duplicate_state\",\n \"suspicious_singleton_state\",\n \"unused_state\",\n \"needs_human_review\",\n]);\nconst ACTIONS = new Set<AssetAuditAction>([\"merge\", \"delete\", \"review\"]);\nconst CONFIDENCES = new Set<AssetAuditConfidence>([\"high\", \"medium\", \"low\"]);\n\n// The roster can be large. This format declares column names once instead of\n// repeating JSON keys for every asset/state, while preserving readable evidence.\nfunction compactField(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"-\";\n return trimmed\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\r\\n?|\\n/g, \"\\\\n\")\n .replace(/\\|/g, \"\\\\|\")\n .replace(/;/g, \"\\\\;\");\n}\n\nfunction compactList(values: string[]): string {\n return values.length > 0 ? values.map(compactField).join(\";\") : \"-\";\n}\n\nexport function formatAssetAuditInput(snapshot: AssetAuditSnapshot): string {\n const lines = [\n \"ASSET_AUDIT_SNAPSHOT_V1\",\n `title|${compactField(snapshot.title)}`,\n `A_COLUMNS|${ASSET_INPUT_COLUMNS.join(\"|\")}`,\n `S_COLUMNS|${STATE_INPUT_COLUMNS.join(\"|\")}`,\n ];\n\n const appendSection = (name: \"actors\" | \"locations\" | \"props\", assets: AssetAuditSnapshot[typeof name]): void => {\n lines.push(`[${name}:${assets.length}]`);\n for (const asset of assets) {\n lines.push([\n \"A\",\n compactField(asset.id),\n compactField(asset.name),\n compactList(asset.aliases),\n compactField(asset.importance),\n String(asset.reference_count),\n String(asset.episode_count),\n String(asset.scene_count),\n compactField(asset.format_key),\n compactField(asset.description),\n compactList(asset.references),\n ].join(\"|\"));\n for (const state of asset.states) {\n lines.push([\n \"S\",\n compactField(state.address),\n compactField(state.state_name),\n String(state.reference_count),\n String(state.episode_count),\n String(state.scene_count),\n state.frequency_flag ?? \"-\",\n compactField(state.format_key),\n compactField(state.description),\n compactList(state.references),\n ].join(\"|\"));\n }\n }\n };\n\n appendSection(\"actors\", snapshot.actors);\n appendSection(\"locations\", snapshot.locations);\n appendSection(\"props\", snapshot.props);\n return lines.join(\"\\n\");\n}\n\nconst isObj = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst asArr = (value: unknown): unknown[] => Array.isArray(value) ? value : [];\nconst asStr = (value: unknown): string => typeof value === \"string\" ? value.trim() : \"\";\nconst strings = (value: unknown): string[] => [...new Set(asArr(value).map(asStr).filter(Boolean))];\n\nexport function parseAssetAuditInput(parsed: unknown, snapshot: AssetAuditSnapshot): AssetAuditIssue[] {\n if (!isObj(parsed)) throw new Error(\"asset audit response must be a JSON object\");\n const validAssetIds = new Set([...snapshot.actors, ...snapshot.locations, ...snapshot.props].map((asset) => asset.id));\n const validStateIds = new Set([...snapshot.actors, ...snapshot.locations, ...snapshot.props].flatMap((asset) => asset.states.map((state) => state.address)));\n const issues: AssetAuditIssue[] = [];\n\n for (const rawIssue of asArr(parsed.issues)) {\n if (!isObj(rawIssue)) continue;\n const type = asStr(rawIssue.type) as AssetAuditIssueType;\n const action = asStr(rawIssue.action) as AssetAuditAction;\n const confidence = asStr(rawIssue.confidence) as AssetAuditConfidence;\n if (!ISSUE_TYPES.has(type) || !ACTIONS.has(action) || !CONFIDENCES.has(confidence)) continue;\n const assetIds = strings(rawIssue.asset_ids).filter((id) => validAssetIds.has(id));\n const stateIds = strings(rawIssue.state_ids).filter((id) => validStateIds.has(id));\n if (assetIds.length === 0 && stateIds.length === 0) continue;\n const survivor = asStr(rawIssue.suggested_survivor);\n const suggestedSurvivor = survivor && (validAssetIds.has(survivor) || validStateIds.has(survivor)) ? survivor : null;\n issues.push({\n type,\n asset_ids: assetIds,\n state_ids: stateIds,\n names: strings(rawIssue.names),\n evidence: asStr(rawIssue.evidence),\n recommendation: asStr(rawIssue.recommendation),\n suggested_survivor: suggestedSurvivor,\n action,\n confidence,\n });\n }\n return issues;\n}\n\nexport async function runAssetAudit(executor: LlmTaskExecutor, snapshot: AssetAuditSnapshot, signal?: AbortSignal): Promise<AssetAuditIssue[]> {\n const response = await executor.generateTool(\"ingest.asset-audit\", {\n system: ASSET_AUDIT_SYSTEM,\n user: formatAssetAuditInput(snapshot),\n tool: {\n name: \"emit_asset_audit\",\n description: \"\u8FD4\u56DE\u5168\u5267\u8D44\u4EA7\u4E00\u81F4\u6027\u5BA1\u8BA1\u53D1\u73B0\",\n inputSchema: ASSET_AUDIT_SCHEMA,\n },\n ...(signal ? { signal } : {}),\n });\n return parseAssetAuditInput(response.input, snapshot);\n}\n", "// Shared asset-audit boundary for text ingest and the standalone audit command.\n// Results are content-addressed so an unchanged script reuses the sidecar while\n// any edit makes the old result stale automatically.\n\nimport {\n buildAssetAuditSnapshot,\n type AssetAuditIssue,\n} from \"../../domain/ingest/asset-audit.js\";\nimport type { ValidationIssue } from \"../../domain/ingest/validation.js\";\nimport { semanticScriptHash } from \"../../infra/script-working-copy.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\nimport { runAssetAudit } from \"../../llm/tasks/ingest/asset-audit.js\";\nimport type { LlmTaskExecutor } from \"../../llm/types.js\";\n\nexport const ASSET_AUDIT_VERSION = \"1\";\n\nexport interface AssetAuditReport {\n audit_version: string;\n script_hash: string;\n created_at: string;\n summary: {\n issues: number;\n high: number;\n medium: number;\n low: number;\n };\n issues: AssetAuditIssue[];\n}\n\nconst isReport = (value: unknown, scriptHash: string): value is AssetAuditReport => {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const report = value as Partial<AssetAuditReport>;\n return report.audit_version === ASSET_AUDIT_VERSION\n && report.script_hash === scriptHash\n && report.summary !== null\n && typeof report.summary === \"object\"\n && Array.isArray(report.issues);\n};\n\nfunction reportFor(scriptHash: string, issues: AssetAuditIssue[]): AssetAuditReport {\n return {\n audit_version: ASSET_AUDIT_VERSION,\n script_hash: scriptHash,\n created_at: new Date().toISOString(),\n summary: {\n issues: issues.length,\n high: issues.filter((issue) => issue.confidence === \"high\").length,\n medium: issues.filter((issue) => issue.confidence === \"medium\").length,\n low: issues.filter((issue) => issue.confidence === \"low\").length,\n },\n issues,\n };\n}\n\nexport async function auditScriptAssets(script: Record<string, unknown>, executor: LlmTaskExecutor, signal?: AbortSignal): Promise<AssetAuditReport> {\n const scriptHash = semanticScriptHash(script);\n const snapshot = buildAssetAuditSnapshot(script);\n const issues = await runAssetAudit(executor, snapshot, signal);\n return reportFor(scriptHash, issues);\n}\n\nexport async function auditScriptAssetsCached(opts: {\n script: Record<string, unknown>;\n executor: LlmTaskExecutor;\n read: () => unknown;\n write: (report: AssetAuditReport) => void;\n exists: () => boolean;\n force?: boolean;\n signal?: AbortSignal;\n}): Promise<{ report: AssetAuditReport; reused: boolean }> {\n const scriptHash = semanticScriptHash(opts.script);\n if (!opts.force && opts.exists()) {\n try {\n const cached = opts.read();\n if (isReport(cached, scriptHash)) {\n opts.executor.recordReuse(\"ingest.asset-audit\");\n return { report: cached, reused: true };\n }\n } catch {\n // A malformed/stale sidecar is disposable; regenerate it from script.json.\n }\n }\n const report = await auditScriptAssets(opts.script, opts.executor, opts.signal);\n opts.write(report);\n return { report, reused: false };\n}\n\nexport async function auditWorkspaceScriptAssets(\n store: WorkspaceStore,\n script: Record<string, unknown>,\n executor: LlmTaskExecutor,\n opts: { force?: boolean; signal?: AbortSignal } = {},\n): Promise<{ report: AssetAuditReport; reused: boolean }> {\n return auditScriptAssetsCached({\n script,\n executor,\n read: () => store.readJson(\"asset-audit.json\"),\n write: (report) => store.writeJson(\"asset-audit.json\", report),\n exists: () => store.has(\"asset-audit.json\"),\n ...(opts.force ? { force: true } : {}),\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n}\n\nconst TYPE_LABEL: Record<AssetAuditIssue[\"type\"], string> = {\n duplicate_actor: \"duplicate actor\",\n duplicate_location: \"duplicate location\",\n duplicate_prop: \"duplicate prop\",\n duplicate_state: \"duplicate state\",\n suspicious_singleton_state: \"suspicious singleton state\",\n unused_state: \"unused state\",\n needs_human_review: \"asset needs human review\",\n};\n\nexport function assetAuditIssueLine(issue: AssetAuditIssue): string {\n const targets = [...issue.asset_ids, ...issue.state_ids].join(\", \") || \"<unknown>\";\n const detail = issue.evidence || issue.recommendation || \"review the referenced assets\";\n return `${TYPE_LABEL[issue.type]} [${targets}]: ${detail}`;\n}\n\nexport function assetAuditWarnings(report: AssetAuditReport): ValidationIssue[] {\n return report.issues.map((issue) => ({\n code: `asset_audit_${issue.type}`,\n path: \"$\",\n message: `${assetAuditIssueLine(issue)}; action=${issue.action}; confidence=${issue.confidence}`,\n }));\n}\n", "// Accurate in-process timing for `scriptctl ingest`, persisted incrementally to\n// workspace/timings.json so `scriptctl view --watch` and `scriptctl ingest status`\n// show REAL wall-clock durations + a serial ETA (not mtime guesses). Written after\n// each phase boundary and each serial window, so the live monitor ticks as the run\n// progresses. Timing is per THIS run: a new run/resume starts a fresh record.\n\nexport interface WindowTiming { start: number; end: number; ms: number; cached: boolean }\nexport interface PhaseTiming { name: string; startedMs: number; endedMs: number | null }\nexport interface SerialTiming { totalWindows: number; totalEpisodes: number; windows: WindowTiming[] }\nexport interface IngestTimings {\n startedMs: number;\n endedMs: number | null;\n phases: PhaseTiming[];\n serial: SerialTiming | null;\n}\n\n// Records timing and flushes the whole record on every mutation. `flush` persists\n// it (the pipeline writes workspace/timings.json); `now` is injectable for tests.\nexport class Timings {\n private t: IngestTimings;\n constructor(private readonly flush: (t: IngestTimings) => void, private readonly now: () => number = () => Date.now()) {\n this.t = { startedMs: this.now(), endedMs: null, phases: [], serial: null };\n this.flush(this.t);\n }\n phaseStart(name: string): void {\n this.t.phases.push({ name, startedMs: this.now(), endedMs: null });\n this.flush(this.t);\n }\n phaseEnd(name: string): void {\n for (let i = this.t.phases.length - 1; i >= 0; i--) {\n const p = this.t.phases[i]!;\n if (p.name === name && p.endedMs === null) { p.endedMs = this.now(); this.flush(this.t); return; }\n }\n }\n serialStart(totalWindows: number, totalEpisodes: number): void {\n this.t.serial = { totalWindows, totalEpisodes, windows: [] };\n this.flush(this.t);\n }\n windowDone(start: number, end: number, ms: number, cached: boolean): void {\n if (!this.t.serial) this.t.serial = { totalWindows: 0, totalEpisodes: 0, windows: [] };\n this.t.serial.windows.push({ start, end, ms, cached });\n this.flush(this.t);\n }\n finish(): void { this.t.endedMs = this.now(); this.flush(this.t); }\n}\n\n// A now-relative presentation summary for `ingest status --json` consumers.\nexport interface TimingSummary {\n elapsedMs: number;\n done: boolean;\n phases: Array<{ name: string; ms: number; running: boolean }>;\n serial: {\n doneWindows: number;\n totalWindows: number;\n doneEpisodes: number;\n totalEpisodes: number;\n avgWindowMs: number | null; // over REAL (non-cached) windows only\n etaMs: number | null;\n } | null;\n}\n\n// Pure: compute elapsed/phase/eta at a given `nowMs`. ETA extrapolates the average\n// of REAL (non-cached) serial windows over the windows still to run; cached windows\n// (resume replays) are excluded so a resumed run's ETA isn't skewed toward zero.\nexport function summarizeTimings(t: IngestTimings, nowMs: number): TimingSummary {\n const elapsedMs = (t.endedMs ?? nowMs) - t.startedMs;\n const phases = t.phases.map((p) => ({ name: p.name, ms: (p.endedMs ?? nowMs) - p.startedMs, running: p.endedMs === null }));\n let serial: TimingSummary[\"serial\"] = null;\n if (t.serial) {\n const w = t.serial.windows;\n const real = w.filter((x) => !x.cached);\n const avg = real.length ? real.reduce((a, x) => a + x.ms, 0) / real.length : null;\n const doneEpisodes = w.reduce((a, x) => a + (x.end - x.start + 1), 0);\n const remainingWindows = Math.max(0, t.serial.totalWindows - w.length);\n serial = {\n doneWindows: w.length,\n totalWindows: t.serial.totalWindows,\n doneEpisodes,\n totalEpisodes: t.serial.totalEpisodes,\n avgWindowMs: avg != null ? Math.round(avg) : null,\n etaMs: avg != null ? Math.round(avg * remainingWindows) : null,\n };\n }\n return { elapsedMs, done: t.endedMs !== null, phases, serial };\n}\n", "// Streaming LLM cost ledger \u2192 workspace/usage.json.\n//\n// ModelRouter emits one immutable event per actual routed model execution. This\n// ledger appends those events after each ingest unit and derives every aggregate\n// from the event list, so task/model/global totals cannot drift or double-count.\n\nimport * as crypto from \"node:crypto\";\n\nimport type {\n LlmProtocol,\n LlmTaskExecutor,\n LlmTaskId,\n LlmUsageEvent,\n} from \"../../llm/types.js\";\nimport type { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\n\nexport interface UsageTotals {\n calls: number;\n succeeded: number;\n failed: number;\n reused: number;\n attempts: number;\n durationMs: number;\n inputTokens: number;\n outputTokens: number;\n cachedInputTokens: number;\n cacheCreationTokens: number;\n totalTokens: number;\n}\n\nexport type UsageScope =\n | { kind: \"episode\"; episode: number }\n | { kind: \"episode-range\"; startEpisode: number; endEpisode: number }\n | { kind: \"phase\"; phase: string }\n | { kind: \"run\" };\n\nexport interface UsageRecord extends LlmUsageEvent {\n id: string;\n runId: string;\n scope: UsageScope;\n}\n\nexport interface UsageModelIdentity {\n provider: string;\n protocol: LlmProtocol;\n model: string;\n}\n\nexport interface UsageModelBreakdown extends UsageModelIdentity {\n profiles: string[];\n fingerprints: string[];\n totals: UsageTotals;\n}\n\nexport interface UsageTaskSummary {\n task: LlmTaskId;\n totals: UsageTotals;\n byModel: UsageModelBreakdown[];\n}\n\nexport interface UsageModelSummary extends UsageModelBreakdown {\n byTask: Array<{ task: LlmTaskId; totals: UsageTotals }>;\n}\n\nexport interface EpisodeStageTiming {\n transcodeMs?: number;\n uploadMs?: number;\n generateMs?: number;\n uploadBytes?: number;\n transcoded?: boolean;\n note?: string;\n}\n\nexport type UsageUnitStatus = \"succeeded\" | \"failed\" | \"reused\";\nexport type UsageRunStatus = \"running\" | \"succeeded\" | \"failed\" | \"interrupted\";\n\nexport interface EpisodeUsageRun {\n runId: string;\n status: UsageUnitStatus;\n startedAt: string;\n endedAt: string;\n durationMs: number;\n stages: EpisodeStageTiming;\n recordIds: string[];\n}\n\nexport interface EpisodeUsageSummary {\n episode: number;\n totals: UsageTotals;\n byTask: UsageTaskSummary[];\n byModel: UsageModelSummary[];\n durationMs: number;\n runs: EpisodeUsageRun[];\n}\n\nexport interface UsageRun {\n id: string;\n status: UsageRunStatus;\n startedAt: string;\n endedAt: string | null;\n durationMs: number;\n}\n\nexport interface UsageReport {\n version: 2;\n createdAt: string;\n updatedAt: string;\n totals: UsageTotals;\n byTask: UsageTaskSummary[];\n byModel: UsageModelSummary[];\n episodes: EpisodeUsageSummary[];\n runs: UsageRun[];\n records: UsageRecord[];\n timing: {\n totalDurationMs: number;\n modelDurationMs: number;\n episodeDurationMs: number;\n };\n}\n\nexport interface UsageFlush {\n scope: UsageScope;\n status?: UsageUnitStatus;\n startedAtMs?: number;\n endedAtMs?: number;\n stages?: EpisodeStageTiming;\n}\n\nfunction emptyTotals(): UsageTotals {\n return {\n calls: 0,\n succeeded: 0,\n failed: 0,\n reused: 0,\n attempts: 0,\n durationMs: 0,\n inputTokens: 0,\n outputTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n totalTokens: 0,\n };\n}\n\nfunction addEvent(total: UsageTotals, event: Pick<UsageRecord, \"status\" | \"attempts\" | \"durationMs\" | \"inputTokens\" | \"outputTokens\" | \"cachedInputTokens\" | \"cacheCreationTokens\">): void {\n if (event.status === \"reused\") {\n total.reused += 1;\n return;\n }\n total.calls += 1;\n if (event.status === \"succeeded\") total.succeeded += 1;\n else total.failed += 1;\n total.attempts += event.attempts;\n total.durationMs += event.durationMs;\n total.inputTokens += event.inputTokens;\n total.outputTokens += event.outputTokens;\n total.cachedInputTokens += event.cachedInputTokens;\n total.cacheCreationTokens += event.cacheCreationTokens;\n total.totalTokens = total.inputTokens + total.outputTokens;\n}\n\nfunction totalsOf(records: UsageRecord[]): UsageTotals {\n const totals = emptyTotals();\n for (const record of records) addEvent(totals, record);\n return totals;\n}\n\nconst modelKey = (record: UsageModelIdentity): string =>\n `${record.provider}\\u0000${record.protocol}\\u0000${record.model}`;\n\nfunction modelBreakdowns(records: UsageRecord[]): UsageModelBreakdown[] {\n const groups = new Map<string, { identity: UsageModelIdentity; profiles: Set<string>; fingerprints: Set<string>; records: UsageRecord[] }>();\n for (const record of records) {\n const key = modelKey(record);\n const group = groups.get(key) ?? {\n identity: { provider: record.provider, protocol: record.protocol, model: record.model },\n profiles: new Set<string>(),\n fingerprints: new Set<string>(),\n records: [],\n };\n group.profiles.add(record.profile);\n group.fingerprints.add(record.fingerprint);\n group.records.push(record);\n groups.set(key, group);\n }\n return [...groups.values()]\n .map((group) => ({\n ...group.identity,\n profiles: [...group.profiles].sort(),\n fingerprints: [...group.fingerprints].sort(),\n totals: totalsOf(group.records),\n }))\n .sort((left, right) => modelKey(left).localeCompare(modelKey(right)));\n}\n\nfunction taskSummaries(records: UsageRecord[]): UsageTaskSummary[] {\n const groups = new Map<LlmTaskId, UsageRecord[]>();\n for (const record of records) {\n const group = groups.get(record.task) ?? [];\n group.push(record);\n groups.set(record.task, group);\n }\n return [...groups.entries()]\n .map(([task, taskRecords]) => ({\n task,\n totals: totalsOf(taskRecords),\n byModel: modelBreakdowns(taskRecords),\n }))\n .sort((left, right) => left.task.localeCompare(right.task));\n}\n\nfunction modelSummaries(records: UsageRecord[]): UsageModelSummary[] {\n return modelBreakdowns(records).map((model) => {\n const modelRecords = records.filter((record) => modelKey(record) === modelKey(model));\n return {\n ...model,\n byTask: taskSummaries(modelRecords).map(({ task, totals }) => ({ task, totals })),\n };\n });\n}\n\nfunction rebuild(report: UsageReport): UsageReport {\n const updatedAt = report.updatedAt;\n const episodes = new Map<number, EpisodeUsageRun[]>();\n for (const episode of report.episodes) episodes.set(episode.episode, episode.runs);\n const episodeSummaries = [...episodes.entries()]\n .map(([episode, runs]) => {\n const ids = new Set(runs.flatMap((run) => run.recordIds));\n const records = report.records.filter((record) => ids.has(record.id));\n return {\n episode,\n totals: totalsOf(records),\n byTask: taskSummaries(records),\n byModel: modelSummaries(records),\n durationMs: runs.reduce((sum, run) => sum + run.durationMs, 0),\n runs,\n };\n })\n .sort((left, right) => left.episode - right.episode);\n const totals = totalsOf(report.records);\n return {\n ...report,\n updatedAt,\n totals,\n byTask: taskSummaries(report.records),\n byModel: modelSummaries(report.records),\n episodes: episodeSummaries,\n timing: {\n totalDurationMs: report.runs.reduce((sum, run) => sum + run.durationMs, 0),\n modelDurationMs: totals.durationMs,\n episodeDurationMs: episodeSummaries.reduce((sum, episode) => sum + episode.durationMs, 0),\n },\n };\n}\n\nfunction newReport(now: string): UsageReport {\n return {\n version: 2,\n createdAt: now,\n updatedAt: now,\n totals: emptyTotals(),\n byTask: [],\n byModel: [],\n episodes: [],\n runs: [],\n records: [],\n timing: { totalDurationMs: 0, modelDurationMs: 0, episodeDurationMs: 0 },\n };\n}\n\nfunction iso(ms: number): string {\n return new Date(ms).toISOString();\n}\n\n// Owns one process run. `flush` advances an in-memory cursor over executor events;\n// an event can therefore be persisted exactly once even though usage.json is\n// rewritten after every episode/phase boundary.\nexport class UsageLedger {\n private readonly runId = crypto.randomUUID();\n private readonly startedAtMs: number;\n private cursor: number;\n private report: UsageReport;\n\n constructor(\n private readonly store: WorkspaceStore,\n private readonly executor: LlmTaskExecutor,\n private readonly now: () => number = () => Date.now(),\n ) {\n this.startedAtMs = this.now();\n this.cursor = executor.usageEvents().length;\n const nowIso = iso(this.startedAtMs);\n this.report = store.has(\"usage.json\") ? store.readJson<UsageReport>(\"usage.json\") : newReport(nowIso);\n if (this.report.version !== 2) {\n throw new Error(\"workspace/usage.json uses an incompatible schema; rerun ingest with --force to rebuild the workspace.\");\n }\n for (const run of this.report.runs) {\n if (run.status !== \"running\") continue;\n run.status = \"interrupted\";\n run.endedAt = this.report.updatedAt;\n run.durationMs = Math.max(0, Date.parse(this.report.updatedAt) - Date.parse(run.startedAt));\n }\n this.report.runs.push({\n id: this.runId,\n status: \"running\",\n startedAt: nowIso,\n endedAt: null,\n durationMs: 0,\n });\n this.write(this.startedAtMs);\n }\n\n flush(input: UsageFlush): void {\n const endedAtMs = input.endedAtMs ?? this.now();\n const startedAtMs = input.startedAtMs ?? endedAtMs;\n const events = this.executor.usageEvents();\n const current = events.slice(this.cursor);\n const records = current.map((event) => this.toRecord(event, input.scope));\n this.cursor = events.length;\n this.report.records.push(...records);\n\n if (input.scope.kind === \"episode\") {\n const episodeNumber = input.scope.episode;\n const existing = this.report.episodes.find((episode) => episode.episode === episodeNumber);\n const runs = existing?.runs ?? [];\n runs.push({\n runId: this.runId,\n status: input.status ?? \"succeeded\",\n startedAt: iso(startedAtMs),\n endedAt: iso(endedAtMs),\n durationMs: Math.max(0, endedAtMs - startedAtMs),\n stages: input.stages ?? {},\n recordIds: records.map((record) => record.id),\n });\n if (!existing) {\n this.report.episodes.push({\n episode: episodeNumber,\n totals: emptyTotals(),\n byTask: [],\n byModel: [],\n durationMs: 0,\n runs,\n });\n }\n }\n this.write(endedAtMs);\n }\n\n finish(status: Exclude<UsageRunStatus, \"running\" | \"interrupted\">): void {\n const endedAtMs = this.now();\n if (this.executor.usageEvents().length > this.cursor) {\n this.flush({ scope: { kind: \"run\" }, status: status === \"succeeded\" ? \"succeeded\" : \"failed\", endedAtMs });\n }\n const run = this.report.runs.find((candidate) => candidate.id === this.runId);\n if (run) {\n run.status = status;\n run.endedAt = iso(endedAtMs);\n run.durationMs = Math.max(0, endedAtMs - this.startedAtMs);\n }\n this.write(endedAtMs);\n }\n\n private toRecord(event: LlmUsageEvent, scope: UsageScope): UsageRecord {\n return {\n ...event,\n id: `${this.runId}:${event.sequence}`,\n runId: this.runId,\n scope,\n };\n }\n\n private write(atMs: number): void {\n const run = this.report.runs.find((candidate) => candidate.id === this.runId);\n if (run?.status === \"running\") run.durationMs = Math.max(0, atMs - this.startedAtMs);\n this.report.updatedAt = iso(atMs);\n this.report = rebuild(this.report);\n this.store.writeJson(\"usage.json\", this.report);\n }\n}\n", "// Video ingest pipeline (\u00A710.2, serial rewrite). Two stages:\n// Stage S \u2014 parse episodes one at a time, IN ORDER. Each episode's Gemini call\n// watches the video WITH the running cross-episode context (registry + plot\n// digest + open threads) and returns both the episode content and a registry\n// delta. Identity is resolved by plot as we go, so there is no parallel\n// transcribe + roster-merge + correct + speaker compensation. Checkpoint =\n// per episode: ep/ep_NNN.json (content) + context.json (running context,\n// authoritative for resume). script.json is rebuilt after each episode so an\n// editor can stream it as it grows.\n// Stage F \u2014 the deterministic tail, SHARED with text ingest: rename provisional\n// names to their revealed identities \u2192 docsToNameScript \u2192 assignProvisionalIds\n// \u2192 stampRegistryMetadata \u2192 governDeterministic \u2192 renumberIds \u2192 validateScriptV3.\n// The final script.json is the same v4 dialect as text ingest.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT } from \"../../common.js\";\nimport { formatFailure } from \"../../failures.js\";\nimport { assignProvisionalIds } from \"../../domain/ingest/assembler.js\";\nimport { governDeterministic } from \"../../domain/ingest/govern.js\";\nimport { validateProductionStandard } from \"../../domain/ingest/production-validation.js\";\nimport { renumberIds } from \"../../domain/ingest/renumber.js\";\nimport { validateScriptV3 } from \"../../domain/ingest/validation.js\";\nimport {\n classifyVideoSourceEvolution,\n validateContinuousEpisodeSequence,\n type VideoSourceEpisodeIdentity,\n} from \"../../domain/ingest/video-source-evolution.js\";\nimport { requireScriptV3 } from \"../../domain/script/v3/parse.js\";\nimport {\n emptyV4IdentityMap,\n newScriptV4FromV3WithIdentity,\n type V3IdentityKeys,\n type V4IdentityMap,\n} from \"../../domain/script/v4/from-v3.js\";\nimport type { ScriptV4 } from \"../../domain/script/v4/types.js\";\nimport { validateScriptV4 } from \"../../domain/script/v4/validation.js\";\nimport { applyRename, docsToNameScript } from \"../../domain/ingest/video-apply.js\";\nimport { buildVideoStateEvidencePlan } from \"../../domain/ingest/video-state-evidence.js\";\nimport {\n applyDelta,\n buildAliasMap,\n deltaToDoc,\n emptyContext,\n renderContext,\n stampRegistryMetadata,\n type RunContext,\n} from \"../../domain/ingest/video-context.js\";\nimport type { VideoEpisodeDoc } from \"../../domain/ingest/video-records.js\";\nimport { resolveSource } from \"../../infra/ingest/source-resolver.js\";\nimport { discoverEpisodes } from \"../../infra/ingest/video-discovery.js\";\nimport {\n snapshotVideoSource,\n videoSourceFingerprint,\n} from \"../../infra/ingest/video-source-snapshot.js\";\nimport { transcodeForUpload } from \"../../infra/ingest/video-transcode.js\";\nimport { materializeVideoStateEvidence } from \"../../infra/ingest/video-state-evidence.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\nimport { withIngestWorkspaceLock } from \"../../infra/ingest/workspace-lock.js\";\nimport { runVideoSerial } from \"../../llm/tasks/ingest/video-serial.js\";\nimport {\n MAX_INLINE_VIDEO_BYTES,\n type LlmTaskExecutor,\n type TaskVideoPort,\n type VideoUploadMode,\n} from \"../../llm/types.js\";\nimport { UsageLedger } from \"./usage-report.js\";\nimport { createEpisodeErrorSidecar, recoveryHint, type IngestErrorSidecar } from \"./failure.js\";\nimport {\n assertVideoSkipSources,\n markSkippedEpisodes,\n readAcceptedVideoDocs,\n reconcileVideoSkips,\n type VideoSkipRecord,\n} from \"./video-skip-state.js\";\n\nexport const VIDEO_PIPELINE_VERSION = \"19\"; // detailed reproducible visual-state descriptions\nconst COMPATIBLE_VIDEO_PIPELINE_VERSIONS = new Set([VIDEO_PIPELINE_VERSION]);\nconst pad = (n: number): string => String(n).padStart(3, \"0\");\nconst VIDEO_VALIDATION_ATTEMPTS = 2;\n\nexport interface VideoIngestOptions {\n sourcePath: string;\n workspacePath: string;\n executor: LlmTaskExecutor;\n fps?: number;\n force?: boolean;\n step?: boolean;\n uploadMode?: VideoUploadMode;\n signal?: AbortSignal;\n}\n\nexport interface VideoIngestReport {\n workspacePath: string;\n episodes: number;\n processed: number;\n reused: number;\n skipped: number;\n skippedEpisodes: number[];\n completed: number;\n remaining: number;\n complete: boolean;\n nextEpisode: number | null;\n uploadMode: VideoUploadMode;\n assets: { actors: number; locations: number; props: number };\n evidence: { states: number; samples: number; ready: number };\n scriptPath: string;\n validation: { ok: boolean; errors: number; warnings: number };\n}\n\nexport type VideoSourceKind = \"video-file\" | \"video-directory\";\n\nexport interface VideoIngestManifest {\n version: 2;\n pipeline_version: string;\n updated: string;\n source: {\n kind: VideoSourceKind;\n path: string;\n sha256: string;\n };\n episodes: VideoSourceEpisodeIdentity[];\n fps: number;\n current_error?: IngestErrorSidecar;\n skips?: VideoSkipRecord[];\n}\n\n// Per-episode timing, appended a line at a time to timing.jsonl so a long run's\n// costs are inspectable live (which episode uploaded/generated how long).\ninterface EpisodeTiming {\n episode: number;\n uploadMode: VideoUploadMode;\n status: \"succeeded\" | \"failed\";\n totalMs: number;\n transcodeMs?: number;\n uploadMs?: number;\n generateMs?: number;\n uploadBytes?: number;\n transcoded?: boolean;\n note?: string;\n}\n\nfunction fileSize(p: string): number {\n try { return fs.statSync(p).size; } catch { return 0; }\n}\n\nexport function assertInlineVideoSize(filePath: string, episode: number): void {\n const bytes = fileSize(filePath);\n if (bytes < MAX_INLINE_VIDEO_BYTES) return;\n throw new CliError(`Episode ${episode} is too large for inline base64 video input.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VIDEO_INLINE_TOO_LARGE\",\n hint: \"Use --upload-mode file-api, or provide a source that transcodes below the Gemini inline limit.\",\n data: {\n expected: [`video smaller than ${MAX_INLINE_VIDEO_BYTES} bytes after ingest transcoding`],\n actual: [`${bytes} bytes`],\n },\n });\n}\n\nfunction appendTiming(store: WorkspaceStore, t: EpisodeTiming): void {\n try {\n const mb = t.uploadBytes ? (t.uploadBytes / 1024 / 1024).toFixed(1) : \"?\";\n const line = JSON.stringify({ ...t, uploadMB: mb, at: new Date().toISOString() }) + \"\\n\";\n fs.appendFileSync(store.path(\"timing.jsonl\"), line);\n } catch { /* timing is diagnostic-only, never fail the run */ }\n}\n\nfunction sourceMismatch(reason: string): CliError {\n return new CliError(\"This workspace's accepted video sequence no longer matches the source.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SOURCE_MISMATCH\",\n hint: \"Restore the accepted episode prefix, or choose a fresh --workspace-path for a different source.\",\n data: { actual: [reason] },\n });\n}\n\nexport function readCurrentVideoManifest(store: WorkspaceStore): VideoIngestManifest | null {\n if (!store.has(\"manifest.json\")) return null;\n const header = store.readJson<{ pipeline_version?: string }>(\"manifest.json\");\n if (!header.pipeline_version || !COMPATIBLE_VIDEO_PIPELINE_VERSIONS.has(header.pipeline_version)) {\n throw new CliError(\"This workspace uses an incompatible video-ingest pipeline.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_PIPELINE_MISMATCH\",\n hint: \"Choose a fresh --workspace-path and run ingest again.\",\n data: { actual: [`workspace pipeline ${header.pipeline_version ?? \"(missing)\"}; current ${VIDEO_PIPELINE_VERSION}`] },\n });\n }\n return store.readJson<VideoIngestManifest>(\"manifest.json\");\n}\n\nexport function migrateVideoManifest(\n store: WorkspaceStore,\n manifest: VideoIngestManifest,\n): VideoIngestManifest {\n if (manifest.pipeline_version === VIDEO_PIPELINE_VERSION) return manifest;\n const migrated: VideoIngestManifest = {\n ...manifest,\n pipeline_version: VIDEO_PIPELINE_VERSION,\n updated: new Date().toISOString(),\n };\n store.writeJson(\"manifest.json\", migrated);\n return migrated;\n}\n\nfunction checkSourceRoot(\n previous: VideoIngestManifest | null,\n sourceKind: VideoSourceKind,\n _sourcePath: string,\n): void {\n if (!previous) return;\n if (previous.source.kind !== sourceKind) {\n throw sourceMismatch(`source kind changed from ${previous.source.kind} to ${sourceKind}`);\n }\n // A directory relocation is not a source identity change. The accepted\n // sequence is guarded below by episode number, media type and file sha256;\n // permitting a new root lets projects safely relink moved/NAS-hosted media.\n}\n\nfunction checkLifecycle(\n store: WorkspaceStore,\n previous: VideoIngestManifest | null,\n episodes: VideoSourceEpisodeIdentity[],\n force: boolean,\n): void {\n if (previous) {\n const evolution = classifyVideoSourceEvolution(previous.episodes, episodes);\n if (evolution.kind === \"incompatible\") throw sourceMismatch(evolution.reason);\n }\n\n if (force) {\n fs.rmSync(store.path(\"ep\"), { recursive: true, force: true });\n fs.rmSync(store.path(\"cache\"), { recursive: true, force: true });\n fs.rmSync(store.path(\"evidence\"), { recursive: true, force: true });\n for (const f of [\n \"context.json\",\n \"script.initial.json\",\n \"script.json\",\n \"validation.json\",\n \"asset-audit.json\",\n \"id_map.json\",\n \"timing.jsonl\",\n \"usage.json\",\n \"v4_identity_map.json\",\n \"skipped.json\",\n ]) fs.rmSync(store.path(f), { force: true });\n }\n}\n\n// Rename docs' structured names plus actor names inside narrative actions through\n// the historical-name alias map before convergence. Spoken content stays verbatim.\n// Deep-cloned so the persisted ep docs are never mutated.\nfunction renameDocs(docs: VideoEpisodeDoc[], alias: Map<string, string>): VideoEpisodeDoc[] {\n const terms = new Map<string, string>();\n for (const [surface, canonical] of alias) {\n terms.set(canonical, canonical);\n terms.set(surface, canonical);\n }\n const orderedTerms = [...terms].sort(([left], [right]) => right.length - left.length);\n const renameActionContent = (content: string): string => {\n let result = \"\";\n let offset = 0;\n while (offset < content.length) {\n const match = orderedTerms.find(([surface]) => content.startsWith(surface, offset));\n if (match) {\n result += match[1];\n offset += match[0].length;\n } else {\n result += content[offset]!;\n offset += 1;\n }\n }\n return result;\n };\n\n return docs.map((d) => {\n const c = JSON.parse(JSON.stringify(d)) as VideoEpisodeDoc;\n for (const a of c.actors) a.name = applyRename(a.name, alias) ?? a.name;\n for (const sc of c.scenes) {\n for (const ch of sc.characters) ch.name = applyRename(ch.name, alias) ?? ch.name;\n if (sc.location) sc.location = applyRename(sc.location, alias) ?? sc.location;\n // Rename props through the alias map, then collapse any pairs that now\n // share a canonical name (surface A + surface B \u2192 same entity).\n const renamedProps: string[] = [];\n const seenProps = new Set<string>();\n for (const prop of sc.props) {\n const name = (applyRename(prop, alias) ?? prop).trim();\n if (!name) continue;\n const key = name.normalize(\"NFC\").replace(/\\s+/g, \" \").trim().toLowerCase();\n if (seenProps.has(key)) continue;\n seenProps.add(key);\n renamedProps.push(name);\n }\n sc.props = renamedProps;\n for (const an of sc.anchors) {\n an.speaker = applyRename(an.speaker, alias);\n if (an.kind === \"act\") an.content = renameActionContent(an.content);\n }\n }\n return c;\n });\n}\n\ninterface FinalizeResult {\n initial: Record<string, unknown>;\n final: Record<string, unknown>;\n idMap: unknown;\n validation: ReturnType<typeof validateScriptV4>;\n identityMap: V4IdentityMap;\n}\n\nfunction validationRetryContext(\n contextText: string,\n errors: FinalizeResult[\"validation\"][\"errors\"],\n): string {\n const details = errors.slice(0, 8).map((error) => `- ${error.path}: ${error.message}`).join(\"\\n\");\n return `${contextText}\\n\\n========== \u4E0A\u4E00\u6B21\u8F93\u51FA\u7684\u6574\u5408\u6821\u9A8C\u53CD\u9988 ==========\n\u4E0A\u4E00\u6B21\u5BF9\u672C\u96C6\u7684\u7ED3\u6784\u5316\u8F93\u51FA\u6CA1\u6709\u5199\u5165 checkpoint\uFF0C\u56E0\u4E3A\u4E0E\u65E2\u6709\u5267\u672C\u5408\u5E76\u540E\u8FDD\u53CD\u4E86\u4EE5\u4E0B\u7EA6\u675F\uFF1A\n${details}\n\u8BF7\u91CD\u65B0\u89C2\u770B\u672C\u96C6\u5E76\u8FD4\u56DE\u5B8C\u6574 JSON\u3002\u4FDD\u6301\u539F\u7247\u4E8B\u5B9E\u3001\u5BF9\u767D\u3001\u955C\u5934\u4E0E\u5DF2\u77E5\u4EBA\u7269\u4E0D\u53D8\uFF0C\u53EA\u4FEE\u6B63\u5BFC\u81F4\u6821\u9A8C\u5931\u8D25\u7684\u4EBA\u7269\u547D\u540D\u3001\u8D44\u4EA7\u7ED1\u5B9A\u6216 registry_delta\u3002\u4EBA\u7269\u89C4\u8303\u540D\u4E0D\u5F97\u7528\u62EC\u53F7\u5907\u6CE8\u533A\u5206\u89D2\u8272\uFF1B\u89D2\u8272\u804C\u80FD\u5199\u5165 role\uFF0C\u4E0D\u540C\u4EBA\u7269\u4F7F\u7528\u5F52\u4E00\u540E\u4ECD\u552F\u4E00\u7684\u89C4\u8303\u540D\u3002`;\n}\n\nconst identityNorm = (value: string): string =>\n value.normalize(\"NFC\").replace(/\\s+/g, \" \").trim().toLowerCase();\n\nfunction videoIdentityKeys(\n assets: ReturnType<typeof assignProvisionalIds>[\"assets\"],\n registry: RunContext[\"registry\"],\n): V3IdentityKeys {\n const aliases = buildAliasMap(registry);\n const resolvedName = (name: string): string => aliases.get(name) ?? name;\n const keyByCanonical = new Map<string, string>();\n for (const entity of registry) {\n const canonical = resolvedName(entity.name);\n const exactTarget = registry.find((candidate) =>\n candidate.kind === entity.kind\n && identityNorm(candidate.name) === identityNorm(canonical));\n const source = exactTarget ?? entity;\n const canonicalKey = `${entity.kind}:${identityNorm(canonical)}`;\n if (!keyByCanonical.has(canonicalKey)) {\n keyByCanonical.set(\n canonicalKey,\n `video:${source.kind}:${source.firstEpisode}:${identityNorm(source.identitySeed)}`,\n );\n }\n }\n const actor: Record<string, string> = {};\n const location: Record<string, string> = {};\n const prop: Record<string, string> = {};\n const state: Record<string, Record<string, string>> = {};\n const byKind = { actor, location, prop };\n for (const asset of assets) {\n const name = asset.names[0] ?? asset.provisional_id;\n const key = keyByCanonical.get(`${asset.kind}:${identityNorm(name)}`)\n ?? `video:${asset.kind}:source:${identityNorm(name)}`;\n byKind[asset.kind][asset.provisional_id] = key;\n state[asset.provisional_id] = Object.fromEntries(\n asset.states.map((state) => [\n state.id,\n `${key}:state:${identityNorm(state.name)}`,\n ]),\n );\n }\n return { actor, location, prop, state };\n}\n\n// Deterministic tail shared with text ingest. Pure (no LLM); ms-fast, so it runs\n// after every episode (streaming) and once at the end (gated on validation).\nexport function finalizeVideoScript(\n docs: VideoEpisodeDoc[],\n ctx: RunContext,\n title: string,\n priorIdentity: V4IdentityMap,\n skips: readonly VideoSkipRecord[] = [],\n): FinalizeResult {\n const alias = buildAliasMap(ctx.registry);\n const renamed = renameDocs(docs, alias);\n const nameScript = docsToNameScript(renamed, title);\n const { script, assets, identityKeys } = assignProvisionalIds(nameScript);\n stampRegistryMetadata(script, ctx.registry);\n const governed = governDeterministic(script);\n const { script: final, idMap } = renumberIds(governed);\n const intermediateValidation = validateScriptV3(final);\n if (!intermediateValidation.ok) {\n return { initial: script, final, idMap, validation: intermediateValidation, identityMap: priorIdentity };\n }\n // Persist identities against the pre-renumber ingest keys. Contiguous V3 ids\n // shift when an earlier entity disappears and therefore are not identities.\n const converted = newScriptV4FromV3WithIdentity(\n requireScriptV3(governed),\n priorIdentity,\n {\n ...videoIdentityKeys(assets, ctx.registry),\n ...identityKeys,\n },\n );\n const scriptV4 = converted.script;\n markSkippedEpisodes(scriptV4, skips);\n const structuralValidation = validateScriptV4(scriptV4);\n const descriptionWarnings = [\n ...scriptV4.actors.map((asset, index) => ({ asset, path: `$.actors[${index}]` })),\n ...scriptV4.locations.map((asset, index) => ({ asset, path: `$.locations[${index}]` })),\n ...scriptV4.props.map((asset, index) => ({ asset, path: `$.props[${index}]` })),\n ].flatMap(({ asset, path }) => [\n ...(!asset.description.trim() ? [{ code: \"video_asset_description_missing\", path: `${path}.description`, message: \"video asset needs a source-grounded description\" }] : []),\n ...asset.states.flatMap((state, stateIndex) => !state.description.trim()\n ? [{ code: \"video_state_description_missing\", path: `${path}.states[${stateIndex}].description`, message: \"video asset state needs a source-grounded visual description\" }]\n : []),\n ]);\n const validation = {\n ...structuralValidation,\n warnings: [\n ...structuralValidation.warnings,\n ...validateProductionStandard(scriptV4),\n ...descriptionWarnings,\n ...skips.map((record) => ({\n code: \"episode_skipped\",\n path: `$.episodes[${record.episode - 1}]`,\n message: `Episode ${record.episode} was manually skipped: ${record.reason}`,\n })),\n ],\n };\n return { initial: script, final: scriptV4, idMap, validation, identityMap: converted.identityMap };\n}\n\nexport function publishFinalizedVideoWorkspace(\n store: WorkspaceStore,\n episodes: ReadonlyArray<{ episode: number }>,\n ctx: RunContext,\n title: string,\n identityMap: V4IdentityMap,\n skips: readonly VideoSkipRecord[],\n): FinalizeResult {\n const finalized = finalizeVideoScript(\n readAcceptedVideoDocs(store, episodes, ctx.lastEpisode, skips),\n ctx,\n title,\n identityMap,\n skips.filter((record) => record.episode <= ctx.lastEpisode),\n );\n const { initial, final, idMap, validation } = finalized;\n store.writeJson(\"script.initial.json\", initial);\n store.writeJson(\"id_map.json\", idMap);\n store.writeJson(\"validation.json\", validation);\n store.writeJson(\"v4_identity_map.json\", finalized.identityMap);\n if (!validation.ok) {\n throw new CliError(\"Final script.json failed validation.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VALIDATION_FAILED\",\n hint: \"Inspect validation.json.\",\n data: { actual: validation.errors.slice(0, 5).map((error) => `${error.path}: ${error.message}`) },\n });\n }\n store.writeJson(\"script.json\", final);\n return finalized;\n}\n\nasync function materializeStateEvidenceForPrefix(\n store: WorkspaceStore,\n docs: VideoEpisodeDoc[],\n script: ScriptV4,\n context: RunContext,\n sources: readonly VideoSourceEpisodeIdentity[],\n sourceSha256: string,\n signal?: AbortSignal,\n) {\n return materializeVideoStateEvidence(\n store,\n buildVideoStateEvidencePlan(docs, script, context, sources, sourceSha256),\n signal,\n );\n}\n\nasync function runVideoIngestUnlocked(opts: VideoIngestOptions): Promise<VideoIngestReport> {\n const resolved = resolveSource(opts.sourcePath);\n if (resolved.kind === \"text\") throw new CliError(\"runVideoIngest received a text source.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_WRONG_PIPELINE\",\n });\n const episodes = [...discoverEpisodes(resolved)].sort((a, b) => a.episode - b.episode);\n const sequenceError = validateContinuousEpisodeSequence(episodes);\n if (sequenceError) {\n throw new CliError(\"Video episodes must form one continuous sequence starting at episode 1.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VIDEO_SEQUENCE\",\n hint: \"Add or rename files so the discovered episode numbers are 1..N with no gaps.\",\n data: { actual: [sequenceError] },\n });\n }\n const fps = opts.fps ?? 3;\n const force = opts.force ?? false;\n const step = opts.step ?? false;\n const uploadMode = opts.uploadMode ?? \"file-api\";\n const sig = opts.signal;\n\n const store = new WorkspaceStore(opts.workspacePath);\n store.ensure();\n const previousManifest = readCurrentVideoManifest(store);\n const sourcePath = path.resolve(resolved.path);\n checkSourceRoot(previousManifest, resolved.kind, sourcePath);\n const sourceEpisodes = snapshotVideoSource(\n episodes,\n previousManifest?.episodes ?? [],\n previousManifest?.updated,\n );\n checkLifecycle(\n store,\n previousManifest,\n sourceEpisodes,\n force,\n );\n const manifest: VideoIngestManifest = {\n version: 2,\n pipeline_version: VIDEO_PIPELINE_VERSION,\n updated: new Date().toISOString(),\n source: {\n kind: resolved.kind,\n path: sourcePath,\n sha256: videoSourceFingerprint(sourceEpisodes),\n },\n episodes: sourceEpisodes,\n fps,\n skips: force ? [] : previousManifest?.skips ?? [],\n };\n store.writeJson(\"manifest.json\", manifest);\n\n const usage = new UsageLedger(store, opts.executor);\n let runStatus: \"succeeded\" | \"failed\" = \"failed\";\n try {\n let port: TaskVideoPort | null = null;\n const title = deriveVideoTitle(opts.sourcePath);\n let ctx: RunContext = !force && store.has(\"context.json\") ? store.readJson<RunContext>(\"context.json\") : emptyContext();\n const skipLedger = { schema_version: 1 as const, episodes: manifest.skips ?? [] };\n assertVideoSkipSources(skipLedger.episodes, sourceEpisodes);\n if (!force) reconcileVideoSkips(store, ctx, skipLedger.episodes);\n const skippedEpisodes = new Set(skipLedger.episodes.map((record) => record.episode));\n let identityMap = !force && store.has(\"v4_identity_map.json\")\n ? store.readJson<V4IdentityMap>(\"v4_identity_map.json\")\n : emptyV4IdentityMap();\n let reused = 0;\n let processed = 0;\n\n // ===== Stage S: serial per-episode parse =====\n for (const e of episodes) {\n const rel = `ep/ep_${pad(e.episode)}.json`;\n if (!force && skippedEpisodes.has(e.episode) && e.episode <= ctx.lastEpisode) continue;\n // Resume: skip only when the episode's content exists AND the running context\n // already accounts for it (a crash between the two writes \u2192 rerun this ep).\n if (!force && store.has(rel) && e.episode <= ctx.lastEpisode) {\n reused++;\n opts.executor.recordReuse(\"ingest.video-serial\");\n const at = Date.now();\n usage.flush({\n scope: { kind: \"episode\", episode: e.episode },\n status: \"reused\",\n startedAtMs: at,\n endedAtMs: at,\n });\n continue;\n }\n if (step && processed >= 1) break;\n\n // Persist the exact context fed to Gemini for this episode (inspectable: what\n // prior-episode knowledge the model saw), before the call so a failed episode\n // still shows its input.\n const ctxMd = renderContext(ctx);\n store.writeText(`ep/ep_${pad(e.episode)}.context.md`, ctxMd);\n let md!: string;\n let doc!: VideoEpisodeDoc;\n let nextContext!: RunContext;\n let streamed!: FinalizeResult;\n const episodeStartedMs = Date.now();\n const timing: EpisodeTiming = { episode: e.episode, uploadMode, status: \"succeeded\", totalMs: 0 };\n let failurePhase = \"transcode\";\n try {\n // Shrink the source before upload while retaining its frame rate so the\n // requested provider sampling rate still has the original temporal detail.\n // Best-effort: falls back to the original.\n const tStart = Date.now();\n const enc = await transcodeForUpload(e.path, store.path(`cache/ep_${pad(e.episode)}.mp4`), e.mime, sig);\n timing.transcodeMs = Date.now() - tStart;\n timing.uploadBytes = fileSize(enc.path);\n timing.transcoded = enc.transcoded;\n if (enc.note) timing.note = enc.note;\n if (uploadMode === \"base64\") assertInlineVideoSize(enc.path, e.episode);\n\n failurePhase = \"upload\";\n port ??= opts.executor.videoPort(\"ingest.video-serial\");\n const uStart = Date.now();\n const media = await port.prepare(enc.path, enc.mime, uploadMode, sig);\n timing.uploadMs = Date.now() - uStart;\n try {\n failurePhase = \"generate\";\n const gStart = Date.now();\n const acceptedDocs = readAcceptedVideoDocs(\n store,\n episodes,\n ctx.lastEpisode,\n skipLedger.episodes,\n );\n let generationContext = ctxMd;\n for (let attempt = 1; attempt <= VIDEO_VALIDATION_ATTEMPTS; attempt++) {\n const generated = await runVideoSerial(\n port,\n media,\n e.episode,\n generationContext,\n fps,\n sig,\n { path: enc.path, mime: enc.mime },\n );\n const candidateDoc = deltaToDoc(generated.output, e.episode);\n const candidateContext = structuredClone(ctx);\n applyDelta(candidateContext, generated.output, e.episode);\n const candidate = finalizeVideoScript(\n [...acceptedDocs, candidateDoc],\n candidateContext,\n title,\n identityMap,\n skipLedger.episodes.filter((record) => record.episode <= e.episode),\n );\n if (candidate.validation.ok) {\n md = generated.md;\n doc = candidateDoc;\n nextContext = candidateContext;\n streamed = candidate;\n break;\n }\n failurePhase = \"validation\";\n if (attempt === VIDEO_VALIDATION_ATTEMPTS) {\n throw new CliError(\"Final script.json failed validation after model correction.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VALIDATION_FAILED\",\n hint: \"Rerun ingest to continue with the next configured model route.\",\n data: {\n actual: candidate.validation.errors.slice(0, 8)\n .map((error) => `${error.path}: ${error.message}`),\n },\n });\n }\n generationContext = validationRetryContext(ctxMd, candidate.validation.errors);\n }\n timing.generateMs = Date.now() - gStart;\n } finally {\n await port.release(media, sig).catch(() => {}); // best-effort cleanup; serial never reuses media\n // Drop the local transcode once uploaded+parsed \u2014 it is a disposable cache.\n if (enc.transcoded) fs.rmSync(enc.path, { force: true });\n }\n } catch (err) {\n const endedAtMs = Date.now();\n timing.status = \"failed\";\n timing.totalMs = endedAtMs - episodeStartedMs;\n appendTiming(store, timing);\n usage.flush({\n scope: { kind: \"episode\", episode: e.episode },\n status: \"failed\",\n startedAtMs: episodeStartedMs,\n endedAtMs,\n stages: timing,\n });\n const sidecarPhase = err instanceof CliError && err.errorCode === \"INGEST_VIDEO_SERIAL_FAILED\"\n ? \"parse\"\n : failurePhase;\n const sidecar = createEpisodeErrorSidecar(err, e.episode, sidecarPhase);\n const detail = formatFailure(sidecar.failure);\n store.writeJson(`ep/ep_${pad(e.episode)}.error.json`, sidecar);\n store.writeJson(\"manifest.json\", { ...manifest, updated: sidecar.occurred_at, current_error: sidecar });\n if (err instanceof CliError && (\n err.errorCode === \"INGEST_VIDEO_INLINE_TOO_LARGE\"\n || err.errorCode === \"INGEST_VALIDATION_FAILED\"\n )) throw err;\n throw new CliError(`Episode ${e.episode} failed serial parse; later episodes depend on its context.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SERIAL_INCOMPLETE\",\n hint: recoveryHint(sidecar.failure),\n data: { actual: [detail] },\n });\n }\n\n ctx = nextContext;\n processed += 1;\n store.writeText(`ep/ep_${pad(e.episode)}.md`, md); // raw transcript for human review\n store.writeJson(rel, doc);\n store.writeJson(\"context.json\", ctx);\n store.clearError(`ep/ep_${pad(e.episode)}.error.json`);\n const episodeEndedMs = Date.now();\n timing.totalMs = episodeEndedMs - episodeStartedMs;\n appendTiming(store, timing); // per-episode transcode/upload/generate durations\n usage.flush({\n scope: { kind: \"episode\", episode: e.episode },\n status: \"succeeded\",\n startedAtMs: episodeStartedMs,\n endedAtMs: episodeEndedMs,\n stages: timing,\n });\n\n // Publish only after the candidate episode and its updated registry validate\n // together. A bad model response is never allowed to advance the checkpoint.\n identityMap = streamed.identityMap;\n store.writeJson(\"v4_identity_map.json\", identityMap);\n store.writeJson(\"script.json\", streamed.final);\n }\n\n // ===== Stage F: deterministic finalize (gated) =====\n const completed = Math.min(ctx.lastEpisode, episodes.length);\n const remaining = episodes.length - completed;\n const complete = remaining === 0;\n const nextEpisode = complete ? null : episodes[completed]?.episode ?? null;\n const finalized = publishFinalizedVideoWorkspace(\n store,\n episodes.slice(0, completed),\n ctx,\n title,\n identityMap,\n skipLedger.episodes,\n );\n const { final, validation } = finalized;\n const evidence = complete\n ? await materializeStateEvidenceForPrefix(\n store,\n readAcceptedVideoDocs(store, episodes, ctx.lastEpisode, skipLedger.episodes),\n final as ScriptV4,\n ctx,\n sourceEpisodes,\n manifest.source.sha256,\n sig,\n )\n : { items: [] };\n const evidenceSamples = evidence.items.flatMap((item) => item.samples);\n\n const g = final as { actors?: unknown[]; locations?: unknown[]; props?: unknown[] };\n runStatus = \"succeeded\";\n return {\n workspacePath: store.root,\n episodes: episodes.length,\n processed,\n reused,\n skipped: skipLedger.episodes.length,\n skippedEpisodes: skipLedger.episodes.map((record) => record.episode),\n completed,\n remaining,\n complete,\n nextEpisode,\n uploadMode,\n assets: { actors: g.actors?.length ?? 0, locations: g.locations?.length ?? 0, props: g.props?.length ?? 0 },\n evidence: {\n states: evidence.items.length,\n samples: evidenceSamples.length,\n ready: evidenceSamples.filter((sample) => sample.frame_status === \"ready\").length,\n },\n scriptPath: store.path(\"script.json\"),\n validation: { ok: validation.ok, errors: validation.errors.length, warnings: validation.warnings.length },\n };\n } finally {\n usage.finish(runStatus);\n }\n}\n\nexport async function runVideoIngest(opts: VideoIngestOptions): Promise<VideoIngestReport> {\n return withIngestWorkspaceLock(opts.workspacePath, () => runVideoIngestUnlocked(opts));\n}\n\nexport function deriveVideoTitle(sourcePath: string): string {\n const base = path.basename(sourcePath, path.extname(sourcePath));\n return base || \"\";\n}\n", "export interface VideoSourceEpisodeIdentity {\n episode: number;\n path: string;\n ext: string;\n mime: string;\n sha256: string;\n size_bytes?: number;\n mtime_ms?: number;\n /** Container duration used to reject impossible evidence timestamps. */\n duration_ms?: number;\n}\n\nexport type VideoSourceEvolution =\n | { kind: \"unchanged\"; appended: [] }\n | { kind: \"append\"; appended: VideoSourceEpisodeIdentity[] }\n | { kind: \"incompatible\"; reason: string };\n\nfunction identityMismatch(\n previous: VideoSourceEpisodeIdentity,\n current: VideoSourceEpisodeIdentity,\n): string | null {\n if (previous.episode !== current.episode) {\n return `episode ${previous.episode} was replaced by episode ${current.episode}`;\n }\n if (previous.ext !== current.ext || previous.mime !== current.mime) {\n return `episode ${previous.episode} changed media type`;\n }\n if (previous.sha256 !== current.sha256) {\n return `episode ${previous.episode} content changed`;\n }\n return null;\n}\n\nexport function classifyVideoSourceEvolution(\n previous: VideoSourceEpisodeIdentity[],\n current: VideoSourceEpisodeIdentity[],\n): VideoSourceEvolution {\n if (current.length < previous.length) {\n return {\n kind: \"incompatible\",\n reason: `source removed ${previous.length - current.length} previously accepted episode(s)`,\n };\n }\n\n for (let index = 0; index < previous.length; index += 1) {\n const mismatch = identityMismatch(previous[index]!, current[index]!);\n if (mismatch) return { kind: \"incompatible\", reason: mismatch };\n }\n\n const appended = current.slice(previous.length);\n return appended.length === 0\n ? { kind: \"unchanged\", appended: [] }\n : { kind: \"append\", appended };\n}\n\nexport function validateContinuousEpisodeSequence(\n episodes: ReadonlyArray<{ episode: number }>,\n): string | null {\n for (let index = 0; index < episodes.length; index += 1) {\n const expected = index + 1;\n const actual = episodes[index]!.episode;\n if (actual !== expected) {\n return `expected episode ${expected}, found episode ${actual}`;\n }\n }\n return null;\n}\n", "/**\n * Canonicalize a video-model clock value before it enters Script.\n *\n * Models occasionally express the exact minute boundary as `00:60`. The value\n * is unambiguous, so carry overflow into the next minute. Values that are not a\n * clock-shaped string stay unchanged and are reported by Script validation.\n */\nexport function normalizeVideoTimestamp(raw: unknown): string {\n const input = typeof raw === \"string\" ? raw.trim().replace(/\\.\\d+$/, \"\") : \"\";\n const match = input.match(/^(?:(\\d+):)?(\\d+):(\\d{2})$/);\n if (!match) return input;\n const hours = Number(match[1] ?? 0);\n const minutes = Number(match[2]);\n const seconds = Number(match[3]);\n if (![hours, minutes, seconds].every(Number.isSafeInteger)) return input;\n const totalSeconds = hours * 3600 + minutes * 60 + seconds;\n const canonicalHours = Math.floor(totalSeconds / 3600);\n const canonicalMinutes = Math.floor((totalSeconds % 3600) / 60);\n const canonicalSeconds = totalSeconds % 60;\n return canonicalHours > 0\n ? `${canonicalHours}:${String(canonicalMinutes).padStart(2, \"0\")}:${String(canonicalSeconds).padStart(2, \"0\")}`\n : `${String(canonicalMinutes).padStart(2, \"0\")}:${String(canonicalSeconds).padStart(2, \"0\")}`;\n}\n", "// Video docs \u2192 shared NameScript convergence (\u00A710.2). Converts per-episode video\n// docs into the SHARED NameScript so the common tail (assignProvisionalIds \u2192\n// govern \u2192 renumber \u2192 validate) produces the exact same v3 as text ingest.\n// applyRename folds the serial pipeline's provisional\u2192real alias map into the\n// structured name fields; the deterministic finalize sweep owns that map.\n\nimport type { NameScene, NameScript } from \"./assembler.js\";\nimport type { NameStateRef, SpeakerRef } from \"./records.js\";\nimport { isCrowdName } from \"./serial-context.js\";\nimport type { VideoEpisodeDoc } from \"./video-records.js\";\nimport { normalizeSceneTime } from \"./environment.js\";\nimport { normalizeVideoTimestamp } from \"./video-timestamp.js\";\n\n// Rename a name, preserving a typed speaker prefix (broadcast:xxx \u2192 only xxx).\nexport function applyRename(name: string | undefined, map: Map<string, string>): string | undefined {\n if (!name) return name;\n const m = name.match(/^(\\w+):(.+)$/);\n if (m) return `${m[1]}:${map.get(m[2]!) ?? m[2]}`;\n return map.get(name) ?? name;\n}\n\nconst pad = (n: number): string => String(n).padStart(3, \"0\");\nconst SPACE_ZH_TO_EN: Record<string, string> = { \"\u5185\": \"interior\", \"\u5916\": \"exterior\" };\nconst KIND_TO_TYPE: Record<string, string> = { act: \"action\", dlg: \"dialogue\", think: \"inner_thought\" };\n// scaffold typed-speaker prefixes \u2192 v3 non-actor speaker kinds.\nconst KIND_MAP: Record<string, \"system\" | \"broadcast\" | \"offscreen\" | \"group\"> = {\n broadcast: \"broadcast\", system: \"system\", group: \"group\", offscreen: \"offscreen\", prop: \"offscreen\", location: \"offscreen\",\n};\n\nfunction toSpeaker(raw: string): SpeakerRef {\n const m = raw.match(/^(\\w+):(.+)$/);\n if (m && KIND_MAP[m[1]!]) { const label = m[2]!.trim(); return label ? { kind: KIND_MAP[m[1]!]!, label } : { kind: KIND_MAP[m[1]!]! }; }\n if (isCrowdName(raw)) return { kind: \"group\", label: raw.trim() };\n return { name: raw };\n}\n\n// Convert video docs \u2192 the shared NameScript (name-based, plain-text content,\n// scene-level cast). Timestamps ride action.extend.timestamp through to the final\n// v3. Actor speakers are added to the scene cast (mirrors assemble()).\nexport function docsToNameScript(docs: VideoEpisodeDoc[], title: string): NameScript {\n let scn = 0;\n const episodes = docs.map((d, ei) => {\n const episodeIdentityKey = `video:episode:${d.episode}`;\n const sceneIdentityOccurrences = new Map<string, number>();\n return {\n identity_key: episodeIdentityKey,\n episode_id: `ep_${pad(ei + 1)}`,\n scenes: d.scenes.map((s): NameScene => {\n const sceneAnchor = s.timeRange?.trim()\n ? `time:${s.timeRange.trim()}`\n : `index:${s.index}`;\n const sceneOccurrence = (sceneIdentityOccurrences.get(sceneAnchor) ?? 0) + 1;\n sceneIdentityOccurrences.set(sceneAnchor, sceneOccurrence);\n const sceneIdentityKey = `${episodeIdentityKey}:scene:${sceneAnchor}:${sceneOccurrence}`;\n const env: { space?: string; time?: string } = {};\n const sp = SPACE_ZH_TO_EN[(s.environment.space ?? \"\").trim()];\n const tm = normalizeSceneTime(s.environment.time);\n if (sp) env.space = sp;\n if (tm) env.time = tm;\n\n const actors: NameStateRef[] = [];\n const ensureSpeakerActor = (name: string): void => {\n if (!actors.some((actor) => actor.name === name)) actors.push({ name });\n };\n for (const ch of s.characters) {\n if (ch.name && !isCrowdName(ch.name)) {\n if (ch.states.length === 0) actors.push({ name: ch.name });\n else actors.push(...ch.states.map((state) => ({ name: ch.name, state })));\n }\n }\n\n const actionIdentityOccurrences = new Map<string, number>();\n const actions = s.anchors.map((a) => {\n const timestamp = normalizeVideoTimestamp(a.ts);\n const actionAnchor = timestamp\n ? `time:${timestamp}`\n : `content:${JSON.stringify([a.kind, a.speaker ?? \"\", a.content])}`;\n const actionOccurrence = (actionIdentityOccurrences.get(actionAnchor) ?? 0) + 1;\n actionIdentityOccurrences.set(actionAnchor, actionOccurrence);\n const out: NameScene[\"actions\"][number] = {\n identity_key: `${sceneIdentityKey}:action:${actionAnchor}:${actionOccurrence}`,\n type: KIND_TO_TYPE[a.kind] ?? \"action\",\n content: a.content,\n };\n if ((a.kind === \"dlg\" || a.kind === \"think\") && a.speaker) {\n const spk = toSpeaker(a.speaker);\n out.speaker = spk;\n if (\"name\" in spk) ensureSpeakerActor(spk.name); // actor speaker is present\n }\n if (a.parenthetical) out.parenthetical = a.parenthetical;\n const ts = normalizeVideoTimestamp(a.ts);\n if (ts) out.extend = { timestamp: ts };\n return out;\n });\n\n const loc = (s.location ?? \"\").trim();\n // Scene props must be unique by normalized name: Script v3 forbids\n // duplicate prop_id on one scene, and the video model occasionally\n // lists the same prop twice (or alias-collapsed names become one).\n const props: NameStateRef[] = [];\n const seenProps = new Set<string>();\n for (const p of s.props ?? []) {\n if (!p) continue;\n const key = p.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n if (!key || seenProps.has(key)) continue;\n seenProps.add(key);\n props.push({ name: p });\n }\n return {\n identity_key: sceneIdentityKey,\n scene_id: `scn_${pad(++scn)}`,\n ...(env.space || env.time ? { environment: env } : {}),\n location: loc ? { name: loc } : null,\n actors,\n props,\n actions,\n };\n }),\n };\n });\n return { title, episodes };\n}\n", "// Serial video-ingest running context (\u00A710.2 rewrite). Pure & deterministic \u2014\n// no LLM. As episodes are parsed one at a time, this carries a global entity\n// registry (canonical + provisional identities with visual anchors, plot role,\n// known outfit states) plus a compacting plot digest and open story threads.\n// renderContext() serializes it into the markdown block fed back into the next\n// episode's parse so the model resolves identity by plot \u2014 not by re-matching\n// faces in isolation. identitySeed stays fixed while direct naming evidence may\n// upgrade the current canonical name; previous names accumulate as aliases for\n// the deterministic finalize sweep (buildAliasMap \u2192 renameDocs).\n\nimport type { SerialIdentityProfile, SerialOutput, SerialStateDescription } from \"./video-serial-md.js\";\nimport type { VideoAnchor, VideoEpisodeDoc, VideoScene } from \"./video-records.js\";\nimport { isCrowdName } from \"./serial-context.js\";\n\nexport type EntityKind = \"actor\" | \"location\" | \"prop\";\n\nexport interface RegistryState {\n name: string;\n description: string;\n}\n\nexport interface RegistryEntity {\n identitySeed: string; // immutable first-seen name used by stable Script v4 identity\n name: string; // current canonical display name\n kind: EntityKind;\n status: \"canonical\" | \"provisional\";\n importance: \"featured\" | \"background\";\n recognitionAnchors: string[]; // discriminative stable cues for cross-episode re-identification\n identityProfile?: SerialIdentityProfile; // actor-only stable physical and voice traits\n appearance?: string; // location/prop visible form\n role: string; // plot identity / relationships\n aliases: string[]; // other surface names seen\n states: RegistryState[]; // known durable visual states \u2014 reused across episodes to stop drift\n firstEpisode: number;\n lastEpisode: number;\n}\n\nconst EMPTY_IDENTITY_PROFILE = (): SerialIdentityProfile => ({\n apparent_gender: \"\",\n apparent_age: \"\",\n face_shape: \"\",\n brows_eyes: \"\",\n nose: \"\",\n mouth: \"\",\n skin_features: \"\",\n hair: \"\",\n build: \"\",\n persistent_marks: [],\n voice: \"\",\n});\n\nexport interface EpisodeDigest {\n episode: number;\n synopsis: string;\n outcome?: \"parsed\" | \"skipped\";\n}\n\nexport interface OpenThread {\n id: string;\n text: string;\n sinceEpisode: number;\n}\n\nexport interface RunContext {\n lastEpisode: number;\n registry: RegistryEntity[];\n digests: EpisodeDigest[];\n openThreads: OpenThread[];\n}\n\nexport function emptyContext(): RunContext {\n return { lastEpisode: 0, registry: [], digests: [], openThreads: [] };\n}\n\nconst norm = (s: string): string => s.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\nconst clip = (s: string, n: number): string => (s.length > n ? `${s.slice(0, n)}\u2026` : s);\n\nfunction findRegistryEntity(registry: RegistryEntity[], name: string): RegistryEntity | undefined {\n const key = norm(name);\n return registry.find((entity) =>\n norm(entity.name) === key\n || norm(entity.identitySeed) === key\n || entity.aliases.some((alias) => norm(alias) === key));\n}\n\nconst RECENT_N = 3; // recent episodes kept with full synopsis\nconst CHAR_BUDGET = 12000; // renderContext output ceiling; shrink the window to fit\n\nfunction pushUniq(arr: string[], v?: string): void {\n const s = (v ?? \"\").trim();\n if (s && !arr.includes(s)) arr.push(s);\n}\n\nconst PROFILE_TEXT_KEYS = [\n \"apparent_gender\",\n \"apparent_age\",\n \"face_shape\",\n \"brows_eyes\",\n \"nose\",\n \"mouth\",\n \"skin_features\",\n \"hair\",\n \"build\",\n \"voice\",\n] as const;\n\nfunction mergeIdentityProfile(\n current: SerialIdentityProfile | undefined,\n patch: Partial<SerialIdentityProfile> | undefined,\n overwrite: boolean,\n): SerialIdentityProfile | undefined {\n if (!patch) return current;\n const profile = current ? { ...current, persistent_marks: [...current.persistent_marks] } : EMPTY_IDENTITY_PROFILE();\n for (const key of PROFILE_TEXT_KEYS) {\n const value = patch[key]?.trim() ?? \"\";\n if (value && (overwrite || !profile[key])) profile[key] = value;\n }\n for (const mark of patch.persistent_marks ?? []) pushUniq(profile.persistent_marks, mark);\n return profile;\n}\n\nfunction upsertState(states: RegistryState[], incoming: SerialStateDescription, overwrite: boolean): void {\n const name = incoming.name.trim();\n if (!name) return;\n const description = incoming.description.trim();\n const existing = states.find((state) => norm(state.name) === norm(name));\n if (!existing) {\n states.push({ name, description });\n return;\n }\n if (description && (overwrite || !existing.description)) existing.description = description;\n}\n\n// Merge fresh evidence into an existing registry entity: unions recognition\n// anchors, aliases, and states while patching identity-profile fields independently.\n// `overwrite` controls scalar identity-profile fields plus appearance/role:\n// - false (a re-registration of a known name via \u65B0\u589E): fill empties only, never\n// clobber what we already know.\n// - true (an explicit \u4FEE\u6B63 correction): the model deliberately looked again and\n// gives a better value \u2192 replace even a non-empty field.\nfunction enrichEntity(\n e: RegistryEntity,\n d: {\n add_recognition_anchors?: string[];\n identity_profile_patch?: Partial<SerialIdentityProfile>;\n appearance?: string;\n role?: string;\n add_aliases?: string[];\n add_states?: SerialStateDescription[];\n },\n episode: number,\n overwrite = false,\n): void {\n const set = (has: string | undefined, val: string | undefined): string | undefined => {\n const v = (val ?? \"\").trim();\n if (!v) return has;\n return overwrite || !has ? v : has;\n };\n for (const anchor of d.add_recognition_anchors ?? []) pushUniq(e.recognitionAnchors, anchor);\n e.identityProfile = mergeIdentityProfile(e.identityProfile, d.identity_profile_patch, overwrite);\n const appearance = set(e.appearance, d.appearance);\n if (appearance) e.appearance = appearance;\n e.role = set(e.role, d.role) ?? e.role;\n for (const a of d.add_aliases ?? []) pushUniq(e.aliases, a);\n for (const state of d.add_states ?? []) upsertState(e.states, state, overwrite);\n e.lastEpisode = episode;\n}\n\n// Fold one episode's serial output into the context. Mutates and returns ctx\n// (called once per episode in the serial loop).\nexport function applyDelta(ctx: RunContext, out: SerialOutput, episode: number): RunContext {\n const find = (name: string): RegistryEntity | undefined => findRegistryEntity(ctx.registry, name);\n\n for (const ne of out.registry_delta.new_entities) {\n const name = ne.name.trim();\n if (!name) continue;\n if (ne.kind === \"actor\" && isCrowdName(name)) continue;\n const existing = find(name);\n if (existing) {\n enrichEntity(existing, {\n add_recognition_anchors: ne.recognition_anchors,\n identity_profile_patch: ne.identity_profile,\n appearance: ne.appearance,\n role: ne.role,\n add_aliases: ne.aliases,\n add_states: ne.states,\n }, episode);\n continue;\n }\n const states: RegistryState[] = [];\n for (const state of ne.states ?? []) upsertState(states, state, false);\n const aliases: string[] = [];\n for (const a of ne.aliases ?? []) pushUniq(aliases, a);\n ctx.registry.push({\n identitySeed: name,\n name,\n kind: ne.kind,\n status: ne.status,\n importance: ne.importance,\n recognitionAnchors: [...new Set((ne.recognition_anchors ?? []).map((anchor) => anchor.trim()).filter(Boolean))],\n ...(ne.identity_profile ? { identityProfile: mergeIdentityProfile(undefined, ne.identity_profile, true) } : {}),\n ...(ne.appearance ? { appearance: ne.appearance.trim() } : {}),\n role: (ne.role ?? \"\").trim(),\n aliases,\n states,\n firstEpisode: episode,\n lastEpisode: episode,\n });\n }\n\n // enrich = the \u4FEE\u6B63 section: an explicit correction of a known entity \u2192 overwrite.\n for (const en of out.registry_delta.enrich) {\n const e = find(en.name);\n if (!e) continue;\n enrichEntity(e, en, episode, true);\n }\n\n for (const change of out.registry_delta.canonicalize) {\n const source = find(change.from_name);\n const canonicalName = change.canonical_name.trim();\n if (!source || !canonicalName || norm(canonicalName) === norm(source.name)) continue;\n const target = find(canonicalName);\n\n if (target && target !== source) {\n // Preserve the identity that entered the story first; on a tie, prefer the\n // already-canonical target. Display metadata comes from the named target,\n // while lists and appearance history are combined without loss.\n const stable = source.firstEpisode < target.firstEpisode ? source : target;\n const other = stable === source ? target : source;\n const stableStates = stable.states.map((state) => ({ ...state }));\n const aliases = new Set([\n ...source.aliases,\n ...target.aliases,\n source.identitySeed,\n target.identitySeed,\n source.name,\n target.name,\n change.from_name,\n ].map((name) => name.trim()).filter(Boolean));\n\n stable.name = canonicalName;\n stable.status = \"canonical\";\n stable.importance = source.importance === \"featured\" || target.importance === \"featured\" ? \"featured\" : \"background\";\n stable.recognitionAnchors = [];\n for (const anchor of [...source.recognitionAnchors, ...target.recognitionAnchors]) pushUniq(stable.recognitionAnchors, anchor);\n const sourceProfile = mergeIdentityProfile(undefined, source.identityProfile, true);\n stable.identityProfile = mergeIdentityProfile(sourceProfile, target.identityProfile, true);\n if (target.appearance || source.appearance) stable.appearance = target.appearance || source.appearance;\n stable.role = target.role || source.role;\n stable.states = [];\n for (const state of [...stableStates, ...other.states]) upsertState(stable.states, state, false);\n stable.aliases = [...aliases].filter((alias) => norm(alias) !== norm(canonicalName));\n stable.firstEpisode = Math.min(source.firstEpisode, target.firstEpisode);\n stable.lastEpisode = Math.max(source.lastEpisode, target.lastEpisode, episode);\n ctx.registry.splice(ctx.registry.indexOf(other), 1);\n continue;\n }\n\n pushUniq(source.aliases, source.name);\n pushUniq(source.aliases, change.from_name);\n source.name = canonicalName;\n source.status = \"canonical\";\n source.aliases = source.aliases.filter((alias) => norm(alias) !== norm(canonicalName));\n source.lastEpisode = episode;\n }\n\n let seq = 0;\n for (const op of out.open_threads.opened) {\n const text = op.text.trim();\n if (text) ctx.openThreads.push({ id: `t${episode}_${++seq}`, text, sinceEpisode: episode });\n }\n for (const cl of out.open_threads.closed) {\n const ref = cl.ref.trim();\n if (ref) ctx.openThreads = ctx.openThreads.filter((t) => t.id !== ref && t.text !== ref);\n }\n\n ctx.digests.push({ episode, synopsis: (out.synopsis ?? \"\").trim() });\n ctx.lastEpisode = episode;\n return ctx;\n}\n\nexport function advanceSkippedEpisode(ctx: RunContext, episode: number): RunContext {\n ctx.digests.push({ episode, synopsis: \"\", outcome: \"skipped\" });\n ctx.lastEpisode = episode;\n return ctx;\n}\n\n// ===== renderContext (compaction folded in) =====\n\nfunction renderActor(e: RegistryEntity, hard: boolean): string[] {\n const L: string[] = [];\n const tag = e.status === \"provisional\" ? \"\u00B7\u5F85\u5B9A \u26A0\" : `\u00B7${e.importance}`;\n L.push(`### ${e.name} ${tag}`);\n if (e.role) L.push(`- \u4F5C\u7528: ${clip(e.role, hard ? 40 : 200)}`);\n if (e.recognitionAnchors.length) L.push(`- \u8BC6\u522B\u951A\u70B9: ${e.recognitionAnchors.join(\"\uFF1B\")}`);\n const profile = e.identityProfile;\n if (profile) {\n const ageGender = [profile.apparent_gender, profile.apparent_age].filter(Boolean).join(\"\uFF0C\");\n if (ageGender) L.push(`- \u5E74\u9F84\u6027\u522B: ${ageGender}`);\n if (profile.face_shape) L.push(`- \u8138\u578B\u4E0B\u988C: ${profile.face_shape}`);\n if (profile.brows_eyes) L.push(`- \u7709\u773C: ${profile.brows_eyes}`);\n if (profile.nose) L.push(`- \u9F3B\u90E8: ${profile.nose}`);\n if (profile.mouth) L.push(`- \u5507\u5F62\u5634\u89D2: ${profile.mouth}`);\n if (profile.skin_features) L.push(`- \u80A4\u8272\u9762\u90E8: ${profile.skin_features}`);\n if (profile.hair) L.push(`- \u53D1\u578B: ${profile.hair}`);\n if (profile.build) L.push(`- \u4F53\u6001: ${profile.build}`);\n if (profile.persistent_marks.length) L.push(`- \u56FA\u5B9A\u6807\u8BB0: ${profile.persistent_marks.join(\"\uFF1B\")}`);\n if (profile.voice) L.push(`- \u58F0\u7EBF: ${profile.voice}`);\n }\n if (e.aliases.length) L.push(`- \u66FE\u7528\u79F0\u547C: ${e.aliases.join(\"\u3001\")}`);\n if (e.states.length) {\n L.push(`- \u5DF2\u77E5\u9020\u578B: ${e.states.map((state) => {\n const description = clip(state.description, hard ? 30 : 90);\n return description ? `${state.name}\uFF08${description}\uFF09` : state.name;\n }).join(\" / \")}`);\n }\n L.push(`- \u51FA\u73B0: ep ${e.firstEpisode}\u2013${e.lastEpisode}`);\n if (e.status === \"provisional\") L.push(`- \u8EAB\u4EFD\u672A\u786E\u8BA4\uFF1A\u672C\u96C6\u82E5\u51FA\u73B0\u4E66\u9762\u59D3\u540D\u6216\u53F0\u8BCD\u672C\u540D\uFF0C\u7528 canonicalize \u4ECE\u300C${e.name}\u300D\u5347\u7EA7\u89C4\u8303\u540D`);\n return L;\n}\n\nfunction renderAsset(e: RegistryEntity, hard: boolean): string {\n const desc = clip(e.appearance || e.role || \"\", hard ? 30 : 60);\n const states = e.states.map((state) => state.description ? `${state.name}\uFF08${clip(state.description, hard ? 20 : 60)}\uFF09` : state.name).join(\" / \");\n return `- ${e.name} \u00B7${e.importance}${desc ? `\uFF1A${desc}` : \"\"}${states ? `\uFF1B\u72B6\u6001\uFF1A${states}` : \"\"}`;\n}\n\nfunction render(ctx: RunContext, recentN: number, hard: boolean): string {\n const L: string[] = [];\n L.push(`# \u5DF2\u77E5\u8BBE\u5B9A\uFF08\u89E3\u6790\u7B2C ${ctx.lastEpisode + 1} \u96C6\u65F6\u5BF9\u7167\u672C\u8868\uFF09`, \"\");\n L.push(\"\u8BA4\u5F97\u51FA\u7684\u4EBA/\u7269\u6CBF\u7528\u5176**\u89C4\u8303\u540D**\uFF0C\u522B\u81EA\u5DF1\u65B0\u8D77\u540D\uFF1B\u4EBA\u7269\u4F18\u5148\u6BD4\u5BF9\u8BC6\u522B\u951A\u70B9\u4E0E\u7ED3\u6784\u5316\u8EAB\u4EFD\u753B\u50CF\uFF0C\u670D\u88C5\u53EA\u4F5C\u5F31\u8F85\u52A9\u3002\", \"\");\n\n const actors = ctx.registry.filter((e) => e.kind === \"actor\");\n const locations = ctx.registry.filter((e) => e.kind === \"location\");\n const props = ctx.registry.filter((e) => e.kind === \"prop\");\n\n if (actors.length) {\n L.push(\"## \u4EBA\u7269\", \"\");\n for (const e of actors) L.push(...renderActor(e, hard), \"\");\n }\n if (locations.length || props.length) {\n L.push(\"## \u573A\u666F / \u9053\u5177\", \"\");\n for (const e of locations) L.push(renderAsset(e, hard));\n for (const e of props) L.push(renderAsset(e, hard));\n L.push(\"\");\n }\n\n const recentDigests = ctx.digests.filter((digest) => digest.episode > ctx.lastEpisode - recentN);\n if (recentDigests.length) {\n L.push(\"## \u5267\u60C5\u8FDB\u5C55\", \"\");\n for (const d of [...recentDigests].sort((a, b) => a.episode - b.episode)) {\n L.push(d.outcome === \"skipped\"\n ? `\u7B2C${d.episode}\u96C6\u5DF2\u4EBA\u5DE5\u8DF3\u8FC7\uFF0C\u5267\u60C5\u672A\u77E5\u3002`\n : `\u7B2C${d.episode}\u96C6\uFF1A${hard ? clip(d.synopsis, 40) : d.synopsis}`);\n }\n L.push(\"\");\n }\n\n if (ctx.openThreads.length) {\n L.push(\"## \u672A\u95ED\u5408\u7EBF\u7D22\uFF08\u82E5\u672C\u96C6\u4EA4\u4EE3\u4E86\uFF0C\u7528 open_threads.closed \u5F15\u7528\u5176 [id] \u5173\u95ED\uFF09\", \"\");\n for (const t of ctx.openThreads) L.push(`- [${t.id}] ${t.text}`);\n L.push(\"\");\n }\n\n return L.join(\"\\n\");\n}\n\n// Serialize the context for the next episode's prompt. Registry + open threads\n// are load-bearing identity anchors and are NEVER compacted. Plot history is a\n// rolling window: older resolved events would otherwise grow without bound and\n// compete with the current episode's audio/visual evidence.\nexport function renderContext(ctx: RunContext): string {\n for (let n = RECENT_N; n >= 1; n--) {\n const out = render(ctx, n, false);\n if (out.length <= CHAR_BUDGET) return out;\n }\n return render(ctx, 1, true); // n==1 still over budget \u2192 hard-trim digests/appearance\n}\n\n// ===== historical surface name \u2192 current canonical name (finalize) =====\n\nexport function buildAliasMap(registry: RegistryEntity[]): Map<string, string> {\n const aliases = new Map<string, string>();\n for (const entity of registry) {\n for (const surface of [entity.identitySeed, ...entity.aliases]) {\n if (norm(surface) !== norm(entity.name)) aliases.set(surface, entity.name);\n }\n }\n return aliases;\n}\n\n// ===== registry metadata stamping =====\n\ntype LooseScript = { actors?: Asset[]; locations?: Asset[]; props?: Asset[] };\ntype AssetState = { state_name: string; description: string };\ntype Asset = {\n actor_name?: string;\n location_name?: string;\n prop_name?: string;\n aliases?: string[];\n importance?: string;\n description?: string;\n states?: AssetState[];\n};\n\nfunction actorAssetDescription(entity: RegistryEntity): string {\n const profile = entity.identityProfile;\n const parts: string[] = [];\n if (profile) {\n const ageGender = [profile.apparent_gender, profile.apparent_age].filter(Boolean).join(\"\uFF0C\");\n if (ageGender) parts.push(`\u5916\u89C2\u5E74\u9F84\u4E0E\u6027\u522B\uFF1A${ageGender}`);\n if (profile.face_shape) parts.push(`\u8138\u578B\u4E0B\u988C\uFF1A${profile.face_shape}`);\n if (profile.brows_eyes) parts.push(`\u7709\u773C\uFF1A${profile.brows_eyes}`);\n if (profile.nose) parts.push(`\u9F3B\u90E8\uFF1A${profile.nose}`);\n if (profile.mouth) parts.push(`\u5507\u5F62\u53E3\u5468\uFF1A${profile.mouth}`);\n if (profile.skin_features) parts.push(`\u80A4\u8272\u9762\u90E8\uFF1A${profile.skin_features}`);\n if (profile.hair) parts.push(`\u5934\u53D1\uFF1A${profile.hair}`);\n if (profile.build) parts.push(`\u9AA8\u67B6\u4F53\u578B\uFF1A${profile.build}`);\n if (profile.persistent_marks.length) parts.push(`\u56FA\u5B9A\u6807\u8BB0\uFF1A${profile.persistent_marks.join(\"\u3001\")}`);\n if (profile.voice) parts.push(`\u58F0\u7EBF\uFF1A${profile.voice}`);\n }\n if (entity.recognitionAnchors.length) parts.push(`\u8BC6\u522B\u951A\u70B9\uFF1A${entity.recognitionAnchors.join(\"\uFF1B\")}`);\n if (entity.role) parts.push(`\u89D2\u8272\u8BED\u5883\uFF1A${entity.role}`);\n return parts.map((part) => part.replace(/[\u3002\uFF1B]+$/, \"\")).join(\"\uFF1B\");\n}\n\n// The video path bypasses runGovern (which used to inject asset metadata), so\n// stamp descriptions, state descriptions, importance, and aliases deterministically\n// from the registry before governDeterministic.\n// Importance: unmatched assets default to \"featured\" (never silently hidden),\n// matching apply-plan. Historical names from identitySeed + aliases are folded\n// onto the canonical asset (renameDocs collapsed them to one name, so\n// assignProvisionalIds saw no aliases).\nexport function stampRegistryMetadata<T extends LooseScript>(script: T, registry: RegistryEntity[]): T {\n const imp = new Map<string, \"featured\" | \"background\">();\n const surfaceFor = new Map<string, Set<string>>(); // canonical norm name \u2192 surface aliases\n const addSurface = (canon: string, alias: string): void => {\n const k = norm(canon);\n const a = alias.trim();\n if (!a || norm(a) === k) return;\n if (!surfaceFor.has(k)) surfaceFor.set(k, new Set());\n surfaceFor.get(k)!.add(a);\n };\n for (const e of registry) {\n imp.set(norm(e.name), e.importance);\n for (const a of e.aliases) imp.set(norm(a), e.importance);\n imp.set(norm(e.identitySeed), e.importance);\n for (const alias of new Set([e.identitySeed, ...e.aliases])) addSurface(e.name, alias);\n }\n const stamp = (list: Asset[] | undefined, nameKey: keyof Asset): void => {\n for (const a of list ?? []) {\n const canonName = String(a[nameKey] ?? \"\");\n const names = [canonName, ...(a.aliases ?? [])];\n let entity: RegistryEntity | undefined;\n for (const nm of names) {\n entity = registry.find((candidate) =>\n norm(candidate.name) === norm(nm)\n || norm(candidate.identitySeed) === norm(nm)\n || candidate.aliases.some((alias) => norm(alias) === norm(nm)));\n if (entity) break;\n }\n a.importance = entity?.importance ?? imp.get(norm(canonName)) ?? \"featured\";\n const surf = surfaceFor.get(norm(canonName));\n if (surf?.size) a.aliases = [...new Set([...(a.aliases ?? []), ...surf])];\n if (!entity) continue;\n const description = entity.kind === \"actor\"\n ? actorAssetDescription(entity)\n : [entity.appearance, entity.role]\n .map((part) => (part?.trim() ?? \"\").replace(/[\u3002\uFF1B]+$/, \"\"))\n .filter(Boolean)\n .join(\"\uFF1B\");\n if (description) a.description = `${description}\u3002`;\n for (const state of a.states ?? []) {\n const registryState = entity.states.find((candidate) => norm(candidate.name) === norm(state.state_name));\n if (registryState?.description) state.description = registryState.description;\n else if (state.state_name === \"default\" && entity.kind !== \"actor\" && entity.appearance) state.description = entity.appearance;\n }\n }\n };\n stamp(script.actors, \"actor_name\");\n stamp(script.locations, \"location_name\");\n stamp(script.props, \"prop_name\");\n return script;\n}\n\n// ===== serial output \u2192 per-episode working doc =====\n\n// Map the serial parse output onto the established VideoEpisodeDoc shape. Only\n// scenes + synopsis are populated (docsToNameScript consumes just those); the\n// roster arrays stay empty since identity now lives in the running context.\nexport function deltaToDoc(out: SerialOutput, episode: number): VideoEpisodeDoc {\n const scenes: VideoScene[] = out.scenes.map((s, i) => {\n const env: { space?: string; time?: string } = {};\n if (s.environment?.space) env.space = s.environment.space;\n if (s.environment?.time) env.time = s.environment.time;\n const anchors: VideoAnchor[] = (s.anchors ?? []).map((a) => ({\n kind: a.kind,\n ...(a.speaker ? { speaker: a.speaker } : {}),\n ...(a.parenthetical ? { parenthetical: a.parenthetical } : {}),\n ...(a.ts ? { ts: a.ts } : {}),\n content: a.content ?? \"\",\n }));\n return {\n index: i + 1,\n environment: env,\n ...(s.timeRange ? { timeRange: s.timeRange } : {}),\n ...(s.location ? { location: s.location } : {}),\n characters: (s.characters ?? []).filter((c) => c.name).map((c) => ({ name: c.name, states: [...c.states] })),\n props: (s.props ?? []).filter(Boolean),\n anchors,\n };\n });\n return {\n episode,\n synopsis: (out.synopsis ?? \"\").trim(),\n scenes,\n actors: [],\n locations: [],\n props: [],\n speakers: [],\n actorStates: [],\n locationStates: [],\n propStates: [],\n };\n}\n", "import type { VideoEpisodeDoc } from \"./video-records.js\";\nimport { buildAliasMap, type RunContext } from \"./video-context.js\";\nimport type { VideoSourceEpisodeIdentity } from \"./video-source-evolution.js\";\nimport type { ActionV4, ActorV4, ScriptV4 } from \"../script/v4/types.js\";\n\n/** `model` remains readable for version-1 compatibility; new plans never emit it. */\nexport type VideoStateEvidenceSelection = \"model\" | \"target_anchor\" | \"scene_fallback\";\nexport type VideoStateEvidenceFrameStatus = \"pending\" | \"ready\" | \"unavailable\";\n\nexport interface VideoStateEvidenceSample {\n evidence_id: string;\n episode: number;\n episode_id: string;\n scene_id: string;\n timestamp: string;\n offset_ms: -1000 | 0 | 1000;\n selection: VideoStateEvidenceSelection;\n source_sha256: string;\n frame_path: string;\n frame_status: VideoStateEvidenceFrameStatus;\n error?: string;\n}\n\nexport interface VideoActorStateEvidence {\n evidence_id: string;\n asset_kind: \"actor\";\n actor_id: string;\n actor_name: string;\n state_id: string;\n state_name: string;\n samples: VideoStateEvidenceSample[];\n}\n\nexport interface VideoActorIdentityEvidence {\n evidence_id: string;\n asset_kind: \"actor\";\n actor_id: string;\n actor_name: string;\n samples: VideoStateEvidenceSample[];\n}\n\nexport interface VideoStateEvidenceManifest {\n version: 2;\n generated_at: string;\n source_sha256: string;\n items: VideoActorStateEvidence[];\n identities?: VideoActorIdentityEvidence[];\n}\n\nexport interface PlannedVideoStateEvidenceSample extends VideoStateEvidenceSample {\n source_path: string;\n}\n\nexport interface PlannedVideoActorStateEvidence extends Omit<VideoActorStateEvidence, \"samples\"> {\n samples: PlannedVideoStateEvidenceSample[];\n}\n\nexport interface PlannedVideoActorIdentityEvidence extends Omit<VideoActorIdentityEvidence, \"samples\"> {\n samples: PlannedVideoStateEvidenceSample[];\n}\n\nexport interface VideoStateEvidencePlan {\n version: 2;\n source_sha256: string;\n items: PlannedVideoActorStateEvidence[];\n identities: PlannedVideoActorIdentityEvidence[];\n}\n\ninterface Candidate {\n actorId: string;\n episode: number;\n episodeId: string;\n sceneId: string;\n timestamp: string;\n milliseconds: number;\n durationMs?: number;\n stateScore: number;\n identityScore: number;\n selection: Exclude<VideoStateEvidenceSelection, \"model\">;\n sourcePath: string;\n sourceSha256: string;\n}\n\ntype TimestampMode = \"clock\" | \"legacy_centiseconds\";\n\nconst IDENTITY_MIN_EVIDENCE_SCORE = 60;\nconst IDENTITY_BOARD_SIZE = 6;\nconst FRAME_OFFSETS_MS = [-1_000, 0, 1_000] as const;\nconst WARDROBE_CUE = /(?:\u8EAB\u7A7F|\u7A7F\u7740|\u670D\u88C5|\u9020\u578B|\u8863|\u88D9|\u888D|\u886B|\u5939\u514B|\u5236\u670D|\u897F\u88C5|\u76D4\u7532|\u88C5\u7532|\u9632\u5F39\u670D|\u5957\u88C5|\u88E4|\u9774)/u;\nconst FRAMING_CUE = /(?:\u5168\u8EAB|\u534A\u8EAB|\u4E0A\u534A\u8EAB|\u56DB\u5206\u4E4B\u4E09\u8EAB|\u8EAF\u5E72|\u80F8\u524D|\u8170\u90E8)/u;\nconst BODY_CUE = /(?:\u7AD9(?:\u5728|\u7ACB)|\u5750(?:\u5728|\u4E0B|\u8D77)|\u8DEA(?:\u5728|\u4E0B|\u5012)?|\u8E72(?:\u5728|\u4E0B)?|\u8D70(?:\u5728|\u51FA|\u5411)|\u884C\u8D70|\u8FC8\u6B65|\u5954\u8DD1|\u8DF3\u8D77|\u8DC3\u8D77|\u8F6C\u8EAB|\u62AC\u5934|\u8F6C\u5934)/u;\nconst FACE_CUE = /(?:\u7279\u5199|\u8FD1\u666F|\u8138|\u9762\u5BB9|\u4E94\u5B98|\u6B63\u8138|\u4FA7\u8138|\u4FA7\u524D\u8138|\u53CC\u773C|\u773C\u7736|\u7709\u5934|\u5634\u89D2)/u;\nconst BAD_VISUAL_CUE = /(?:\u80CC\u5BF9|\u80CC\u5F71|\u8FDC\u5904|\u6781\u8FDC|\u6A21\u7CCA|\u8FD0\u52A8\u6A21\u7CCA|\u8138\u88AB\u906E|\u9762\u90E8\u906E\u6321|\u53EA\u9732\u51FA|\u7EAF\u9053\u5177|\u7A7A\u955C)/u;\nconst DETAIL_ONLY_CUE = /(?:\u53CC\u811A|\u811A\u90E8|\u819D\u76D6|\u4F24\u53E3|\u624B\u90E8\u7279\u5199)/u;\nconst OFFSCREEN_SPEECH_CUE = /(?:\u753B\u5916\u97F3|\u65C1\u767D|\u672A\u5165\u955C|\u955C\u5916|\u7535\u8BDD\u97F3|\u5E7F\u64AD|\\bO\\.?S\\.?\\b)/iu;\n\nfunction norm(value: string): string {\n return value.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n}\n\nfunction clockTimestampMilliseconds(value: string): number | null {\n const match = value.trim().match(/^(?:(\\d{1,2}):)?(\\d{1,2}):(\\d{2})(?:\\.(\\d{1,3}))?$/);\n if (!match) return null;\n const hours = Number(match[1] ?? 0);\n const minutes = Number(match[2]);\n const seconds = Number(match[3]);\n if (minutes >= 60 && match[1] !== undefined) return null;\n if (seconds >= 60) return null;\n const fraction = String(match[4] ?? \"\").padEnd(3, \"0\");\n return ((hours * 60 + minutes) * 60 + seconds) * 1000 + Number(fraction || 0);\n}\n\n/**\n * Some imported projects used `seconds:centiseconds` (for example `29:00`\n * means 29 seconds) before Script v4 standardized on clock timestamps. Keep\n * compatibility at the episode level so ordinary `00:33` remains 33 seconds.\n */\nfunction legacyCentisecondTimestampMilliseconds(value: string): number | null {\n const match = value.trim().match(/^(\\d+):(\\d{2})$/);\n if (!match) return null;\n return Number(match[1]) * 1_000 + Number(match[2]) * 10;\n}\n\nfunction timestampMilliseconds(value: string, mode: TimestampMode = \"clock\"): number | null {\n return mode === \"legacy_centiseconds\"\n ? legacyCentisecondTimestampMilliseconds(value)\n : clockTimestampMilliseconds(value);\n}\n\nfunction inSourceRange(milliseconds: number | null, durationMs?: number): milliseconds is number {\n if (milliseconds === null) return false;\n return durationMs === undefined || milliseconds <= durationMs;\n}\n\nfunction episodeTimestampMode(\n episode: ScriptV4[\"episodes\"][number],\n durationMs?: number,\n): TimestampMode {\n if (durationMs === undefined) return \"clock\";\n const timestamps = episode.scenes.flatMap((scene) => scene.actions.map(actionTimestamp)).filter(Boolean);\n const clockValid = timestamps.filter((value) => inSourceRange(clockTimestampMilliseconds(value), durationMs)).length;\n const legacyValid = timestamps.filter((value) => inSourceRange(legacyCentisecondTimestampMilliseconds(value), durationMs)).length;\n // Ties intentionally remain standard clock timestamps. A legacy episode is\n // selected only when the source duration proves it explains more Actions.\n return legacyValid > clockValid ? \"legacy_centiseconds\" : \"clock\";\n}\n\nfunction timestampFromMilliseconds(milliseconds: number): string {\n const minutes = Math.floor(milliseconds / 60_000);\n const seconds = Math.floor((milliseconds % 60_000) / 1_000);\n const fraction = milliseconds % 1_000;\n return `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}.${String(fraction).padStart(3, \"0\")}`;\n}\n\nfunction actionTimestamp(action: ActionV4): string {\n const value = action.extend?.timestamp;\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction actorSurfaces(actor: ActorV4, contextAliases: Map<string, string>): string[] {\n const names = new Set([actor.actor_name, ...(actor.aliases ?? [])].map(norm).filter(Boolean));\n for (const [alias, canonical] of contextAliases) {\n if (norm(canonical) === norm(actor.actor_name)) names.add(norm(alias));\n }\n return [...names].sort((left, right) => right.length - left.length);\n}\n\nfunction mentionIndex(content: string, surfaces: readonly string[]): number {\n const indices = surfaces.map((surface) => content.indexOf(surface)).filter((index) => index >= 0);\n return indices.length > 0 ? Math.min(...indices) : -1;\n}\n\nfunction visibleNames(content: string, actors: readonly ActorV4[], surfacesByActor: Map<string, string[]>): number {\n return actors.filter((actor) => mentionIndex(content, surfacesByActor.get(actor.actor_id) ?? []) >= 0).length;\n}\n\nfunction scoreActionCandidate({\n action,\n actor,\n actorCount,\n allActors,\n surfaces,\n surfacesByActor,\n stateName,\n}: {\n action: ActionV4;\n actor: ActorV4;\n actorCount: number;\n allActors: readonly ActorV4[];\n surfaces: readonly string[];\n surfacesByActor: Map<string, string[]>;\n stateName: string;\n}): { stateScore: number; identityScore: number; selection: Candidate[\"selection\"] } | null {\n const narrative = action.type === \"action\" || action.type === \"transition\";\n const content = norm(narrative\n ? action.content\n : \"parenthetical\" in action ? action.parenthetical ?? \"\" : \"\");\n const directIndex = mentionIndex(content, surfaces);\n const directSubject = directIndex >= 0 && directIndex <= 12;\n const directMention = directIndex >= 0;\n\n // For a visual contact sheet, a normal spoken line in a scene where the final\n // Script already binds this actor + state is the best cheap proxy for a clean\n // character shot. It is not identity proof (reverse shots still exist), so\n // the client keeps the neighbouring frames and human annotation path. Explicit\n // off-screen/voice-over speech is never used as a visual anchor.\n const actorSpeaker = action.type === \"dialogue\" && \"speaker\" in action && \"actor_id\" in action.speaker\n && action.speaker.actor_id === actor.actor_id;\n const visibleSpeaker = actorSpeaker && !OFFSCREEN_SPEECH_CUE.test(content);\n const singleActorVisibleFallback = actorCount === 1 && (\n (narrative && content.length > 0)\n || (visibleSpeaker && content.length > 0 && (BODY_CUE.test(content) || FACE_CUE.test(content)))\n );\n if (!directMention && !visibleSpeaker && !singleActorVisibleFallback) return null;\n\n const selection: Candidate[\"selection\"] = directSubject || visibleSpeaker ? \"target_anchor\" : \"scene_fallback\";\n // Deliberately keep ordinary on-screen dialogue above even a very descriptive\n // wardrobe Action: the scene-level state reference already establishes which\n // outfit is active, while the speaking beat is more likely to show the person.\n let stateScore = visibleSpeaker ? 250 : directSubject ? 65 : directMention ? 50 : 45;\n let identityScore = visibleSpeaker ? 250 : directSubject ? 65 : directMention ? 50 : 45;\n if (actorCount === 1) {\n stateScore += 20;\n identityScore += 20;\n }\n const normalizedState = norm(stateName);\n if (normalizedState && normalizedState !== \"default\" && normalizedState !== \"\u9ED8\u8BA4\" && content.includes(normalizedState)) {\n stateScore += 35;\n }\n if (WARDROBE_CUE.test(content)) stateScore += 30;\n if (FRAMING_CUE.test(content)) {\n stateScore += 25;\n identityScore += 15;\n } else if (BODY_CUE.test(content)) {\n stateScore += 15;\n identityScore += 5;\n }\n if (FACE_CUE.test(content)) {\n identityScore += 30;\n if (!FRAMING_CUE.test(content)) stateScore -= 20;\n }\n if (BAD_VISUAL_CUE.test(content)) {\n stateScore -= 70;\n identityScore -= 70;\n }\n if (DETAIL_ONLY_CUE.test(content)) stateScore -= 40;\n if (visibleNames(content, allActors, surfacesByActor) >= 2) {\n stateScore -= 15;\n identityScore -= 15;\n }\n return { stateScore, identityScore, selection };\n}\n\nfunction scoreStateCoverageFallback(\n action: ActionV4,\n allActors: readonly ActorV4[],\n surfacesByActor: Map<string, string[]>,\n): { stateScore: number; identityScore: number; selection: Candidate[\"selection\"] } | null {\n const narrative = action.type === \"action\" || action.type === \"transition\";\n const parenthetical = \"parenthetical\" in action ? norm(action.parenthetical ?? \"\") : \"\";\n if (!narrative && OFFSCREEN_SPEECH_CUE.test(parenthetical)) return null;\n const content = norm(narrative ? action.content : parenthetical);\n\n // A scene-level timestamp cannot prove identity, but it is still a useful\n // last-resort state anchor when the final scene reference binds one costume to\n // the actor. Keep it below every actor-specific candidate so quality scoring\n // only chooses the best frame; it must not make a referenced costume disappear.\n let stateScore = narrative ? 0 : -40;\n stateScore -= visibleNames(content, allActors, surfacesByActor) * 20;\n if (WARDROBE_CUE.test(content)) stateScore += 10;\n if (FRAMING_CUE.test(content)) stateScore += 10;\n else if (BODY_CUE.test(content)) stateScore += 5;\n if (BAD_VISUAL_CUE.test(content)) stateScore -= 20;\n if (DETAIL_ONLY_CUE.test(content)) stateScore -= 10;\n return { stateScore, identityScore: Number.NEGATIVE_INFINITY, selection: \"scene_fallback\" };\n}\n\nfunction effectiveScore(\n candidate: Candidate,\n scoreKey: \"stateScore\" | \"identityScore\",\n owners: Map<string, Set<string>>,\n): number {\n const shared = (owners.get(`${candidate.episode}:${candidate.milliseconds}`)?.size ?? 0) > 1;\n return candidate[scoreKey] - (shared ? 35 : 0);\n}\n\nfunction bestCandidates(\n candidates: readonly Candidate[],\n scoreKey: \"stateScore\" | \"identityScore\",\n owners: Map<string, Set<string>>,\n limit: number,\n minimumScore: number | null,\n): Candidate[] {\n const deduplicated = new Map<string, Candidate>();\n for (const candidate of candidates) {\n const key = `${candidate.episode}:${candidate.milliseconds}`;\n const existing = deduplicated.get(key);\n if (!existing || effectiveScore(candidate, scoreKey, owners) > effectiveScore(existing, scoreKey, owners)) {\n deduplicated.set(key, candidate);\n }\n }\n const ranked = [...deduplicated.values()]\n .sort((left, right) => effectiveScore(right, scoreKey, owners) - effectiveScore(left, scoreKey, owners)\n || left.episode - right.episode\n || left.milliseconds - right.milliseconds)\n .filter((candidate) => minimumScore === null || effectiveScore(candidate, scoreKey, owners) >= minimumScore);\n\n // A useful contact sheet needs visual variety, not six near-identical frames\n // from one shot. Prefer different scenes; only reuse a scene when its anchors\n // are at least three seconds apart and the board still has empty cells.\n const selected: Candidate[] = [];\n for (const candidate of ranked) {\n const tooClose = selected.some((entry) => entry.episode === candidate.episode\n && entry.sceneId === candidate.sceneId\n && Math.abs(entry.milliseconds - candidate.milliseconds) < 3_000);\n if (tooClose) continue;\n selected.push(candidate);\n if (selected.length >= limit) break;\n }\n return selected;\n}\n\nfunction bestCandidate(\n candidates: readonly Candidate[],\n scoreKey: \"stateScore\" | \"identityScore\",\n owners: Map<string, Set<string>>,\n): Candidate | null {\n // State evidence is coverage-first: every actor-specific or neutral visual\n // candidate remains eligible, while scores only determine which one wins.\n return bestCandidates(candidates, scoreKey, owners, 1, null)[0] ?? null;\n}\n\nfunction timestampFilePart(timestamp: string): string {\n return timestamp.replace(/[^0-9]+/g, \"-\").replace(/^-|-$/g, \"\") || \"unknown\";\n}\n\n/**\n * Build evidence only after final Script v4 identities are stable. Gemini does\n * not return any evidence fields: candidates come from final Action timestamps,\n * visible-action text and single-person scene ranges, then ffmpeg materializes\n * the selected frames locally.\n */\nexport function buildVideoStateEvidencePlan(\n docs: readonly VideoEpisodeDoc[],\n script: ScriptV4,\n context: RunContext,\n sources: readonly VideoSourceEpisodeIdentity[],\n sourceSha256: string,\n): VideoStateEvidencePlan {\n const sourceByEpisode = new Map(sources.map((source) => [source.episode, source]));\n const contextAliases = buildAliasMap(context.registry);\n const actorById = new Map<string, ActorV4>(script.actors.map((actor) => [actor.actor_id, actor]));\n const surfacesByActor = new Map(script.actors.map((actor) => [actor.actor_id, actorSurfaces(actor, contextAliases)]));\n const appearancesByActor = new Map<string, number>();\n const identityCandidates = new Map<string, Candidate[]>();\n const stateCandidates = new Map<string, Candidate[]>();\n const owners = new Map<string, Set<string>>();\n\n for (let episodeIndex = 0; episodeIndex < script.episodes.length; episodeIndex += 1) {\n const episode = script.episodes[episodeIndex]!;\n const episodeNo = episodeIndex + 1;\n const source = sourceByEpisode.get(episodeNo);\n if (!source) continue;\n const timestampMode = episodeTimestampMode(episode, source.duration_ms);\n for (let sceneIndex = 0; sceneIndex < episode.scenes.length; sceneIndex += 1) {\n const scene = episode.scenes[sceneIndex]!;\n const actors = scene.actors.map((ref) => actorById.get(ref.actor_id)).filter((actor): actor is ActorV4 => Boolean(actor));\n for (const ref of scene.actors) {\n appearancesByActor.set(ref.actor_id, (appearancesByActor.get(ref.actor_id) ?? 0) + 1);\n const actor = actorById.get(ref.actor_id);\n if (!actor) continue;\n const surfaces = surfacesByActor.get(actor.actor_id) ?? [actor.actor_name];\n const local: Candidate[] = [];\n const stateId = ref.state_ids.length === 1 ? ref.state_ids[0]! : null;\n const state = stateId ? actor.states.find((candidate) => candidate.state_id === stateId) : null;\n for (const action of scene.actions) {\n const timestamp = actionTimestamp(action);\n const milliseconds = timestampMilliseconds(timestamp, timestampMode);\n if (!inSourceRange(milliseconds, source.duration_ms)) continue;\n const actorSpecific = scoreActionCandidate({\n action,\n actor,\n actorCount: actors.length,\n allActors: actors,\n surfaces,\n surfacesByActor,\n stateName: state?.state_name ?? \"default\",\n });\n const scored = actorSpecific ?? (state\n ? scoreStateCoverageFallback(action, actors, surfacesByActor)\n : null);\n if (!scored) continue;\n const candidate: Candidate = {\n actorId: actor.actor_id,\n episode: episodeNo,\n episodeId: episode.episode_id,\n sceneId: scene.scene_id,\n timestamp: timestampFromMilliseconds(milliseconds),\n milliseconds,\n durationMs: source.duration_ms,\n stateScore: scored.stateScore,\n identityScore: scored.identityScore,\n selection: scored.selection,\n sourcePath: source.path,\n sourceSha256: source.sha256,\n };\n local.push(candidate);\n if (actorSpecific) {\n const ownerKey = `${episodeNo}:${milliseconds}`;\n const ownerSet = owners.get(ownerKey) ?? new Set<string>();\n ownerSet.add(actor.actor_id);\n owners.set(ownerKey, ownerSet);\n }\n }\n if (local.length > 0) {\n const identity = identityCandidates.get(actor.actor_id) ?? [];\n identity.push(...local);\n identityCandidates.set(actor.actor_id, identity);\n // A scene-level state_ids set is unordered. Only a single state can be\n // attributed to every Action in the scene without inventing chronology.\n if (state) {\n const key = `${actor.actor_id}:${state.state_id}`;\n const values = stateCandidates.get(key) ?? [];\n values.push(...local);\n stateCandidates.set(key, values);\n }\n }\n }\n }\n }\n\n const compareActorPriority = (leftId: string, rightId: string): number => {\n const left = actorById.get(leftId);\n const right = actorById.get(rightId);\n const leftBackground = left?.importance === \"background\" ? 1 : 0;\n const rightBackground = right?.importance === \"background\" ? 1 : 0;\n return leftBackground - rightBackground\n || (appearancesByActor.get(rightId) ?? 0) - (appearancesByActor.get(leftId) ?? 0)\n || (left?.actor_name ?? leftId).localeCompare(right?.actor_name ?? rightId, \"zh-CN\");\n };\n\n const items = [...stateCandidates.entries()].flatMap(([key, values]): PlannedVideoActorStateEvidence[] => {\n const [actorId, stateId] = key.split(\":\");\n const actor = actorId ? actorById.get(actorId) : undefined;\n const state = actor?.states.find((candidate) => candidate.state_id === stateId);\n const anchor = bestCandidate(values, \"stateScore\", owners);\n if (!actor || !state || !anchor) return [];\n const evidenceId = `state:${actor.actor_id}:${state.state_id}`;\n const samples = FRAME_OFFSETS_MS.map((offset) => {\n const lastSeekableMillisecond = anchor.durationMs === undefined\n ? Number.POSITIVE_INFINITY\n : Math.max(0, anchor.durationMs - 50);\n const milliseconds = Math.min(lastSeekableMillisecond, Math.max(0, anchor.milliseconds + offset));\n const timestamp = timestampFromMilliseconds(milliseconds);\n return {\n evidence_id: `${evidenceId}:${anchor.episode}:${timestamp}`,\n episode: anchor.episode,\n episode_id: anchor.episodeId,\n scene_id: anchor.sceneId,\n timestamp,\n offset_ms: offset,\n selection: anchor.selection,\n source_sha256: anchor.sourceSha256,\n source_path: anchor.sourcePath,\n frame_path: `evidence/frames/${actor.actor_id}/${state.state_id}/ep_${String(anchor.episode).padStart(3, \"0\")}_${timestampFilePart(timestamp)}.jpg`,\n frame_status: \"pending\" as const,\n };\n }).filter((sample, index, all) => all.findIndex((candidate) => candidate.timestamp === sample.timestamp) === index);\n return [{\n evidence_id: evidenceId,\n asset_kind: \"actor\",\n actor_id: actor.actor_id,\n actor_name: actor.actor_name,\n state_id: state.state_id,\n state_name: state.state_name,\n samples,\n }];\n }).sort((left, right) => compareActorPriority(left.actor_id, right.actor_id)\n || left.state_name.localeCompare(right.state_name, \"zh-CN\"));\n\n const identities = [...identityCandidates.entries()].flatMap(([actorId, values]): PlannedVideoActorIdentityEvidence[] => {\n const actor = actorById.get(actorId);\n const anchors = bestCandidates(\n values,\n \"identityScore\",\n owners,\n IDENTITY_BOARD_SIZE,\n IDENTITY_MIN_EVIDENCE_SCORE,\n );\n if (!actor || anchors.length === 0) return [];\n const evidenceId = `identity:${actor.actor_id}`;\n return [{\n evidence_id: evidenceId,\n asset_kind: \"actor\",\n actor_id: actor.actor_id,\n actor_name: actor.actor_name,\n // Ranked, cross-scene identity/appearance frames. The client renders these\n // as a compact 3x2 contact sheet; the first sample remains the single-frame\n // fallback for older clients and inline hover cards.\n samples: anchors.map((anchor) => ({\n evidence_id: `${evidenceId}:${anchor.episode}:${anchor.timestamp}`,\n episode: anchor.episode,\n episode_id: anchor.episodeId,\n scene_id: anchor.sceneId,\n timestamp: anchor.timestamp,\n offset_ms: 0,\n selection: anchor.selection,\n source_sha256: anchor.sourceSha256,\n source_path: anchor.sourcePath,\n frame_path: `evidence/frames/${actor.actor_id}/identity/ep_${String(anchor.episode).padStart(3, \"0\")}_${timestampFilePart(anchor.timestamp)}.jpg`,\n frame_status: \"pending\" as const,\n })),\n }];\n }).sort((left, right) => compareActorPriority(left.actor_id, right.actor_id));\n\n return { version: 2, source_sha256: sourceSha256, items, identities };\n}\n\nexport function parseVideoEvidenceTimestamp(value: string): number | null {\n return timestampMilliseconds(value);\n}\n", "// Video episode discovery (\u00A710.1). Turns a resolved video source into a numbered\n// episode list. A single file is episode 1. In a directory: if every file\n// carries an episode number, reuse them (and reject duplicates); if none do,\n// natural-sort and assign ep 1..N; mixing numbered and unnumbered files fails\n// up front rather than guessing an order.\n\nimport * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT } from \"../../common.js\";\nimport { VIDEO_MIME, type ResolvedSource } from \"./source-resolver.js\";\n\nexport interface VideoEpisode {\n episode: number;\n path: string;\n ext: string;\n mime: string;\n}\n\nfunction ext(p: string): string {\n return path.extname(p).toLowerCase();\n}\n\nfunction mimeFor(p: string): string {\n return VIDEO_MIME[ext(p)] ?? \"application/octet-stream\";\n}\n\n// Prefer an explicit episode marker before falling back to the first run of\n// digits. Real series names commonly carry unrelated numbers (for example\n// `749\u5C40-\u7B2C35\u96C6.mp4`); treating the title number as the episode collapses an\n// entire directory into one duplicate episode.\nfunction episodeNumber(file: string): number | null {\n // Strip the extension first \u2014 `.mp4`/`.mpeg` carry digits that are not episode\n // numbers.\n const stem = path.basename(file, path.extname(file));\n const explicit = stem.match(/\u7B2C\\s*0*(\\d+)\\s*[\u96C6\u8BDD\u56DE]/u)\n ?? stem.match(/(?:^|[._\\-\\s])(?:ep(?:isode)?|e)\\s*[._\\-\\s]*0*(\\d+)(?=$|[._\\-\\s])/iu);\n if (explicit) return Number(explicit[1]);\n const m = stem.match(/\\d+/);\n return m ? Number(m[0]) : null;\n}\n\nfunction discoveryError(message: string, received: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_VIDEO_DISCOVERY\",\n hint: \"Name every episode file with a number, or none of them, and rerun `scriptctl ingest`.\",\n data: { actual: received },\n });\n}\n\nfunction episode(file: string, n: number): VideoEpisode {\n return { episode: n, path: file, ext: ext(file), mime: mimeFor(file) };\n}\n\nexport function discoverEpisodes(source: ResolvedSource): VideoEpisode[] {\n if (source.kind === \"text\") {\n throw new CliError(\"discoverEpisodes received a text source.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_WRONG_PIPELINE\",\n });\n }\n if (source.kind === \"video-file\") return [episode(source.path, 1)];\n\n const files = source.files; // already one-level, allowlisted, sorted (source-resolver)\n const numbers = files.map(episodeNumber);\n const numbered = numbers.filter((n): n is number => n !== null);\n\n if (numbered.length === 0) {\n // None numbered: keep the resolver's natural sort, assign 1..N.\n return files.map((file, i) => episode(file, i + 1));\n }\n if (numbered.length !== files.length) {\n const bad = files.filter((_, i) => numbers[i] === null).map((f) => path.basename(f));\n throw discoveryError(\"Some episode files carry a number and some do not.\", [`unnumbered: ${bad.join(\", \")}`]);\n }\n const seen = new Set<number>();\n for (const n of numbered) {\n if (seen.has(n)) throw discoveryError(\"Two episode files resolve to the same number.\", [`duplicate episode: ${n}`]);\n seen.add(n);\n }\n return files.map((file, i) => episode(file, numbers[i]!)).sort((a, b) => a.episode - b.episode);\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { sha256File, sha256Text } from \"../../common.js\";\nimport type { VideoSourceEpisodeIdentity } from \"../../domain/ingest/video-source-evolution.js\";\nimport type { VideoEpisode } from \"./video-discovery.js\";\n\nexport function snapshotVideoSource(\n episodes: VideoEpisode[],\n previous: readonly VideoSourceEpisodeIdentity[] = [],\n previousVerifiedAt?: string,\n): VideoSourceEpisodeIdentity[] {\n const priorByEpisode = new Map(previous.map((item) => [item.episode, item]));\n const verifiedAtMs = previousVerifiedAt ? Date.parse(previousVerifiedAt) : Number.NaN;\n return episodes.map((episode) => {\n const absolutePath = path.resolve(episode.path);\n const stat = fs.statSync(absolutePath);\n const sizeBytes = stat.size;\n const mtimeMs = Math.trunc(stat.mtimeMs);\n const prior = priorByEpisode.get(episode.episode);\n const unchangedByMetadata = prior\n && prior.size_bytes === sizeBytes\n && prior.mtime_ms === mtimeMs;\n const unchangedSinceLegacyVerification = prior\n && prior.size_bytes === undefined\n && prior.mtime_ms === undefined\n && prior.path === absolutePath\n && Number.isFinite(verifiedAtMs)\n && stat.mtimeMs <= verifiedAtMs;\n const sha256 = prior\n && prior.ext === episode.ext\n && prior.mime === episode.mime\n && (unchangedByMetadata || unchangedSinceLegacyVerification)\n ? prior.sha256\n : sha256File(absolutePath);\n return {\n episode: episode.episode,\n path: absolutePath,\n ext: episode.ext,\n mime: episode.mime,\n sha256,\n size_bytes: sizeBytes,\n mtime_ms: mtimeMs,\n };\n });\n}\n\nexport function videoSourceFingerprint(episodes: VideoSourceEpisodeIdentity[]): string {\n return sha256Text(JSON.stringify(episodes.map((episode) => ({\n episode: episode.episode,\n ext: episode.ext,\n mime: episode.mime,\n sha256: episode.sha256,\n }))));\n}\n", "// Pre-upload video transcode (\u00A710.1). Source short-drama episodes ship at high\n// bitrates, so we re-encode to 720p (long edge \u22641280, never upscaled), CRF 27,\n// and 96k AAC before upload. Frame rate is inherited from the source so callers\n// can choose any provider-supported sampling rate without losing frames during\n// compression. Best-effort: if ffmpeg is missing or the encode fails, the caller\n// uploads the original.\n\nimport { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\n// Episodes already at/below this size upload as-is \u2014 transcoding buys little and\n// costs CPU/time. Matches the ~20 MB per-episode target.\nconst SKIP_BELOW_BYTES = 20 * 1024 * 1024;\n\n// Orientation-agnostic: clamp the LONG edge to 1280 (landscape \u2192 720p tall,\n// portrait \u2192 1280 tall), keep aspect, and never upscale a smaller source. `-2`\n// keeps the other edge even (libx264 requires it).\nconst SCALE_FILTER =\n \"scale='if(gt(a,1),min(1280,iw),-2)':'if(gt(a,1),-2,min(1280,ih))'\";\n\nexport interface TranscodeResult {\n path: string; // path to upload (transcoded output, or the original on skip/fallback)\n mime: string; // mime to upload with\n transcoded: boolean; // true when we produced a re-encoded file\n note?: string; // human-readable reason when we did NOT transcode\n}\n\nfunction ffmpegArgs(src: string, out: string): string[] {\n return [\n \"-y\", \"-loglevel\", \"error\",\n \"-i\", src,\n \"-vf\", SCALE_FILTER,\n \"-c:v\", \"libx264\", \"-preset\", \"medium\", \"-crf\", \"27\", \"-pix_fmt\", \"yuv420p\",\n \"-c:a\", \"aac\", \"-b:a\", \"96k\",\n \"-movflags\", \"+faststart\",\n \"-f\", \"mp4\",\n out,\n ];\n}\n\nfunction runFfmpeg(src: string, out: string, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) { reject(new Error(\"aborted\")); return; }\n const child = spawn(\"ffmpeg\", ffmpegArgs(src, out), { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n child.stderr?.on(\"data\", (d) => { stderr += String(d); });\n const onAbort = (): void => { child.kill(\"SIGKILL\"); };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"error\", (err) => { signal?.removeEventListener(\"abort\", onAbort); reject(err); });\n child.on(\"close\", (code) => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (code === 0) resolve();\n else reject(new Error(`ffmpeg exited ${code}: ${stderr.trim().slice(0, 300)}`));\n });\n });\n}\n\n// Transcode `src` to `out` for upload. Never throws for encode/tooling problems \u2014\n// falls back to the original file so a missing ffmpeg or a stubborn clip cannot\n// fail the ingest run. `out` is only written when transcoding actually happens.\nexport async function transcodeForUpload(\n src: string,\n out: string,\n mime: string,\n signal?: AbortSignal,\n): Promise<TranscodeResult> {\n // Reuse an already-transcoded output (resume path) rather than re-encoding.\n // Safe because `out` is published atomically (rename below) \u2014 it exists ONLY\n // when fully written, so a resume can never reuse a truncated/corrupt encode.\n if (fs.existsSync(out) && (fs.statSync(out).size ?? 0) > 0) {\n return { path: out, mime: \"video/mp4\", transcoded: true };\n }\n let size = 0;\n try { size = fs.statSync(src).size; } catch { /* stat failure \u2192 try transcode anyway */ }\n if (size > 0 && size <= SKIP_BELOW_BYTES) {\n return { path: src, mime, transcoded: false, note: `already ${(size / 1024 / 1024).toFixed(1)}MB (\u226420MB)` };\n }\n // Encode to a `.part` sidecar, then atomically rename onto `out`. A SIGKILL\n // mid-encode (the ingest process gets reaped constantly) would otherwise leave a\n // half-written, moov-less file at `out` that the reuse check above happily feeds\n // to Gemini forever \u2192 the episode is stuck on \"file processing failed\" and can\n // never self-heal. With the rename, a killed run leaves only `.part`, which the\n // next attempt overwrites.\n const tmp = `${out}.part`;\n try {\n fs.mkdirSync(path.dirname(out), { recursive: true });\n fs.rmSync(tmp, { force: true }); // drop any leftover from a previously killed encode\n await runFfmpeg(src, tmp, signal);\n if (!fs.existsSync(tmp) || fs.statSync(tmp).size === 0) throw new Error(\"ffmpeg produced no output\");\n fs.renameSync(tmp, out); // atomic publish\n return { path: out, mime: \"video/mp4\", transcoded: true };\n } catch (err) {\n // Best-effort: clean partial outputs (both the sidecar and any stale target)\n // and upload the original.\n try { fs.rmSync(tmp, { force: true }); fs.rmSync(out, { force: true }); } catch { /* ignore */ }\n if (signal?.aborted) throw err instanceof Error ? err : new Error(String(err));\n const reason = err instanceof Error ? err.message : String(err);\n return { path: src, mime, transcoded: false, note: `transcode failed, uploading original (${reason})` };\n }\n}\n", "import { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n parseVideoEvidenceTimestamp,\n type PlannedVideoStateEvidenceSample,\n type VideoStateEvidenceManifest,\n type VideoStateEvidencePlan,\n} from \"../../domain/ingest/video-state-evidence.js\";\nimport type { WorkspaceStore } from \"./workspace-store.js\";\n\nconst FRAME_SCALE = \"scale='if(gt(a,1),min(960,iw),-2)':'if(gt(a,1),-2,min(960,ih))'\";\nconst FRAME_EXTRACTION_CONCURRENCY = 4;\n\nexport interface FrameExtractionResult {\n ok: boolean;\n error?: string;\n}\n\nexport type VideoFrameExtractor = (\n sourcePath: string,\n timestamp: string,\n outputPath: string,\n signal?: AbortSignal,\n) => Promise<FrameExtractionResult>;\n\nexport interface VideoStateEvidenceMaterializeOptions {\n /** Reuse a ready frame already present at the deterministic output path. */\n reuseExistingFrames?: boolean;\n}\n\nfunction ffmpegTimestamp(timestamp: string): string | null {\n const milliseconds = parseVideoEvidenceTimestamp(timestamp);\n return milliseconds === null ? null : (milliseconds / 1000).toFixed(3);\n}\n\nexport const extractVideoEvidenceFrame: VideoFrameExtractor = async (\n sourcePath,\n timestamp,\n outputPath,\n signal,\n) => {\n if (signal?.aborted) throw new Error(\"aborted\");\n const seek = ffmpegTimestamp(timestamp);\n if (seek === null) return { ok: false, error: \"invalid timestamp\" };\n try {\n if (!fs.existsSync(sourcePath) || fs.statSync(sourcePath).size === 0) {\n return { ok: false, error: \"source video is unavailable or empty\" };\n }\n } catch {\n return { ok: false, error: \"source video is unavailable\" };\n }\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n const partial = `${outputPath}.part`;\n fs.rmSync(partial, { force: true });\n return new Promise((resolve, reject) => {\n const child = spawn(\"ffmpeg\", [\n \"-y\", \"-loglevel\", \"error\",\n \"-ss\", seek,\n \"-i\", sourcePath,\n \"-frames:v\", \"1\",\n \"-vf\", FRAME_SCALE,\n \"-q:v\", \"3\",\n \"-f\", \"image2\",\n partial,\n ], { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n child.stderr?.resume();\n const onAbort = (): void => {\n child.kill(\"SIGKILL\");\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n fs.rmSync(partial, { force: true });\n if (signal?.aborted) reject(new Error(\"aborted\"));\n else resolve({ ok: false, error: \"frame extractor unavailable\" });\n });\n child.on(\"close\", (code) => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (signal?.aborted) {\n fs.rmSync(partial, { force: true });\n reject(new Error(\"aborted\"));\n return;\n }\n if (code === 0 && fs.existsSync(partial) && fs.statSync(partial).size > 0) {\n fs.renameSync(partial, outputPath);\n resolve({ ok: true });\n return;\n }\n fs.rmSync(partial, { force: true });\n resolve({ ok: false, error: `frame extraction failed (exit ${code ?? \"unknown\"})` });\n });\n });\n};\n\nfunction publicSample(sample: PlannedVideoStateEvidenceSample): Omit<PlannedVideoStateEvidenceSample, \"source_path\"> {\n const { source_path: _sourcePath, ...rest } = sample;\n return rest;\n}\n\n/** Materialize a plan without making frame-tooling failures fatal to ingest. */\nexport async function materializeVideoStateEvidence(\n store: WorkspaceStore,\n plan: VideoStateEvidencePlan,\n signal?: AbortSignal,\n extractor: VideoFrameExtractor = extractVideoEvidenceFrame,\n options: VideoStateEvidenceMaterializeOptions = {},\n): Promise<VideoStateEvidenceManifest> {\n const reuseExistingFrames = options.reuseExistingFrames !== false;\n const plannedSamples = [\n ...plan.items.flatMap((item) => item.samples),\n ...(plan.identities ?? []).flatMap((identity) => identity.samples),\n ];\n const materialized = new Map<\n PlannedVideoStateEvidenceSample,\n Omit<PlannedVideoStateEvidenceSample, \"source_path\">\n >();\n let cursor = 0;\n const worker = async (): Promise<void> => {\n while (true) {\n const index = cursor;\n cursor += 1;\n if (index >= plannedSamples.length) return;\n if (signal?.aborted) throw new Error(\"aborted\");\n const sample = plannedSamples[index]!;\n const outputPath = store.path(sample.frame_path);\n let result: FrameExtractionResult;\n if (reuseExistingFrames && fs.existsSync(outputPath) && fs.statSync(outputPath).size > 0) {\n result = { ok: true };\n } else {\n // An explicit refresh must not silently keep a frame produced from an\n // older video at the same episode/timestamp path.\n fs.rmSync(outputPath, { force: true });\n result = await extractor(sample.source_path, sample.timestamp, outputPath, signal);\n }\n materialized.set(sample, publicSample({\n ...sample,\n frame_status: result.ok ? \"ready\" : \"unavailable\",\n ...(result.error ? { error: result.error } : {}),\n }));\n }\n };\n await Promise.all(Array.from(\n { length: Math.min(FRAME_EXTRACTION_CONCURRENCY, plannedSamples.length) },\n () => worker(),\n ));\n const materializeSamples = (\n samples: readonly PlannedVideoStateEvidenceSample[],\n ): Omit<PlannedVideoStateEvidenceSample, \"source_path\">[] => samples.map((sample) => materialized.get(sample)!);\n\n const items = plan.items.map((item) => ({ ...item, samples: materializeSamples(item.samples) }));\n const identities = (plan.identities ?? [])\n .map((identity) => ({ ...identity, samples: materializeSamples(identity.samples) }));\n const manifest: VideoStateEvidenceManifest = {\n version: 2,\n generated_at: new Date().toISOString(),\n source_sha256: plan.source_sha256,\n items,\n ...(identities.length > 0 ? { identities } : {}),\n };\n if (store.has(\"evidence/state-evidence.json\")) {\n try {\n const existing = store.readJson<VideoStateEvidenceManifest>(\"evidence/state-evidence.json\");\n // identities must take part in the comparison, or a plan that only changed\n // identity frames would keep serving the stale sidecar.\n const comparable = (value: VideoStateEvidenceManifest) => JSON.stringify({\n version: value.version,\n source_sha256: value.source_sha256,\n items: value.items,\n identities: value.identities ?? [],\n });\n if (comparable(existing) === comparable(manifest)) return existing;\n } catch { /* replace a malformed or obsolete sidecar */ }\n }\n store.writeJson(\"evidence/state-evidence.json\", manifest);\n return manifest;\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport lockfile from \"proper-lockfile\";\n\nimport { CliError, EXIT_RUNTIME } from \"../../common.js\";\n\nexport async function withIngestWorkspaceLock<T>(workspacePath: string, operation: () => Promise<T>): Promise<T> {\n const root = path.resolve(workspacePath);\n fs.mkdirSync(root, { recursive: true });\n let release: (() => Promise<void>) | null = null;\n try {\n release = await lockfile.lock(root, {\n realpath: false,\n stale: 120_000,\n update: 10_000,\n retries: 0,\n });\n } catch (error) {\n throw new CliError(\"The ingest workspace is busy.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"INGEST_WORKSPACE_BUSY\",\n hint: \"Wait for the other ingest or skip command to finish, then retry.\",\n data: { actual: [root, error instanceof Error ? error.message : String(error)] },\n });\n }\n try {\n return await operation();\n } finally {\n await release();\n }\n}\n", "// ingest.video-serial task (\u00A710.2). The single Gemini pass of the serial video\n// pipeline: it watches ONE episode's video WITH the running cross-episode context\n// (registry + plot digest + open threads) and returns ONE structured JSON object\n// (responseMimeType application/json + VIDEO_SERIAL_SCHEMA) carrying both (a) the\n// episode's source-faithful storyboard screenplay (scenes \u2192 visual/performance/sound anchors) and (b) incremental\n// registry maintenance (new_entities / enrich / canonicalize) + open threads. This\n// replaces the old \"emit markdown \u2192 parseSerialMd\" contract: structured output\n// removes a whole fragile text-parsing layer and lets the schema forbid the outfit-\n// name pollution (parens/slashes) at the source. Because it parses in order with\n// full plot context, identity is resolved by story \u2014 reusing canonical names,\n// registering anchored provisionals for unknowns, and canonicalizing an existing\n// identity when direct written/spoken evidence reveals a better name.\n\nimport { CliError, EXIT_RUNTIME } from \"../../../common.js\";\nimport { isCrowdName } from \"../../../domain/ingest/serial-context.js\";\nimport { normalizeSceneTime } from \"../../../domain/ingest/environment.js\";\nimport { normalizeVideoTimestamp } from \"../../../domain/ingest/video-timestamp.js\";\nimport type { SerialOutput, SerialScene, SerialEntity, SerialIdentityProfile, SerialStateDescription } from \"../../../domain/ingest/video-serial-md.js\";\nimport { VIDEO_SERIAL_SCHEMA } from \"../schemas.js\";\nimport type { TaskVideoPort, VideoMediaInput } from \"../../types.js\";\n\nexport type { SerialOutput, SerialScene, SerialEntity } from \"../../../domain/ingest/video-serial-md.js\";\n\nexport const VIDEO_SERIAL_SYSTEM =\n \"\u4F60\u662F\u77ED\u5267\u89C6\u9891\u8F6C\u5267\u672C\u7684\u4E32\u884C\u89E3\u6790\u5668\u3002\u8F93\u5165\u662F**\u67D0\u4E00\u96C6**\u7AD6\u5C4F\u77ED\u5267\u89C6\u9891\uFF081-2 \u5206\u949F\uFF09+ \u4E00\u4EFD\u5230\u4E0A\u4E00\u96C6\u4E3A\u6B62\u7D2F\u79EF\u7684**\u5DF2\u77E5\u8BBE\u5B9A**\uFF08\u4EBA\u7269\u82B1\u540D\u518C/\u5267\u60C5\u8FDB\u5C55/\u672A\u95ED\u5408\u7EBF\u7D22\uFF09\u3002\" +\n \"\u4F60\u8981\u8F93\u51FA**\u4E00\u4E2A\u7ED3\u6784\u5316 JSON \u5BF9\u8C61**\uFF08\u4E25\u683C\u7B26\u5408\u7CFB\u7EDF\u7ED9\u5B9A\u7684\u8F93\u51FA schema\uFF09\uFF0C\u540C\u65F6\u5305\u542B\uFF1A\u2460\u8FD9\u4E00\u96C6\u5C3D\u91CF\u5FE0\u5B9E\u8FD8\u539F\u539F\u7247\u7684**\u5206\u955C\u5267\u672C**\uFF08scenes\uFF09\uFF1B\u2461\u5BF9\u5DF2\u77E5\u8BBE\u5B9A\u7684**\u589E\u91CF\u7EF4\u62A4**\uFF08registry_delta\uFF1A\u4EBA\u7269\u82B1\u540D\u518C\u5E26\u72B6\u6001\u6807\u6CE8\u3001\u89C4\u8303\u540D\u5347\u7EA7\uFF09+ \u5267\u60C5\u7EBF\u7D22\uFF08open_threads\uFF09\u3002**\u53EA\u8F93\u51FA\u8BE5 JSON\uFF0C\u4E0D\u8981\u4EFB\u4F55\u989D\u5916\u6587\u5B57\u3001\u89E3\u91CA\u6216\u4EE3\u7801\u5757\u5305\u88F9\u3002**\\n\" +\n \"\u6838\u5FC3\u8981\u6C42\uFF1A\u9010\u955C\u4FDD\u7559\u539F\u7247\u7684\u53EF\u89C1\u4FE1\u606F\u3001\u4EBA\u7269\u8868\u6F14\u3001\u7AD9\u4F4D\u5173\u7CFB\u3001\u6444\u5F71\u8C03\u5EA6\u4E0E\u5168\u90E8\u58F0\u97F3\uFF1B\u52A8\u4F5C/\u5BF9\u767D/\u5B9E\u4F53\u51C6\u786E\uFF0C\u4E0D\u8111\u8865\uFF0C\u65F6\u95F4\u6233\u5BF9\u9F50\u753B\u9762\u3002\\n\" +\n \"\u3010\u5355\u6B21\u89E3\u6790\u987A\u5E8F\u2014\u2014\u5FC5\u987B\u4F9D\u6B21\u5B8C\u6210\u3011\u7B2C\u4E00\u6B65\uFF0C\u4ECE\u89C6\u9891\u5F00\u5934\u5230\u7ED3\u5C3E\u5B8C\u6574\u542C\u4E00\u904D\u97F3\u8F68\uFF0C\u6309\u65F6\u95F4\u987A\u5E8F\u76D8\u70B9\u6240\u6709\u53EF\u8FA8\u8BC6\u4EBA\u58F0\uFF0C\u586B\u5165\u5404 scene \u7684 voices\uFF1B\u7B2C\u4E8C\u6B65\uFF0C\u4ECE\u5F00\u5934\u5230\u7ED3\u5C3E\u9010\u955C\u76D8\u70B9\u6BCF\u6B21\u5207\u955C\u3001\u8FDE\u7EED\u955C\u5934\u5185\u7684\u6444\u5F71\u53D8\u5316\u3001\u753B\u9762\u4E3B\u4F53\u3001\u7AD9\u4F4D\u3001\u52A8\u4F5C\u3001\u8868\u60C5\u3001\u89C6\u7EBF\u3001\u63A5\u89E6\u3001\u9053\u5177\u548C\u73AF\u5883\u53D8\u5316\uFF0C\u586B\u5165\u5404 scene \u7684 shots\uFF1B\u7B2C\u4E09\u6B65\uFF0C\u5206\u522B\u590D\u6838 voices \u662F\u5426\u5B8C\u6574\u3001shots \u662F\u5426\u9010\u955C\u8986\u76D6\u5168\u7247\u3002\u5B8C\u6210 JSON \u524D\u518D\u6B21\u590D\u6838\u6700\u540E\u5341\u79D2\uFF0C\u786E\u8BA4\u63D2\u5165\u753B\u9762\u3001\u624B\u673A/\u5C4F\u5E55\u753B\u9762\u3001\u56DE\u5FC6\u3001\u8499\u592A\u5947\u3001\u91CD\u590D\u753B\u9762\u3001\u53CD\u6253\u548C\u7247\u5C3E\u524D\u53CD\u5E94\u90FD\u6CA1\u6709\u6F0F\u5199\u3002\u76D8\u70B9\u548C\u590D\u6838\u53EA\u5728\u5185\u90E8\u5B8C\u6210\uFF0C\u4E0D\u53E6\u589E\u8F93\u51FA\u5B57\u6BB5\u3002\\n\" +\n \"\u3010\u8EAB\u4EFD\u5F52\u5C5E\u2014\u2014\u672C\u4EFB\u52A1\u91CD\u70B9\u3011\u5E26\u7740\u5DF2\u77E5\u8BBE\u5B9A\u770B\u8FD9\u4E00\u96C6\uFF1A\\n\" +\n \"- \u51FA\u73B0\u7684\u4EBA\u5148\u5224\u65AD**\u662F\u4E0D\u662F\u82B1\u540D\u518C\u91CC\u5DF2\u6709\u7684\u67D0\u4E2A\u4EBA**\uFF1A\u4F18\u5148\u6BD4\u5BF9\u591A\u6761 recognition_anchors \u548C identity_profile \u4E2D\u8DE8\u9020\u578B\u7A33\u5B9A\u7684\u8138\u90E8\u7ED3\u6784\u3001\u56FA\u5B9A\u6807\u8BB0\u3001\u53D1\u9645\u7EBF/\u5E38\u6001\u53D1\u578B\u3001\u9AA8\u67B6\u4F53\u578B\u4E0E\u58F0\u7EBF\uFF1B\u670D\u88C5\u3001\u5986\u5BB9\u548C\u5F53\u4E0B\u59FF\u6001\u53EA\u4F5C\u5F31\u8F85\u52A9\uFF0Crole \u53EA\u63D0\u4F9B\u89D2\u8272\u8BED\u5883\uFF0C\u4E0D\u80FD\u66FF\u4EE3\u89C6\u89C9\u8BC1\u636E\u3002\u7A33\u5B9A\u7279\u5F81\u4E00\u81F4\u624D\u6CBF\u7528\u5176**\u89C4\u8303\u540D**\u3002\u82E5\u5173\u952E\u7A33\u5B9A\u7279\u5F81\u51B2\u7A81\uFF0C\u4E0D\u8981\u5F3A\u884C\u5408\u5E76\uFF0C\u4FDD\u7559\u6216\u767B\u8BB0\u72EC\u7ACB provisional \u8EAB\u4EFD\u7B49\u5F85\u76F4\u63A5\u8BC1\u636E\u3002\\n\" +\n \"- \u8BA4\u4E0D\u51FA\u3001\u4E5F\u6CA1\u542C\u5230\u672C\u540D\u7684\u4EBA \u21D2 **\u4E0D\u8981\u786C\u731C\u3001\u4E0D\u8981\u7F16\u5E26\u59D3\u7684\u5047\u540D**\u3002\u7528\u300E\u7A33\u5B9A\u5916\u89C2\u7279\u5F81+\u5E74\u9F84\u6BB5+\u6027\u522B\u300F\u6784\u6210\u4E0D\u542B\u59D3\u6C0F\u7684\u63CF\u8FF0\u540D\uFF0Cstatus \u6807 `provisional`\uFF0C\u4ECD\u9700\u586B\u5199\u5B8C\u6574\u53EF\u89C1\u8EAB\u4EFD\u753B\u50CF\u3001\u8BC6\u522B\u951A\u70B9\u4E0E\u4F5C\u7528\u3002\\n\" +\n \"- \u63CF\u8FF0\u540D\u3001\u7B80\u79F0\u6216\u4E0D\u5B8C\u6574\u59D3\u540D\u53EA\u6709\u5728\u672C\u96C6\u51FA\u73B0**\u4E66\u9762\u6B63\u5F0F\u59D3\u540D\u6216\u53F0\u8BCD\u76F4\u63A5\u8BF4\u51FA\u672C\u540D**\u65F6\u624D\u80FD\u5347\u7EA7\u89C4\u8303\u540D\uFF1B\u5728 registry_delta.canonicalize \u5199 {from_name, canonical_name, evidence}\uFF0Cevidence \u5FC5\u987B\u5199\u660E\u65F6\u95F4\u6233\u548C\u5F53\u65F6\u53EF\u89C1\u7684\u539F\u6587\u6216\u542C\u5230\u7684\u539F\u8BDD\u3002\u5267\u60C5\u5173\u7CFB\u53EA\u80FD\u5E2E\u52A9\u5224\u65AD\u662F\u4E0D\u662F\u540C\u4E00\u4E2A\u4EBA\uFF0C\u4E0D\u80FD\u5355\u72EC\u4F5C\u4E3A\u6539\u540D\u8BC1\u636E\u3002\\n\" +\n \"- \u5B8C\u6210\u524D\u6267\u884C\u8D44\u4EA7\u5BF9\u8D26\uFF1A\u6C47\u603B scenes.location\u3001scenes.characters\u3001scenes.props \u4E0E\u4EBA\u7269 voices.speaker \u4E2D\u51FA\u73B0\u7684\u6BCF\u4E2A\u8D44\u4EA7\u540D\uFF0C\u9010\u9879\u786E\u8BA4\u5B83\u80FD\u89E3\u6790\u5230\u5DF2\u77E5\u8BBE\u5B9A\u3001registry_delta.new_entities \u6216\u672C\u96C6 canonicalize \u7684\u76EE\u6807\u3002\u4EFB\u4F55\u672A\u767B\u8BB0\u4EBA\u7269\u5FC5\u987B\u8865\u5165 new_entities \u5E76\u586B\u5199 identity_profile\u3001recognition_anchors\u3001role \u4E0E states\uFF1B\u672A\u767B\u8BB0\u5730\u70B9/\u9053\u5177\u5FC5\u987B\u586B\u5199 appearance\u3001role \u4E0E states\u3002\u82E5\u4E00\u4E2A\u7269\u4EF6\u4E0D\u503C\u5F97\u6210\u4E3A\u5173\u952E\u9053\u5177\u8D44\u4EA7\uFF0C\u5C31\u4ECE scenes.props \u79FB\u9664\u3002\u5BF9\u8D26\u5DEE\u96C6\u975E\u7A7A\u65F6\u4E0D\u5F97\u8F93\u51FA JSON\u3002\u89C4\u8303\u540D\u5347\u7EA7\u540E\u7ACB\u5373\u4F7F\u7528 canonical_name\uFF0C\u4E0D\u8BA9\u6B63\u6587\u8D44\u4EA7\u540D\u8131\u79BB\u82B1\u540D\u518C\u3002\\n\" +\n \"\u3010\u4EBA\u7269\u8EAB\u4EFD\u753B\u50CF\u3011\u9996\u6B21\u767B\u8BB0\u4EBA\u7269\u65F6\uFF0C\u4ECE\u5168\u7247\u591A\u4E2A\u6E05\u6670\u89D2\u5EA6\u7EFC\u5408\u586B\u5199 identity_profile\uFF0C\u800C\u4E0D\u662F\u7528\u4E00\u53E5\u7B3C\u7EDF\u5916\u8C8C\u6982\u62EC\u3002\u9010\u9879\u8BB0\u5F55\u53EF\u89C1\u6027\u522B\u4E0E\u5E74\u9F84\u6BB5\u3001\u8138\u578B/\u98A7\u9AA8/\u4E0B\u988C\u3001\u7709\u773C\u3001\u9F3B\u90E8\u3001\u9759\u6001\u5507\u5F62\u4E0E\u53E3\u5468\u3001\u7A33\u5B9A\u80A4\u8272\u548C\u9762\u90E8\u7279\u5F81\u3001\u7A33\u5B9A\u53D1\u8272/\u53D1\u9645\u7EBF/\u5E38\u6001\u53D1\u578B\u3001\u9AA8\u67B6\u4F53\u578B\u3001\u56FA\u5B9A\u8EAB\u4F53\u6807\u8BB0\uFF1B\u58F0\u7EBF\u4EC5\u4F9D\u636E\u6E05\u6670\u539F\u58F0\u586B\u5199\u3002\u770B\u4E0D\u6E05\u7684\u5B57\u6BB5\u7559\u7A7A\uFF0C\u4E0D\u731C\u6D4B\u3002\u63CF\u8FF0\u4F7F\u7528\u53EF\u89C2\u5BDF\u7684\u5F62\u72B6\u3001\u6BD4\u4F8B\u3001\u4F4D\u7F6E\u3001\u989C\u8272\u4E0E\u7EB9\u7406\uFF0C\u907F\u514D\u5BA1\u7F8E\u3001\u6C14\u8D28\u3001\u6027\u683C\u3001\u60C5\u7EEA\u548C\u5267\u60C5\u8BC4\u4EF7\u3002\u670D\u9970\u3001\u5986\u5BB9\u3001\u53EF\u6458\u9970\u54C1\u3001\u5F53\u4E0B\u8868\u60C5\u4E0E\u89C6\u7EBF\u3001\u52A8\u4F5C\u3001\u59FF\u6001\u3001\u4E34\u65F6\u4F24\u75D5/\u8840\u8FF9/\u6C61\u6E0D\u3001\u53D8\u8EAB\u6216\u5176\u4ED6\u9636\u6BB5\u6027\u5F62\u6001\u5C5E\u4E8E states \u6216 shots\uFF0C\u4E0D\u6DF7\u5165\u8EAB\u4EFD\u753B\u50CF\u3002\u586B\u5199\u5B8C\u9010\u5B57\u6BB5\u68C0\u67E5\uFF1A\u5047\u8BBE\u4EBA\u7269\u6362\u88C5\u3001\u5378\u5986\u3001\u6458\u6389\u914D\u9970\u3001\u6539\u53D8\u8868\u60C5\u5E76\u8FDB\u5165\u53E6\u4E00\u573A\u666F\uFF0C\u8BE5\u63CF\u8FF0\u662F\u5426\u4ECD\u6210\u7ACB\uFF1B\u4E0D\u6210\u7ACB\u5C31\u4ECE identity_profile \u79FB\u51FA\u3002\\n\" +\n \"\u3010\u8BC6\u522B\u951A\u70B9\u3011\u4EBA\u7269 recognition_anchors \u5199 3-6 \u6761\u6700\u9002\u5408\u8DE8\u96C6\u91CD\u8BA4\u7684\u7EC4\u5408\u7279\u5F81\uFF1B\u6BCF\u6761\u81F3\u5C11\u7EC4\u5408\u4E24\u4E2A\u6765\u81EA identity_profile \u7684\u7A33\u5B9A\u3001\u53EF\u533A\u5206\u7EBF\u7D22\uFF0C\u5E76\u5C3D\u91CF\u8986\u76D6\u8138\u90E8\u7ED3\u6784\u3001\u4E94\u5B98\u6BD4\u4F8B\u3001\u56FA\u5B9A\u8EAB\u4F53\u6807\u8BB0\u3001\u53D1\u9645\u7EBF/\u5E38\u6001\u5934\u53D1\u3001\u9AA8\u67B6\u4F53\u578B\u6216\u58F0\u7EBF\u7B49\u4E0D\u540C\u7EF4\u5EA6\u3002\u951A\u70B9\u4E0D\u5F97\u5305\u542B\u670D\u88C5\u3001\u5236\u670D\u53F7\u7801\u3001\u5E3D\u5B50\u3001\u773C\u955C\u6216\u5176\u4ED6\u53EF\u6458\u914D\u9970\u3001\u5986\u5BB9\u3001\u5F53\u4E0B\u795E\u60C5/\u52A8\u4F5C/\u59FF\u6001\u3001\u4E34\u65F6\u4F24\u75D5\u6C61\u6E0D\u3001\u5267\u60C5\u8EAB\u4EFD/\u80FD\u529B/\u5173\u7CFB\u3001\u53D8\u8EAB\u5F62\u6001\u6216\u968F\u573A\u666F\u53D8\u5316\u7684\u7269\u4EF6\u3002\u5DF2\u6709\u5B9E\u4F53\u5728\u672C\u96C6\u51FA\u73B0\u66F4\u6E05\u6670\u89D2\u5EA6\u65F6\uFF0C\u7528 enrich.identity_profile_patch \u53EA\u8865\u5145\u6216\u4FEE\u6B63\u6709\u65B0\u8BC1\u636E\u7684\u5B57\u6BB5\uFF0C\u5E76\u7528 add_recognition_anchors \u589E\u52A0\u65B0\u951A\u70B9\uFF1B\u4E0D\u8981\u628A\u6574\u6BB5\u65E7\u753B\u50CF\u6539\u5199\u6210\u53E6\u4E00\u53E5\u3002\u8F93\u51FA\u524D\u9010\u6761\u6838\u5BF9\uFF1A\u951A\u70B9\u4E2D\u7684\u6BCF\u4E2A\u8BCD\u90FD\u80FD\u5728 identity_profile \u627E\u5230\u7A33\u5B9A\u4F9D\u636E\uFF0C\u5426\u5219\u91CD\u5199\u6216\u5220\u9664\u3002\\n\" +\n \"\u3010\u5730\u70B9\u3001\u9053\u5177\u4E0E\u72B6\u6001\u63CF\u8FF0\u3011\u5730\u70B9 appearance \u5199\u7A7A\u95F4\u7ED3\u6784\u3001\u6750\u8D28\u3001\u8272\u5F69\u548C\u56FA\u5B9A\u9648\u8BBE\uFF0Crole \u5199\u7A7A\u95F4\u7528\u9014\uFF1B\u9053\u5177 appearance \u5199\u5F62\u5236\u3001\u6750\u8D28\u3001\u989C\u8272\u548C\u5C3A\u5BF8\u5173\u7CFB\uFF0Crole \u5199\u7528\u9014\u3002states \u7684\u6BCF\u9879\u90FD\u5FC5\u987B\u540C\u65F6\u7ED9\u51FA\u53EF\u590D\u73B0\u7684\u975E\u7A7A description\u3002\u4EBA\u7269\u9020\u578B\u5148\u7EFC\u5408\u672C\u96C6\u591A\u4E2A\u6E05\u6670\u955C\u5934\uFF0C\u518D\u6309\u4ECE\u5934\u5230\u811A\u7684\u7A33\u5B9A\u5C42\u6B21\u63CF\u8FF0\uFF1A\u8BE5\u9020\u578B\u7279\u6709\u7684\u53D1\u578B\u4E0E\u5934\u9970\u3001\u5986\u5BB9\u3001\u9888\u90E8\u9970\u7269\u3001\u5916\u5957\u3001\u4E0A\u88C5\u3001\u4E0B\u88C5\u6216\u8FDE\u4F53\u8863\u88D9\u3001\u889C\u7C7B\u3001\u978B\u5C65\u3001\u624B\u5957\u53CA\u5176\u4ED6\u9970\u54C1\uFF1B\u6BCF\u4EF6\u770B\u6E05\u7684\u5355\u54C1\u5199\u660E\u989C\u8272\u3001\u6750\u8D28/\u5149\u6CFD/\u7EB9\u7406\u3001\u7248\u578B\u4E0E\u677E\u7D27\u3001\u9886\u578B\u3001\u8896\u578B\u3001\u5F00\u5408\u3001\u8170\u7EBF\u3001\u957F\u5EA6\u3001\u4E0B\u6446\u3001\u56FE\u6848\u3001\u6587\u5B57\u6807\u8BC6\u3001\u6EDA\u8FB9\u6216\u91D1\u5C5E\u4EF6\uFF0C\u5E76\u5199\u6E05\u5185\u5916\u53E0\u7A7F\u548C\u914D\u9970\u6240\u5728\u4F4D\u7F6E\uFF1B\u6301\u7EED\u7834\u635F\u3001\u8840\u8FF9\u3001\u6C61\u6E0D\u6216\u53D8\u5F62\u5199\u660E\u90E8\u4F4D\u3001\u8303\u56F4\u4E0E\u989C\u8272\u3002\u53EA\u7701\u7565\u753B\u9762\u672A\u663E\u793A\u6216\u65E0\u6CD5\u786E\u8BA4\u7684\u9879\uFF0C\u4E0D\u7528\u300E\u7A7F\u7740\u67D0\u670D\u88C5\u300F\u4E00\u53E5\u5E26\u8FC7\uFF0C\u4E0D\u51ED\u5C40\u90E8\u955C\u5934\u8865\u5168\u5168\u8EAB\u3002\u5730\u70B9\u548C\u9053\u5177\u72B6\u6001\u5199\u76F8\u5BF9\u5E38\u6001\u7684\u6301\u7EED\u5916\u89C2\u5DEE\u5F02\u3002\u6240\u6709\u63CF\u8FF0\u53EA\u5199\u753B\u9762\u4E8B\u5B9E\uFF0C\u4E0D\u5199\u52A8\u4F5C\u3001\u59FF\u6001\u3001\u60C5\u7EEA\u3001\u5FC3\u7406\u6216\u5267\u60C5\u8BC4\u4EF7\u3002\u5DF2\u77E5\u8BBE\u5B9A\u4E2D\u5DF2\u6709\u7684\u72B6\u6001\u6CBF\u7528\u5176 name\uFF1B\u672C\u96C6\u770B\u5230\u66F4\u591A\u89D2\u5EA6\u6216\u66F4\u6E05\u6670\u7EC6\u8282\u65F6\uFF0C\u7528 enrich.add_states \u7684\u540C\u540D\u9879\u8865\u5168 description\u3002\\n\" +\n \"\u3010\u8BF4\u8BDD\u4EBA\u2014\u2014\u7528\u5267\u60C5\u9501\u5B9A\uFF0C\u522B\u53EA\u770B\u8138\u3011\u77ED\u5267\u5E38\u6709\u51E0\u4E2A\u957F\u76F8\u76F8\u4F3C\u7684\u4E2D\u8001\u5E74\u7537\u6027\u9AD8\u7BA1\uFF0C\u5355\u5E27\u4EBA\u8138\u4F1A\u8BA4\u9519\u3002\u5148\u4ECE\u53F0\u8BCD\u5185\u5BB9\u3001\u5F7C\u6B64\u79F0\u547C\uFF08\u8C01\u53EB\u8C01\u300C\u54E5\u300D\u300CX\u603B\u300D\uFF09\u3001\u573A\u666F\u5173\u7CFB\uFF08\u8C01\u6C42\u8C01\u3001\u8C01\u8BAD\u8C01\u3001\u8C01\u4E0B\u8DEA\uFF09\u63A8\u65AD\u8FD9\u573A\u5728\u573A\u662F\u8C01\u3001\u8C01\u5BF9\u8C01\u8BF4\uFF0C\u518D\u5B9A\u8BF4\u8BDD\u4EBA\u3002\u5267\u60C5\u9501\u5B9A\u4F18\u5148\u4E8E\u5916\u8C8C\u3002\\n\" +\n \"\u3010\u547D\u540D\u4F18\u5148\u7EA7\u3011\u4E66\u9762\u6B63\u5F0F\u59D3\u540D\uFF08\u4EBA\u7269\u4ECB\u7ECD\u6761/\u5DE5\u724C/\u6765\u7535\u663E\u793A\uFF09> \u53F0\u8BCD\u558A\u51FA\u7684\u672C\u540D > \u7EAF\u63CF\u8FF0\u540D\u3002\u6709\u4E66\u9762\u6B63\u5F0F\u59D3\u540D\u5C31\u7528\u5B83\u5F53\u89C4\u8303\u540D\uFF0C\u54EA\u6015\u5168\u96C6\u53EA\u558A\u804C\u52A1\u3002\u7EDD\u4E0D\u51ED\u7A7A\u634F\u9020\u5E26\u59D3\u6C0F\u7684\u5047\u540D\u3002\\n\" +\n \"\u3010\u89C4\u8303\u540D\u552F\u4E00\u6027\u3011\u4EBA\u7269\u89C4\u8303\u540D\u53EA\u5199\u59D3\u540D\u6216\u7A33\u5B9A\u63CF\u8FF0\u540D\uFF0C\u89D2\u8272\u804C\u80FD\u3001\u5173\u7CFB\u3001\u5907\u6CE8\u4E0D\u5F97\u585E\u8FDB\u62EC\u53F7\u3002\u8F93\u51FA\u524D\u6309\u53BB\u7A7A\u683C\u3001\u7EDF\u4E00\u5168\u534A\u89D2\u62EC\u53F7\u5E76\u5FFD\u7565\u62EC\u53F7\u5907\u6CE8\u540E\u7684\u53EF\u89C1\u540D\u79F0\u68C0\u67E5\u82B1\u540D\u518C\uFF1B\u4E24\u4E2A\u4E0D\u540C\u4EBA\u7269\u4E0D\u5F97\u5F97\u5230\u4F1A\u88AB\u5F52\u4E00\u6210\u540C\u540D\u7684\u89C4\u8303\u540D\u3002\u82E5\u53F0\u8BCD\u53EA\u7ED9\u51FA\u76F8\u540C\u79F0\u547C\uFF0C\u4FDD\u7559\u5DF2\u77E5\u4EBA\u7269\u539F\u540D\uFF0C\u5E76\u7ED9\u65B0\u4EBA\u7269\u4F7F\u7528\u80FD\u533A\u5206\u8EAB\u4EFD\u4E14\u4E0D\u5E26\u62EC\u53F7\u7684\u7A33\u5B9A\u63CF\u8FF0\u540D\uFF0C\u4F8B\u5982\u300E\u5A92\u5A46\u738B\u5A76\u300F\uFF0C\u89D2\u8272\u8BF4\u660E\u7EE7\u7EED\u5199\u5728 role\u3002\\n\" +\n \"\u3010\u58F0\u97F3\u5B8C\u6574\u6027\u3011\u6BCF\u6BB5\u53EF\u8FA8\u8BC6\u7684\u4EBA\u58F0\u90FD\u5FC5\u987B\u5728 voices \u4E2D\u51FA\u73B0\u4E14\u53EA\u51FA\u73B0\u4E00\u6B21\uFF0C\u5305\u62EC\u4EBA\u7269\u51FA\u955C\u5BF9\u767D\u3001\u753B\u5916\u5BF9\u767D\u3001\u89D2\u8272\u5185\u5FC3\u72EC\u767D/\u81EA\u8FF0\u3001\u5BA2\u89C2\u65C1\u767D\u3001\u7535\u8BDD/\u5E7F\u64AD/\u8BBE\u5907\u58F0\u3001\u8033\u8BED\u3001\u7FA4\u4F53\u58F0\u548C\u8DE8\u753B\u9762\u8FDE\u7EED\u8BB2\u8FF0\u3002\u8BF4\u8BDD\u65F6\u753B\u9762\u5207\u6362\u3001\u4EBA\u7269\u672A\u51FA\u955C\u3001\u53EA\u663E\u793A\u6D41\u7A0B\u56FE/\u5730\u56FE/\u624B\u673A/\u5C4F\u5E55\u3001\u8FDB\u5165\u56DE\u5FC6\u6216\u8499\u592A\u5947\u3001\u91CD\u590D\u67D0\u6BB5\u753B\u9762\u3001\u53E3\u578B\u4E0D\u53EF\u89C1\uFF0C\u90FD\u4E0D\u662F\u7701\u7565\u58F0\u97F3\u7684\u7406\u7531\u3002\u8FDE\u7EED\u8BB2\u8FF0\u8DE8 scene \u6216\u8DE8\u955C\u65F6\u6309\u81EA\u7136\u8BED\u53E5\u5728\u5BF9\u5E94\u65F6\u95F4\u70B9\u62C6\u5206\uFF0C\u539F\u8BDD\u5B8C\u6574\u4FDD\u7559\u3001\u4E0D\u91CD\u4E0D\u6F0F\uFF1B\u7528\u540C\u8BED\u8A00\u5BF9\u767D\u5B57\u5E55\u9010\u53E5\u6838\u5BF9\u97F3\u8F68\uFF0C\u5C24\u5176\u68C0\u67E5\u77ED\u53E5\u548C\u63D2\u5165\u753B\u9762\u4E0A\u7684\u8FDE\u7EED\u58F0\u97F3\u3002\\n\" +\n \"\u3010\u539F\u58F0\u8BED\u8A00\u94C1\u5F8B\u3011voices.content \u9010\u5B57\u4FDD\u7559\u97F3\u8F68\u5B9E\u9645\u4F7F\u7528\u7684\u8BED\u8A00\u3001\u6587\u5B57\u548C\u5939\u6742\u8BED\u8A00\uFF0C\u4E0D\u7FFB\u8BD1\u3001\u4E0D\u6539\u5199\u3001\u4E0D\u7528\u4E2D\u6587\u5B57\u5E55\u66FF\u6362\u5916\u8BED\u539F\u58F0\u3002\u82F1\u6587\u97F3\u8F68\u914D\u4E2D\u6587\u5B57\u5E55\u65F6\u5199\u82F1\u6587\u539F\u8BCD\uFF1B\u5370\u5C3C\u8BED\u3001\u6CF0\u8BED\u6216\u5176\u4ED6\u8BED\u8A00\u97F3\u8F68\u5199\u5BF9\u5E94\u8BED\u8A00\u539F\u8BCD\uFF1B\u540C\u4E00\u53E5\u53D1\u751F code-switch \u65F6\u6309\u542C\u5230\u7684\u987A\u5E8F\u539F\u6837\u4FDD\u7559\u3002\u8BC1\u636E\u4F18\u5148\u7EA7\u662F\u539F\u59CB\u97F3\u8F68 > \u4E0E\u97F3\u8F68\u540C\u8BED\u8A00\u7684\u5BF9\u767D\u5B57\u5E55 > \u7FFB\u8BD1\u5B57\u5E55\u3002\u5B57\u5E55\u53EA\u80FD\u8F85\u52A9\u8FA8\u6E05\u540C\u8BED\u8A00\u539F\u8BCD\uFF0C\u4E0D\u80FD\u6539\u53D8\u53F0\u8BCD\u8BED\u8A00\uFF1B\u542C\u4E0D\u6E05\u65F6\u4FDD\u7559\u53EF\u786E\u8BA4\u90E8\u5206\u5E76\u5728 parenthetical \u6807\u300E\u542C\u8FA8\u5F85\u590D\u6838\u300F\uFF0C\u4E0D\u8981\u7528\u7FFB\u8BD1\u5B57\u5E55\u731C\u53F0\u8BCD\u3002\\n\" +\n \"\u3010\u753B\u9762\u6587\u5B57\u4E0E\u5D4C\u5957\u753B\u9762\u3011\u5E95\u90E8\u5BF9\u767D\u5B57\u5E55\u662F\u58F0\u97F3\u53F0\u8BCD\u7684\u5197\u4F59\u8BC1\u636E\uFF0C\u4E0D\u5355\u72EC\u5EFA shot\uFF1B\u7528\u5B83\u9010\u53E5\u6838\u5BF9 voices \u662F\u5426\u5B8C\u6574\u3002\u627F\u8F7D\u65B0\u4FE1\u606F\u7684\u753B\u9762\u6587\u5B57\uFF08\u4EBA\u7269\u4ECB\u7ECD\u6761/\u8EAB\u4EFD\u5934\u8854/\u65F6\u95F4\u5730\u70B9\u4EA4\u4EE3/\u7CFB\u7EDF\u63D0\u793A/\u5173\u952E\u9053\u5177\u4E0A\u7684\u5B57\uFF09\u5199\u5165\u5BF9\u5E94 shot.visual\u3002\u624B\u673A\u3001\u76D1\u63A7\u3001\u5C4F\u5E55\u3001\u7167\u7247\u548C\u56DE\u5FC6\u753B\u9762\u53EA\u5199\u5B9E\u9645\u53EF\u89C1\u7684\u4EBA\u7269\u52A8\u4F5C\u3001\u7269\u4F53\u548C\u53EF\u8BFB\u6587\u5B57\uFF1B\u6CA1\u6709\u753B\u9762\u3001\u53F0\u8BCD\u6216\u6587\u5B57\u76F4\u63A5\u8BC1\u660E\u65F6\uFF0C\u4E0D\u63A8\u65AD\u4EBA\u7269\u8EAB\u4F53\u72B6\u6001\u3001\u4E8B\u4EF6\u539F\u56E0\u3001\u524D\u540E\u5173\u7CFB\u6216\u7ED3\u679C\u3002\\n\" +\n \"\u3010\u72B6\u6001=\u9020\u578B\u3011state / states = \u4E00\u4E2A\u89D2\u8272\u4E00\u6574\u5957\u7A33\u5B9A\u626E\u76F8\uFF08\u7740\u88C5+\u53D1\u578B+\u6301\u7EED\u5986\u9020\uFF0C\u5982\u300C\u6DF1\u7070\u897F\u88C5\u300D\uFF09\uFF0C\u4E0D\u662F\u60C5\u7EEA/\u59FF\u6001\uFF0C\u4E5F\u4E0D\u662F\u5355\u4EF6\u8863\u670D\u3002\u7ED9\u67D0\u89D2\u8272\u6807\u9020\u578B\u524D\uFF0C\u5148\u770B\u5DF2\u77E5\u8BBE\u5B9A\u91CC\u4ED6\u540D\u4E0B\u7684\u300C\u5DF2\u77E5\u9020\u578B\u300D\u6E05\u5355\u2014\u2014\u53EA\u8981\u672C\u96C6\u662F\u4ED6\u5DF2\u5217\u8FC7\u7684\u67D0\u5957\u626E\u76F8\uFF08\u54EA\u6015\u53EA\u62CD\u5230\u4E0A\u534A\u8EAB/\u6362\u4E86\u89D2\u5EA6/\u5149\u7EBF\u4E0D\u540C/\u591A\u770B\u5230\u5C11\u770B\u5230\u4E00\u4EF6\u5355\u54C1\uFF09\uFF0C**\u9010\u5B57\u7167\u6284\u6E05\u5355\u91CC\u90A3\u4E2A\u9020\u578B\u540D**\uFF0C\u53EA\u6709\u6574\u5957\u6362\u88C5\u624D\u65B0\u5EFA\u3002\u9020\u578B\u540D\u53EA\u586B\u7B80\u6D01\u6863\u4F4D\u540D\uFF0C\u8BE6\u7EC6\u7EC4\u6210\u5168\u90E8\u5199\u8FDB state.description\u3002\u8F93\u51FA\u524D\u590D\u6838\u6BCF\u4E2A\u9020\u578B\uFF1A\u753B\u9762\u770B\u6E05\u7684\u670D\u88C5\u5C42\u6B21\u3001\u7248\u578B\u7ED3\u6784\u3001\u6750\u8D28\u914D\u8272\u3001\u978B\u889C\u3001\u5986\u53D1\u548C\u914D\u9970\u662F\u5426\u5DF2\u8986\u76D6\uFF1B\u82E5\u66F4\u6E05\u6670\u955C\u5934\u80FD\u8865\u5145\u65E2\u6709\u9020\u578B\uFF0C\u5C31\u66F4\u65B0\u540C\u540D description\uFF0C\u4E0D\u53E6\u5EFA\u8FD1\u4E49\u9020\u578B\u3002\\n\" +\n // Retired experiment: Gemini previously selected identity_evidence and\n // state_evidence timestamps in this same response. The post-ingest evidence\n // pass now derives candidates from stable actors/states and Action timestamps,\n // avoiding extra output tokens and keeping evidence rebuildable without LLMs.\n \"\u3010\u573A\u754C\u4E0E\u5730\u70B9\u3011\u4E00\u573A\u662F\u5730\u70B9\u3001\u8FDE\u7EED\u65F6\u6BB5\u548C\u53D9\u4E8B\u7EBF\u8FDE\u7EED\u7684\u751F\u4EA7\u5355\u5143\u3002\u5BA2\u5385\u3001\u5367\u5BA4\u3001\u536B\u751F\u95F4\u3001\u5927\u5385\u3001\u5E7F\u573A\u3001\u821E\u53F0\u3001\u540E\u53F0\u5206\u522B\u4F7F\u7528\u72EC\u7ACB location\uFF1B\u76F8\u5173\u7A7A\u95F4\u7EDF\u4E00\u547D\u540D\u4E3A\u300E\u8C6A\u5B85\u00B7\u5BA2\u5385\u300F\u300E\u8C6A\u5B85\u00B7\u5367\u5BA4\u300F\u3002\u4EBA\u7269\u8DE8\u8FC7\u95E8\u69DB\u8FDB\u5165\u53E6\u4E00\u7A7A\u95F4\u3001\u53D9\u4E8B\u8FDB\u5165\u53E6\u4E00\u7A33\u5B9A\u7A7A\u95F4\u3001\u660E\u663E\u8DF3\u65F6\u3001\u5207\u6362\u53D9\u4E8B\u7EBF\u6216\u660E\u786E\u8F6C\u573A\u65F6\u5EFA\u7ACB\u65B0 scene\u3002\u4E00\u4E2A scene \u53EA\u5199\u4E00\u4E2A\u4E3B location\uFF1B\u540C\u4E00\u8FDE\u7EED\u573A\u5185\u7684\u4EBA\u7269\u9020\u578B\u53D8\u5316\u4E0D\u662F\u5206\u573A\u7406\u7531\u3002\\n\" +\n \"\u3010\u72B6\u6001\u53D8\u5316\u4E0E\u573A\u5185\u8D44\u4EA7\u3011\u4EBA\u7269\u6362\u6574\u5957\u670D\u88C5\u3001\u53D8\u8EAB\u3001\u8131\u8863\u5F62\u6210\u53EF\u6301\u7EED\u65B0\u5916\u89C2\u65F6\uFF0C\u628A\u53D8\u5316\u52A8\u4F5C\u5199\u5165\u5F53\u524D scene \u7684 shots\u3002characters \u4E2D\u540C\u4E00\u89C4\u8303\u540D\u53EA\u51FA\u73B0\u4E00\u6B21\uFF1B\u8BE5\u6761\u7684 states \u662F\u672C\u573A\u51FA\u73B0\u8FC7\u7684\u5168\u90E8\u7A33\u5B9A\u9020\u578B\u96C6\u5408\uFF0C\u4E0D\u80FD\u6F0F\u6389\u53D8\u5316\u524D\u6216\u53D8\u5316\u540E\u72B6\u6001\uFF0C\u4E5F\u4E0D\u6309\u5148\u540E\u62C6\u6210\u91CD\u590D\u4EBA\u7269\u3002\u5730\u70B9\u88AB\u6BC1\u6216\u5173\u952E\u9053\u5177\u660E\u663E\u53D8\u5F62\u65F6\u767B\u8BB0\u5BF9\u5E94\u65B0 state\u3002\u60C5\u7EEA\u3001\u59FF\u6001\u548C\u4E00\u6B21\u6027\u52A8\u4F5C\u4FDD\u7559\u5728 shots \u7684 visual\uFF0C\u4E0D\u5EFA\u7ACB state\u3002\\n\" +\n \"\u3010\u9010\u955C\u8FD8\u539F\u3011shots \u662F\u72EC\u7ACB\u5206\u955C\u6E05\u5355\u3002\u6BCF\u6B21\u5207\u955C\u90FD\u5728\u8D77\u59CB\u65F6\u95F4\u65B0\u589E\u4E00\u6761 shot\uFF0C\u5373\u4F7F\u5B83\u91CD\u590D\u5C55\u793A\u4E4B\u524D\u7684\u52A8\u4F5C\u6216\u6CA1\u6709\u65B0\u5267\u60C5\uFF0C\u4E5F\u8981\u4FDD\u7559\u3002\u8FDE\u7EED\u955C\u5934\u5185\u7684\u666F\u522B\u3001\u62CD\u6444\u89D2\u5EA6\u3001\u673A\u4F4D\u3001\u955C\u5934\u79FB\u52A8\u3001\u6784\u56FE\u3001\u7126\u70B9\u6216\u753B\u9762\u4E3B\u4F53\u53D8\u5316\uFF0C\u4EE5\u53CA\u6BCF\u4E2A\u65B0\u52A8\u4F5C\u3001\u53CD\u5E94\u3001\u63A5\u89E6/\u5206\u5F00\u3001\u9053\u5177\u64CD\u4F5C\u4E0E\u7ED3\u679C\u3001\u8FDB\u51FA\u573A\u3001\u79FB\u52A8\u3001\u59FF\u52BF/\u671D\u5411/\u89C6\u7EBF\u6216\u7A7A\u95F4\u5173\u7CFB\u53D8\u5316\uFF0C\u90FD\u5728\u5B9E\u9645\u53D1\u751F\u65F6\u53E6\u589E shot\u3002\u4E0D\u5F97\u628A\u5148\u540E\u53D1\u751F\u7684\u5206\u955C\u6216\u52A8\u4F5C\u538B\u7F29\u6210\u5267\u60C5\u6982\u8FF0\u3002\\n\" +\n \"\u3010shot.camera\u3011\u53EA\u5199\u539F\u7247\u53EF\u89C1\u3001\u53EF\u590D\u73B0\u7684\u6444\u5F71\u4FE1\u606F\uFF1A\u8FDC\u666F/\u5168\u666F/\u4E2D\u666F/\u8FD1\u666F/\u7279\u5199\u7B49\u666F\u522B\uFF0C\u4FEF\u62CD/\u4EF0\u62CD/\u5E73\u89C6/\u4FA7\u9762/\u80CC\u9762\u7B49\u89D2\u5EA6\uFF0C\u56FA\u5B9A\u3001\u63A8\u3001\u62C9\u3001\u6447\u3001\u79FB\u3001\u8DDF\u3001\u73AF\u7ED5\u3001\u5347\u964D\u3001\u7126\u70B9\u8F6C\u79FB\u7B49\u53EF\u786E\u8BA4\u7684\u8FD0\u955C\uFF0C\u4EE5\u53CA\u524D\u666F/\u4E2D\u666F/\u540E\u666F\u3001\u753B\u9762\u5DE6\u53F3\u3001\u906E\u6321\u548C\u4E3B\u4F53\u5360\u4F4D\u3002\u5207\u955C\u3001\u53CD\u6253\u3001\u63D2\u5165\u955C\u5934\u3001\u4E3B\u89C2\u955C\u5934\u3001\u7A7A\u955C\u548C\u91CD\u590D\u955C\u5934\u90FD\u5982\u5B9E\u4FDD\u7559\u3002\u4E0D\u63A8\u6D4B\u753B\u9762\u65E0\u6CD5\u786E\u8BA4\u7684\u955C\u5934\u53C2\u6570\u3001\u955C\u5934\u578B\u53F7\u3001\u706F\u5149\u8BBE\u7F6E\u6216\u62CD\u6444\u610F\u56FE\u3002\\n\" +\n \"\u3010\u7AD9\u4F4D\u4E0E\u6301\u7EED\u72B6\u6001\u3011\u6BCF\u573A\u7B2C\u4E00\u4E2A shot \u7684 visual \u5EFA\u7ACB\u753B\u9762\u53EF\u786E\u8BA4\u7684\u4EBA\u7269\u7AD9\u4F4D/\u5750\u5367\u4F4D\u7F6E\u3001\u4E0E\u5730\u70B9\u56FA\u5B9A\u53C2\u7167\u7269\u7684\u5173\u7CFB\u3001\u4EBA\u7269\u4E4B\u95F4\u7684\u8FDC\u8FD1\u4E0E\u524D\u540E\u5DE6\u53F3\u3001\u59FF\u6001\u3001\u9762\u5411\u3001\u89C6\u7EBF\u3001\u63A5\u89E6\u548C\u6B63\u5728\u8FDB\u884C\u7684\u884C\u4E3A\u3002\u540E\u7EED\u5207\u955C\u82E5\u663E\u793A\u65B0\u7684\u6784\u56FE\u5173\u7CFB\uFF0C\u5199\u6E05\u4EBA\u7269\u5728\u753B\u9762\u5DE6/\u53F3\u3001\u524D\u666F/\u4E2D\u666F/\u540E\u666F\u7684\u4F4D\u7F6E\uFF1B\u82E5\u4EBA\u7269\u8FDB\u51FA\u3001\u79FB\u52A8\u3001\u8F6C\u8EAB\u3001\u6539\u53D8\u59FF\u52BF\u3001\u6CE8\u89C6\u5BF9\u8C61\u3001\u63A5\u89E6\u6216\u5206\u5F00\uFF0C\u5199\u6E05\u53D8\u5316\u524D\u540E\u7684\u5173\u7CFB\u3002\u6301\u7EED\u72B6\u6001\u4E0D\u56E0\u5BF9\u767D\u800C\u5931\u6548\uFF0C\u4F46\u6BCF\u6B21\u5207\u955C\u4ECD\u9700\u5199\u8BE5\u955C\u5934\u5B9E\u9645\u5448\u73B0\u7684\u6784\u56FE\u548C\u4E3B\u4F53\u3002\\n\" +\n \"\u3010\u9010\u53E5\u5BF9\u767D\u4E0E\u540C\u671F\u8868\u6F14\u5BF9\u9F50\u2014\u2014\u672C\u4EFB\u52A1\u5B8C\u6210\u95E8\u3011\u4E3A\u6BCF\u6761 voice \u5355\u72EC\u56DE\u770B\u8BE5\u53E5\u5F00\u59CB\u524D\u5230\u8BF4\u5B8C\u7684\u753B\u9762\uFF0C\u786E\u8BA4\u8BF4\u8BDD\u8005\u548C\u540C\u573A\u4EBA\u7269\u5F53\u65F6\u7684\u53EF\u89C1\u52A8\u4F5C\u3001\u8868\u60C5\u3001\u89C6\u7EBF\u3001\u59FF\u6001\u3001\u63A5\u89E6\u548C\u4F4D\u7F6E\u5173\u7CFB\u5DF2\u5728 shots \u4E2D\u51C6\u786E\u627F\u8F7D\u3002\u4E0E\u8FD9\u53E5\u8BDD\u540C\u65F6\u53D1\u751F\u3001\u4E0D\u72EC\u7ACB\u6539\u53D8\u8FDE\u7EED\u6027\u7684\u77ED\u4FC3\u8868\u6F14\u53EF\u5199\u5165\u8BE5 voice \u7684 parenthetical\uFF1B\u8D70\u4F4D\u3001\u59FF\u52BF\u53D8\u5316\u3001\u63A5\u89E6/\u5206\u5F00\u3001\u9053\u5177\u64CD\u4F5C\u6216\u7A7A\u95F4\u5173\u7CFB\u53D8\u5316\u5199\u5165\u5BF9\u5E94\u65F6\u95F4\u7684 shot.visual\u3002\u4E0D\u5F97\u8BA9\u5BF9\u767D\u65F6\u95F4\u70B9\u5C06\u6B63\u5728\u53D1\u751F\u7684\u53EF\u89C1\u8868\u6F14\u53D8\u6210\u5BF9\u767D\u4E4B\u540E\u7684\u52A8\u4F5C\u3002\\n\" +\n \"\u3010shot.visual\u3011\u4F7F\u7528\u4EBA\u7269\u89C4\u8303\u540D\uFF0C\u5199\u6E05\u884C\u52A8\u8005\u3001\u52A8\u4F5C\u3001\u4F5C\u7528\u5BF9\u8C61\u3001\u7A7A\u95F4\u65B9\u5411\u548C\u53EF\u89C1\u7ED3\u679C\u3002\u53EA\u5199\u5177\u4F53\u53EF\u89C1\u7684\u7709\u773C\u3001\u5634\u90E8\u3001\u547C\u5438\u3001\u89C6\u7EBF\u3001\u624B\u52BF\u3001\u59FF\u6001\u3001\u63A5\u89E6\u3001\u79FB\u52A8\u3001\u9053\u5177\u548C\u73AF\u5883\u53D8\u5316\uFF0C\u4E0D\u7528\u6124\u6012\u3001\u7126\u8651\u3001\u59D4\u5C48\u3001\u7EDD\u671B\u3001\u9707\u60CA\u3001\u54C0\u6C42\u3001\u5632\u8BBD\u7B49\u60C5\u7EEA\u3001\u6001\u5EA6\u6216\u5FC3\u7406\u5224\u65AD\u4EE3\u66FF\u753B\u9762\u4E8B\u5B9E\u3002\u53EA\u5199\u539F\u7247\u80FD\u591F\u786E\u8BA4\u7684\u4E8B\u5B9E\uFF1B\u770B\u4E0D\u6E05\u7684\u4F4D\u7F6E\u3001\u671D\u5411\u3001\u8868\u60C5\u6216\u52A8\u4F5C\u4E0D\u5199\uFF0C\u4E0D\u8865\u9020\u3002synopsis \u53EF\u4EE5\u6982\u62EC\u5267\u60C5\uFF0Cshots \u4E0D\u5F97\u5199\u6210\u5267\u60C5\u6897\u6982\u3002\\n\" +\n \"\u3010\u6B63\u6587\u4E0E\u9020\u578B\u3011\u89D2\u8272\u7684\u65E2\u6709\u670D\u88C5\u7531 characters.states \u548C\u4EBA\u7269\u8D44\u4EA7\u627F\u8F7D\uFF0Cshot.visual \u4E0D\u91CD\u590D\u63CF\u8FF0\u3002\u53EA\u6709\u753B\u9762\u4E2D\u53D1\u751F\u7684\u6362\u88C5\u3001\u8131\u8863\u3001\u670D\u88C5\u7834\u635F\u3001\u6CBE\u67D3\u6CE5\u6C61\u7B49\u53EF\u89C1\u53D8\u5316\uFF0C\u6216\u786E\u6709\u5FC5\u8981\u533A\u5206\u4EBA\u7269/\u65F6\u6BB5\u65F6\u624D\u5199\u5165 shot.visual\u3002\\n\" +\n \"\u3010voices\u3011\u4EBA\u7269\u5BF9\u4ED6\u4EBA\u8BF4\u51FA\u7684\u58F0\u97F3\u5199 kind=dlg\uFF1B\u97F3\u8F68\u91CC\u5B9E\u9645\u542C\u5230\u3001\u660E\u786E\u5C5E\u4E8E\u67D0\u89D2\u8272\u7684\u5185\u5FC3\u72EC\u767D\u6216\u7B2C\u4E00\u4EBA\u79F0\u81EA\u8FF0\u5199 kind=think\u3002speaker \u4F7F\u7528\u89D2\u8272\u89C4\u8303\u540D\uFF1B\u5BA2\u89C2\u53D9\u8FF0\u8005\u6216\u8EAB\u4EFD\u65E0\u6CD5\u786E\u8BA4\u7684\u65C1\u767D\u5199 speaker=\u300Ebroadcast:\u65C1\u767D\u300F\uFF1B\u7535\u8BDD\u3001\u5E7F\u64AD\u6216\u8BBE\u5907\u4E2D\u7684\u660E\u786E\u8BF4\u8BDD\u4EBA\u5728 parenthetical \u6807\u660E\u58F0\u6E90\u3002\u53EA\u8BB0\u5F55\u97F3\u8F68\u5B9E\u9645\u8868\u8FBE\u7684\u5185\u5FC3\uFF0C\u4E0D\u8111\u8865\u672A\u8BF4\u51FA\u7684\u5FC3\u7406\u3002content \u4FDD\u7559\u539F\u8BDD\uFF1Bparenthetical \u53EF\u5199\u53EF\u786E\u8BA4\u7684\u53D1\u58F0\u65B9\u5F0F\u3001\u58F0\u97F3\u6765\u6E90\u6216\u540C\u671F\u77ED\u4FC3\u8868\u6F14\uFF0C\u4F46\u6444\u5F71\u8C03\u5EA6\u548C\u5F71\u54CD\u8FDE\u7EED\u6027\u7684\u52A8\u4F5C\u53EA\u5199 shots\u3002\u5BF9\u767D\u8DE8\u8D8A\u5207\u955C\u3001\u955C\u5934\u4E3B\u4F53\u53D8\u5316\u6216\u72EC\u7ACB\u52A8\u4F5C\u65F6\uFF0C\u5728\u5BF9\u5E94\u65F6\u95F4\u70B9\u6309\u539F\u58F0\u81EA\u7136\u8BED\u53E5\u62C6\u5206\uFF1B\u4E0D\u5F97\u628A\u8DE8\u591A\u4E2A\u955C\u5934\u7684\u591A\u53E5\u53F0\u8BCD\u5408\u5E76\u6210\u4E00\u6761\u3002\u4E24\u4EBA\u540C\u65F6\u8BF4\u8BDD\u65F6\u8F93\u51FA\u76F8\u90BB\u4E24\u6761 voice\uFF0C\u7B2C\u4E8C\u6761 parenthetical \u4EE5\u300E\u540C\u65F6\u300F\u5F00\u5934\u3002\u5177\u4F53\u5355\u4EBA\u4F7F\u7528\u89C4\u8303\u540D\uFF1B\u65E0\u6CD5\u533A\u5206\u6210\u5458\u7684\u4F17\u4EBA\u3001\u7FA4\u4F17\u3001\u8DEF\u4EBA\u7B49\u5171\u540C\u53D1\u58F0\u65F6 speaker \u5199\u300Egroup:\u7FA4\u4F53\u540D\u300F\uFF0C\u4E0D\u5217\u5165 characters \u548C registry_delta\u3002\\n\" +\n \"\u3010\u8499\u592A\u5947\u3011\u540C\u5730\u70B9\u8FDE\u7EED\u8499\u592A\u5947\u4FDD\u7559\u4E00\u573A\uFF1B\u8DE8\u5730\u70B9\u8499\u592A\u5947\u6309\u526A\u8F91\u987A\u5E8F\u62C6\u6210\u591A\u4E2A\u77ED scene\uFF0C\u6BCF\u573A\u7ED1\u5B9A\u81EA\u5DF1\u7684 location\u3001characters\u3001props \u548C state\uFF0C\u5E76\u7528 shots \u660E\u786E\u8499\u592A\u5947\u5F00\u59CB\u3001\u5207\u6362\u548C\u7ED3\u675F\u3002\";\n\nexport function buildSerialUser(episodeNo: number, contextText: string): string {\n const ctx = contextText.trim()\n ? `========== \u5DF2\u77E5\u8BBE\u5B9A\uFF08\u5230\u4E0A\u4E00\u96C6\u4E3A\u6B62\uFF0C\u89C4\u8303\u540D\u4EE5\u6B64\u4E3A\u51C6\uFF09 ==========\\n${contextText}\\n`\n : \"\uFF08\u8FD9\u662F\u7B2C\u4E00\u96C6\uFF0C\u6682\u65E0\u5DF2\u77E5\u8BBE\u5B9A\u3002\uFF09\\n\";\n return `\u89E3\u6790\u7B2C ${episodeNo} \u96C6\uFF1A\u5BF9\u7167\u672C\u96C6\u539F\u89C6\u9891\uFF0C\u6309\u8F93\u51FA schema \u8FD4\u56DE JSON \u5BF9\u8C61\u3002scenes \u9010\u573A\u8986\u76D6\u5168\u96C6\uFF1B\u6BCF\u573A\u5148\u72EC\u7ACB\u5B8C\u6210\u9010\u955C shots\uFF0C\u518D\u72EC\u7ACB\u5B8C\u6210 voices\u3002shots \u5FC5\u987B\u8986\u76D6\u6BCF\u6B21\u5207\u955C\u548C\u53EF\u786E\u8BA4\u7684\u6444\u5F71/\u8868\u6F14\u53D8\u5316\uFF0C\u4E0D\u53BB\u91CD\u91CD\u590D\u955C\u5934\uFF0C\u4E0D\u5408\u5E76\u5148\u540E\u53D1\u751F\u7684\u5206\u955C\u6216\u52A8\u4F5C\uFF1Bvoices \u5B8C\u6574\u4FDD\u7559\u539F\u58F0\u5E76\u5728\u8DE8\u955C\u65F6\u6309\u81EA\u7136\u8BED\u53E5\u62C6\u5206\u3002registry_delta \u53EA\u62A5\u589E\u91CF\uFF08\u5DF2\u77E5\u4E14\u65E0\u65B0\u4FE1\u606F\u7684\u5B9E\u4F53\u4E0D\u8981\u5199\uFF09\u3002\u5B8C\u6210\u524D\u5206\u522B\u590D\u6838 shots \u7684\u5207\u955C\u3001\u666F\u522B/\u89D2\u5EA6/\u8FD0\u955C/\u6784\u56FE/\u7126\u70B9\u3001\u53EF\u89C1\u8868\u6F14\u548C\u7AD9\u4F4D\u5173\u7CFB\uFF0C\u4EE5\u53CA voices \u7684\u5168\u90E8\u4EBA\u58F0\u4E0E\u89C6\u9891\u6700\u540E\u5341\u79D2\u3002\\n\\n${ctx}`;\n}\n\nfunction serialError(message: string, received: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_RUNTIME,\n errorCode: \"INGEST_VIDEO_SERIAL_FAILED\",\n hint: \"Inspect the episode error sidecar and rerun `scriptctl ingest` to resume.\",\n data: { actual: received },\n });\n}\n\n// Gemini occasionally emits a NUL () inside a string (e.g. a garbled dialogue\n// line). It's valid JSON but Postgres text/jsonb can't store it, so a downstream\n// insert of script.json dies with UntranslatableCharacter. NUL is never real content\n// here \u2014 strip it at the source so every consumer stays safe, not just this one DB.\n// (Only NUL: other control chars store fine, and touching surrogates would corrupt\n// legit non-BMP CJK that arrives as valid surrogate pairs.)\nconst stripNul = (parsed: unknown): unknown => {\n if (typeof parsed === \"string\") return parsed.replace(/\\u0000/g, \"\");\n if (Array.isArray(parsed)) return parsed.map(stripNul);\n if (isObj(parsed)) return Object.fromEntries(Object.entries(parsed).map(([k, v]) => [k, stripNul(v)]));\n return parsed;\n};\n\nconst isObj = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst asStr = (v: unknown): string => (typeof v === \"string\" ? v.trim() : \"\");\nconst asArr = (v: unknown): unknown[] => (Array.isArray(v) ? v : []);\n\n// Deterministic backstop for outfit-name pollution the schema description already\n// forbids but a model may still leak: a state must be a bare wardrobe label. Strip\n// everything from the first paren/slash/comma separator on \u2014 `\u9ED1\u4E1D\u77ED\u88D9\uFF08\u8EAB\u7A7F\u6536\u94F6\u77ED\u8896\uFF09`\n// and `\u9ED1\u4E1D\u77ED\u88D9/\u7EF7\u5E26\u77ED\u88D9` both collapse to `\u9ED1\u4E1D\u77ED\u88D9`, folding the ep39/40/17-style\n// fragments back onto the canonical outfit. Empty stays empty (no change this scene).\nconst cleanState = (raw: unknown): string => {\n const s = asStr(raw);\n return s ? s.split(/[\uFF08(\uFF0F/\uFF0C,\u3001]/)[0]!.trim() : \"\";\n};\n\nconst cleanStates = (raw: unknown): string[] => [...new Set(\n asArr(raw).map(cleanState).filter(Boolean),\n)];\n\nconst cleanStateDescriptions = (raw: unknown): SerialStateDescription[] => {\n const states: SerialStateDescription[] = [];\n for (const value of asArr(raw)) {\n if (!isObj(value)) continue;\n const name = cleanState(value.name);\n if (!name) continue;\n const description = asStr(value.description);\n const existing = states.find((state) => state.name === name);\n if (existing) {\n if (!existing.description && description) existing.description = description;\n } else {\n states.push({ name, description });\n }\n }\n return states;\n};\n\nconst IDENTITY_TEXT_KEYS = [\n \"apparent_gender\",\n \"apparent_age\",\n \"face_shape\",\n \"brows_eyes\",\n \"nose\",\n \"mouth\",\n \"skin_features\",\n \"hair\",\n \"build\",\n \"voice\",\n] as const;\n\nconst cleanIdentityProfile = (raw: unknown): SerialIdentityProfile | undefined => {\n if (!isObj(raw)) return undefined;\n const profile: SerialIdentityProfile = {\n apparent_gender: \"\",\n apparent_age: \"\",\n face_shape: \"\",\n brows_eyes: \"\",\n nose: \"\",\n mouth: \"\",\n skin_features: \"\",\n hair: \"\",\n build: \"\",\n persistent_marks: asArr(raw.persistent_marks).map(asStr).filter(Boolean),\n voice: \"\",\n };\n for (const key of IDENTITY_TEXT_KEYS) profile[key] = asStr(raw[key]);\n return profile;\n};\n\nconst timestampSeconds = (timestamp: string | undefined): number => {\n if (!timestamp) return Number.POSITIVE_INFINITY;\n const parts = timestamp.split(\":\").map(Number);\n if (parts.some((part) => !Number.isFinite(part))) return Number.POSITIVE_INFINITY;\n if (parts.length === 2) return parts[0]! * 60 + parts[1]!;\n if (parts.length === 3) return parts[0]! * 3600 + parts[1]! * 60 + parts[2]!;\n return Number.POSITIVE_INFINITY;\n};\n\nconst shotContent = (camera: string, visual: string): string => {\n if (!camera) return visual;\n if (!visual) return camera;\n return `${camera.replace(/[\u3002\uFF01\uFF1F\uFF1B]+$/, \"\")}\u3002${visual}`;\n};\n\n// Structured-output JSON \u2192 SerialOutput. The schema guarantees shape; this is a\n// defensive projection (tolerates missing/wrong-typed fields) that also runs every\n// state through cleanState and re-nests space/time into `environment` the way\n// applyDelta / deltaToDoc expect.\nexport function toSerialOutput(input: unknown): SerialOutput {\n const out: SerialOutput = { synopsis: \"\", scenes: [], registry_delta: { new_entities: [], enrich: [], canonicalize: [] }, open_threads: { opened: [], closed: [] } };\n if (!isObj(input)) return out;\n out.synopsis = asStr(input.synopsis);\n\n for (const s of asArr(input.scenes)) {\n if (!isObj(s)) continue;\n const environment: { space?: string; time?: string } = {};\n const space = asStr(s.space); if (space) environment.space = space;\n const time = normalizeSceneTime(s.time); if (time) environment.time = time;\n const characters = new Map<string, SerialScene[\"characters\"][number]>();\n for (const c of asArr(s.characters)) {\n if (!isObj(c)) continue;\n const name = asStr(c.name);\n if (!name || isCrowdName(name)) continue;\n const character = characters.get(name) ?? { name, states: [] };\n for (const state of cleanStates(c.states)) {\n if (!character.states.includes(state)) character.states.push(state);\n }\n // Retired experiment: evidence fields from Gemini were normalized here.\n // They are intentionally ignored now; final Action timestamps drive the\n // post-ingest evidence pass.\n characters.set(name, character);\n }\n // Props are presence-only (no multi-state refs). Collapse exact/whitespace\n // duplicates the same way characters merge by name \u2014 otherwise finalize's\n // v3 gate rejects `duplicate prop ref` before v4 can fold them.\n const props: string[] = [];\n const seenProps = new Set<string>();\n for (const raw of asArr(s.props).map(asStr).filter(Boolean)) {\n const key = raw.normalize(\"NFC\").replace(/\\s+/g, \" \").trim();\n if (!key || seenProps.has(key)) continue;\n seenProps.add(key);\n props.push(raw.trim());\n }\n const anchors: SerialScene[\"anchors\"] = [];\n for (const shot of asArr(s.shots)) {\n if (!isObj(shot)) continue;\n const content = shotContent(asStr(shot.camera), asStr(shot.visual));\n if (!content) continue;\n const anchor: SerialScene[\"anchors\"][number] = { kind: \"act\", content };\n const ts = normalizeVideoTimestamp(shot.ts); if (ts) anchor.ts = ts;\n anchors.push(anchor);\n }\n for (const voice of asArr(s.voices)) {\n if (!isObj(voice)) continue;\n const kind = asStr(voice.kind);\n if (kind !== \"dlg\" && kind !== \"think\") continue;\n const content = asStr(voice.content);\n if (!content) continue;\n const anchor: SerialScene[\"anchors\"][number] = { kind, content };\n const speaker = asStr(voice.speaker); if (speaker) anchor.speaker = speaker;\n const parenthetical = asStr(voice.parenthetical); if (parenthetical) anchor.parenthetical = parenthetical;\n const ts = normalizeVideoTimestamp(voice.ts); if (ts) anchor.ts = ts;\n anchors.push(anchor);\n }\n anchors.sort((left, right) => {\n const timeDiff = timestampSeconds(left.ts) - timestampSeconds(right.ts);\n if (timeDiff !== 0) return timeDiff;\n if (left.kind === \"act\" && right.kind !== \"act\") return -1;\n if (left.kind !== \"act\" && right.kind === \"act\") return 1;\n return 0;\n });\n const scene: SerialScene = {\n environment,\n characters: [...characters.values()],\n props,\n anchors,\n };\n const timeRange = asStr(s.timeRange); if (timeRange) scene.timeRange = timeRange;\n const location = asStr(s.location); if (location) scene.location = location;\n out.scenes.push(scene);\n }\n\n const rd: Record<string, unknown> = isObj(input.registry_delta) ? input.registry_delta : {};\n for (const e of asArr(rd.new_entities)) {\n if (!isObj(e)) continue;\n const name = asStr(e.name); const kind = asStr(e.kind);\n if (!name || (kind !== \"actor\" && kind !== \"location\" && kind !== \"prop\")) continue;\n if (kind === \"actor\" && isCrowdName(name)) continue;\n const ent: SerialEntity = {\n name,\n kind,\n status: asStr(e.status) === \"provisional\" ? \"provisional\" : \"canonical\",\n importance: asStr(e.importance) === \"background\" ? \"background\" : \"featured\",\n };\n const recognitionAnchors = asArr(e.recognition_anchors).map(asStr).filter(Boolean);\n if (recognitionAnchors.length) ent.recognition_anchors = recognitionAnchors;\n const identityProfile = cleanIdentityProfile(e.identity_profile);\n if (identityProfile) ent.identity_profile = identityProfile;\n const appearance = asStr(e.appearance); if (appearance) ent.appearance = appearance;\n const role = asStr(e.role); if (role) ent.role = role;\n const states = cleanStateDescriptions(e.states); if (states.length) ent.states = states;\n const aliases = asArr(e.aliases).map(asStr).filter(Boolean); if (aliases.length) ent.aliases = aliases;\n out.registry_delta.new_entities.push(ent);\n }\n for (const e of asArr(rd.enrich)) {\n if (!isObj(e)) continue;\n const name = asStr(e.name); if (!name) continue;\n const en: SerialOutput[\"registry_delta\"][\"enrich\"][number] = { name };\n const recognitionAnchors = asArr(e.add_recognition_anchors).map(asStr).filter(Boolean);\n if (recognitionAnchors.length) en.add_recognition_anchors = recognitionAnchors;\n const identityProfile = cleanIdentityProfile(e.identity_profile_patch);\n if (identityProfile) en.identity_profile_patch = identityProfile;\n const appearance = asStr(e.appearance); if (appearance) en.appearance = appearance;\n const role = asStr(e.role); if (role) en.role = role;\n const addA = asArr(e.add_aliases).map(asStr).filter(Boolean); if (addA.length) en.add_aliases = addA;\n const addS = cleanStateDescriptions(e.add_states); if (addS.length) en.add_states = addS;\n if (Object.keys(en).length > 1) out.registry_delta.enrich.push(en);\n }\n for (const r of asArr(rd.canonicalize)) {\n if (!isObj(r)) continue;\n const from = asStr(r.from_name); const canonical = asStr(r.canonical_name);\n if (from && canonical) out.registry_delta.canonicalize.push({ from_name: from, canonical_name: canonical, evidence: asStr(r.evidence) });\n }\n\n const ot: Record<string, unknown> = isObj(input.open_threads) ? input.open_threads : {};\n for (const o of asArr(ot.opened)) { if (!isObj(o)) continue; const text = asStr(o.text); if (text) out.open_threads.opened.push({ text }); }\n for (const c of asArr(ot.closed)) { if (!isObj(c)) continue; const ref = asStr(c.ref); if (ref) out.open_threads.closed.push({ ref }); }\n\n return out;\n}\n\n// Returns the raw JSON text (pretty-printed, persisted for human review) alongside\n// the parsed SerialOutput the pipeline folds into context.\nexport async function runVideoSerial(\n port: TaskVideoPort,\n media: VideoMediaInput,\n episodeNo: number,\n contextText: string,\n fps: number,\n signal?: AbortSignal,\n local?: { path: string; mime: string },\n): Promise<{ md: string; output: SerialOutput }> {\n const response = await port.generate({\n media,\n system: VIDEO_SERIAL_SYSTEM,\n user: buildSerialUser(episodeNo, contextText),\n fps,\n responseJsonSchema: VIDEO_SERIAL_SCHEMA,\n // Lets a cross-provider fallback (Doubao) re-upload the same transcode when the\n // Gemini handle can't be reused. The Gemini path ignores these.\n ...(local ? { localPath: local.path, localMime: local.mime } : {}),\n ...(signal ? { signal } : {}),\n });\n const raw = response.text.trim();\n // A too-short body means a failed/empty generation (\u00A712.3: not retried).\n if (raw.length < 40) throw serialError(`episode ${episodeNo}: serial output too short (finishReason=${response.finishReason})`, [`length: ${raw.length}`]);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw serialError(`episode ${episodeNo}: serial output was not valid JSON (finishReason=${response.finishReason})`, [raw.slice(0, 200)]);\n }\n const clean = stripNul(parsed);\n const output = toSerialOutput(clean);\n if (output.scenes.length === 0) throw serialError(`episode ${episodeNo}: serial output produced no scenes`, [raw.slice(0, 200)]);\n const md = JSON.stringify(clean, null, 2);\n return { md, output };\n}\n", "import { CliError } from \"../../common.js\";\nimport {\n createOperationalFailure,\n parseFailureClassification,\n type FailureClassification,\n type FailureContext,\n type OperationalFailure,\n type ProviderSafetyRating,\n} from \"../../failures.js\";\nimport { LlmTransportError } from \"../../llm/types.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport interface IngestErrorSidecar {\n schema_version: 1;\n unit: { kind: \"episode\"; episode: number };\n phase: string;\n occurred_at: string;\n failure: OperationalFailure;\n attempts: OperationalFailure[];\n}\n\nexport type IngestStatusError = OperationalFailure & {\n pass: string;\n unit: string;\n phase: string;\n attempts: OperationalFailure[];\n};\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction classificationForCliError(error: CliError): FailureClassification {\n switch (error.errorCode) {\n case \"LLM_CREDENTIAL_MISSING\":\n return { failure_type: \"authentication\", failure_code: \"authentication_failed\" };\n case \"LLM_CONFIG_INVALID\":\n return { failure_type: \"provider\", failure_code: \"request_rejected\" };\n case \"INGEST_VIDEO_INLINE_TOO_LARGE\":\n return { failure_type: \"media\", failure_code: \"media_too_large\" };\n case \"INGEST_VIDEO_SERIAL_FAILED\":\n return { failure_type: \"pipeline\", failure_code: \"serial_parse_failed\" };\n case \"INGEST_SOURCE_MISMATCH\":\n return { failure_type: \"pipeline\", failure_code: \"source_mismatch\" };\n case \"INGEST_PIPELINE_MISMATCH\":\n return { failure_type: \"pipeline\", failure_code: \"pipeline_mismatch\" };\n case \"INGEST_VALIDATION_FAILED\":\n return { failure_type: \"validation\", failure_code: \"script_validation_failed\" };\n default:\n return { failure_type: \"unknown\", failure_code: \"unknown\" };\n }\n}\n\nexport function failureFromError(error: unknown): { failure: OperationalFailure; attempts: OperationalFailure[] } {\n if (error instanceof LlmTransportError) {\n return { failure: error.failure, attempts: error.modelFailures };\n }\n if (error instanceof CliError) {\n const retryable = error.errorCode === \"INGEST_VALIDATION_FAILED\";\n return {\n failure: createOperationalFailure(classificationForCliError(error), {\n retryable,\n message: error.message,\n }),\n attempts: [],\n };\n }\n return {\n failure: createOperationalFailure(\n { failure_type: \"unknown\", failure_code: \"unknown\" },\n { retryable: false, message: error instanceof Error ? error.message : String(error) },\n ),\n attempts: [],\n };\n}\n\nexport function createEpisodeErrorSidecar(error: unknown, episode: number, phase: string): IngestErrorSidecar {\n const classified = failureFromError(error);\n return {\n schema_version: 1,\n unit: { kind: \"episode\", episode },\n phase,\n occurred_at: new Date().toISOString(),\n ...classified,\n };\n}\n\nexport function recoveryHint(failure: OperationalFailure): string {\n if (failure.retryable) {\n return \"Inspect the episode error sidecar and rerun `scriptctl ingest` to resume from this episode.\";\n }\n if (failure.failure_type === \"policy\") {\n return \"Inspect the provider policy reason in the episode error sidecar; rerunning the same source is unlikely to help.\";\n }\n if (failure.failure_type === \"authentication\" || failure.failure_type === \"authorization\") {\n return \"Fix the provider credential or permission reported in the episode error sidecar before rerunning.\";\n }\n return \"Inspect the typed episode error sidecar and resolve the terminal failure before rerunning.\";\n}\n\nfunction oneOf<const Values extends readonly string[]>(value: unknown, values: Values): value is Values[number] {\n return typeof value === \"string\" && values.some((candidate) => candidate === value);\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction parseSafetyRatings(value: unknown): ProviderSafetyRating[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const parsed: ProviderSafetyRating[] = [];\n for (const item of value) {\n if (!isRecord(item)) return undefined;\n if (typeof item[\"category\"] !== \"string\" || typeof item[\"probability\"] !== \"string\" || typeof item[\"blocked\"] !== \"boolean\") {\n return undefined;\n }\n parsed.push({ category: item[\"category\"], probability: item[\"probability\"], blocked: item[\"blocked\"] });\n }\n return parsed;\n}\n\nfunction parseFailureContext(value: UnknownRecord): FailureContext {\n const source = value[\"provider_source\"];\n const reason = value[\"provider_reason\"];\n const context: FailureContext = {\n provider: optionalString(value[\"provider\"]),\n model: optionalString(value[\"model\"]),\n operation: optionalString(value[\"operation\"]),\n http_status: typeof value[\"http_status\"] === \"number\" ? value[\"http_status\"] : undefined,\n system_code: optionalString(value[\"system_code\"]),\n provider_source: oneOf(source, [\"prompt\", \"candidate\"] as const) ? source : undefined,\n provider_reason: oneOf(reason, [\n \"SAFETY\", \"PROHIBITED_CONTENT\", \"BLOCKLIST\", \"SPII\", \"RECITATION\", \"IMAGE_SAFETY\",\n \"IMAGE_PROHIBITED_CONTENT\", \"IMAGE_RECITATION\", \"ESCALATION\", \"OTHER\", \"UNSPECIFIED\", \"UNKNOWN\",\n ] as const) ? reason : undefined,\n provider_reason_raw: optionalString(value[\"provider_reason_raw\"]),\n finish_message: optionalString(value[\"finish_message\"]),\n safety_ratings: parseSafetyRatings(value[\"safety_ratings\"]),\n details: Array.isArray(value[\"details\"]) && value[\"details\"].every((detail) => typeof detail === \"string\")\n ? value[\"details\"]\n : undefined,\n };\n return context;\n}\n\nexport function parseOperationalFailure(value: unknown): OperationalFailure | null {\n if (!isRecord(value)) return null;\n const classification = parseFailureClassification(value[\"failure_type\"], value[\"failure_code\"]);\n if (!classification || typeof value[\"retryable\"] !== \"boolean\" || typeof value[\"message\"] !== \"string\") return null;\n return createOperationalFailure(classification, {\n ...parseFailureContext(value),\n retryable: value[\"retryable\"],\n message: value[\"message\"],\n });\n}\n\nexport function parseIngestErrorSidecar(value: unknown): IngestErrorSidecar | null {\n if (!isRecord(value) || value[\"schema_version\"] !== 1) return null;\n const unit = value[\"unit\"];\n if (!isRecord(unit) || unit[\"kind\"] !== \"episode\" || typeof unit[\"episode\"] !== \"number\") return null;\n if (typeof value[\"phase\"] !== \"string\" || typeof value[\"occurred_at\"] !== \"string\") return null;\n const failure = parseOperationalFailure(value[\"failure\"]);\n if (!failure || !Array.isArray(value[\"attempts\"])) return null;\n const attempts: OperationalFailure[] = [];\n for (const item of value[\"attempts\"]) {\n const attempt = parseOperationalFailure(item);\n if (!attempt) return null;\n attempts.push(attempt);\n }\n return {\n schema_version: 1,\n unit: { kind: \"episode\", episode: unit[\"episode\"] },\n phase: value[\"phase\"],\n occurred_at: value[\"occurred_at\"],\n failure,\n attempts,\n };\n}\n", "import { CliError, EXIT_INPUT } from \"../../common.js\";\nimport type { OperationalFailure } from \"../../failures.js\";\nimport { advanceSkippedEpisode, type RunContext } from \"../../domain/ingest/video-context.js\";\nimport type { VideoEpisodeDoc } from \"../../domain/ingest/video-records.js\";\nimport type { ScriptV4 } from \"../../domain/script/v4/types.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\nimport { parseOperationalFailure } from \"./failure.js\";\n\nexport interface VideoSkipRecord {\n episode: number;\n skipped_at: string;\n reason: string;\n source_sha256: string;\n failure: OperationalFailure;\n attempts: OperationalFailure[];\n}\n\nexport interface VideoSkipLedger {\n schema_version: 1;\n episodes: VideoSkipRecord[];\n}\n\nfunction invalidLedger(reason: string): CliError {\n return new CliError(\"The video skip ledger is invalid.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SKIP_LEDGER_INVALID\",\n hint: \"Repair or remove skipped.json, then retry.\",\n data: { actual: [reason] },\n });\n}\n\nfunction parseSkipRecord(value: unknown): VideoSkipRecord | null {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n if (!Number.isInteger(record[\"episode\"]) || Number(record[\"episode\"]) <= 0\n || typeof record[\"skipped_at\"] !== \"string\"\n || typeof record[\"reason\"] !== \"string\" || record[\"reason\"].trim().length === 0\n || typeof record[\"source_sha256\"] !== \"string\" || record[\"source_sha256\"].length === 0\n || !Array.isArray(record[\"attempts\"])) return null;\n const failure = parseOperationalFailure(record[\"failure\"]);\n if (!failure) return null;\n const attempts: OperationalFailure[] = [];\n for (const value of record[\"attempts\"]) {\n const attempt = parseOperationalFailure(value);\n if (!attempt) return null;\n attempts.push(attempt);\n }\n return {\n episode: Number(record[\"episode\"]),\n skipped_at: record[\"skipped_at\"],\n reason: record[\"reason\"],\n source_sha256: record[\"source_sha256\"],\n failure,\n attempts,\n };\n}\n\nexport function readVideoSkipLedger(store: WorkspaceStore): VideoSkipLedger {\n if (!store.has(\"skipped.json\")) return { schema_version: 1, episodes: [] };\n const value: unknown = store.readJson(\"skipped.json\");\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) throw invalidLedger(\"root must be an object\");\n const ledger = value as Record<string, unknown>;\n if (ledger[\"schema_version\"] !== 1 || !Array.isArray(ledger[\"episodes\"])) {\n throw invalidLedger(\"schema_version must be 1 and episodes must be an array\");\n }\n const episodes: VideoSkipRecord[] = [];\n const seen = new Set<number>();\n for (const value of ledger[\"episodes\"]) {\n const record = parseSkipRecord(value);\n if (!record) throw invalidLedger(\"one or more episode records are malformed\");\n if (seen.has(record.episode)) throw invalidLedger(`episode ${record.episode} appears more than once`);\n seen.add(record.episode);\n episodes.push(record);\n }\n episodes.sort((left, right) => left.episode - right.episode);\n return { schema_version: 1, episodes };\n}\n\nexport function writeVideoSkipLedger(store: WorkspaceStore, ledger: VideoSkipLedger): void {\n store.writeJson(\"skipped.json\", ledger);\n}\n\nexport function assertVideoSkipSources(\n skips: readonly VideoSkipRecord[],\n sourceEpisodes: ReadonlyArray<{ episode: number; sha256: string }>,\n): void {\n const sourceByEpisode = new Map(sourceEpisodes.map((episode) => [episode.episode, episode.sha256]));\n for (const record of skips) {\n const sourceSha256 = sourceByEpisode.get(record.episode);\n if (sourceSha256 === record.source_sha256) continue;\n throw new CliError(\"The video skip ledger no longer matches the source.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"INGEST_SKIP_SOURCE_MISMATCH\",\n hint: \"Restore the source episode recorded by this workspace, or rebuild the same source with --force.\",\n data: {\n actual: [\n `episode=${record.episode}`,\n `ledger_sha256=${record.source_sha256}`,\n `source_sha256=${sourceSha256 ?? \"<missing>\"}`,\n ],\n },\n });\n }\n}\n\nexport function skippedEpisodeDoc(episode: number): VideoEpisodeDoc {\n return {\n episode,\n synopsis: \"\",\n scenes: [],\n actors: [],\n locations: [],\n props: [],\n speakers: [],\n actorStates: [],\n locationStates: [],\n propStates: [],\n };\n}\n\nexport function readAcceptedVideoDocs(\n store: WorkspaceStore,\n episodes: ReadonlyArray<{ episode: number }>,\n acceptedThrough: number,\n skips: readonly VideoSkipRecord[],\n): VideoEpisodeDoc[] {\n const skipped = new Set(skips.map((record) => record.episode));\n const docs: VideoEpisodeDoc[] = [];\n for (const episode of episodes) {\n if (episode.episode > acceptedThrough) break;\n const rel = `ep/ep_${String(episode.episode).padStart(3, \"0\")}.json`;\n if (store.has(rel)) docs.push(store.readJson<VideoEpisodeDoc>(rel));\n else if (skipped.has(episode.episode)) docs.push(skippedEpisodeDoc(episode.episode));\n }\n return docs;\n}\n\nexport function reconcileVideoSkips(\n store: WorkspaceStore,\n ctx: RunContext,\n skips: readonly VideoSkipRecord[],\n): RunContext {\n for (const record of skips) {\n if (record.episode <= ctx.lastEpisode) {\n store.clearError(`ep/ep_${String(record.episode).padStart(3, \"0\")}.error.json`);\n }\n }\n const byEpisode = new Map(skips.map((record) => [record.episode, record]));\n for (;;) {\n const next = ctx.lastEpisode + 1;\n if (!byEpisode.has(next)) break;\n advanceSkippedEpisode(ctx, next);\n store.writeJson(\"context.json\", ctx);\n store.clearError(`ep/ep_${String(next).padStart(3, \"0\")}.error.json`);\n }\n return ctx;\n}\n\nexport function markSkippedEpisodes(script: ScriptV4, skips: readonly VideoSkipRecord[]): void {\n for (const record of skips) {\n const episode = script.episodes[record.episode - 1];\n if (!episode) continue;\n episode.extend = {\n scriptctl: {\n ingest: {\n outcome: \"skipped\",\n source_episode: record.episode,\n },\n },\n };\n }\n}\n", "// `scriptctl ingest status` \u2014 derives ingest progress from the workspace's REAL\n// file state (\u00A75.3), never from a separate state-machine file. The pipeline\n// already treats the workspace as its source of truth (resume = \"what's on\n// disk\"), so status is a pure function of the files: no run_state.json to drift\n// out of sync. This is the one authoritative status derivation \u2014 the runtime\n// watcher and frontend consume this via `--json` instead of re-deriving it.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { EXIT_OK, type CommandOutput } from \"../../common.js\";\nimport {\n createOperationalFailure,\n type FailureType,\n} from \"../../failures.js\";\nimport type { ScriptV4 } from \"../../domain/script/v4/types.js\";\nimport {\n parseIngestErrorSidecar,\n type IngestErrorSidecar,\n type IngestStatusError,\n} from \"./failure.js\";\nimport { summarizeTimings, type IngestTimings, type TimingSummary } from \"./timings.js\";\nimport type { VideoSkipRecord } from \"./video-skip-state.js\";\n\ntype Dict = Record<string, unknown>;\nconst strOf = (v: unknown): string => (v === null || v === undefined ? \"\" : String(v));\n\nexport type IngestKind = \"text\" | \"video\";\nexport type IngestState = \"empty\" | \"incomplete\" | \"failed\" | \"ready\";\n\nexport interface IngestUnit {\n total: number;\n done: number;\n failed: number;\n}\n\nexport interface IngestPass {\n name: string;\n done: boolean;\n unit?: IngestUnit;\n}\n\nexport interface IngestFailureSummary {\n total: number;\n retryable: number;\n terminal: number;\n by_type: Partial<Record<FailureType, number>>;\n}\n\nexport interface IngestSkipSummary {\n episode: number;\n skipped_at: string;\n reason: string;\n failure_type: FailureType;\n failure_code: string;\n}\n\nexport interface IngestStatus {\n workspace: string;\n exists: boolean;\n kind: IngestKind | null;\n state: IngestState;\n phase: string;\n passes: IngestPass[];\n units: IngestUnit | null; // primary units (chunks / episodes) for a coarse bar\n script: boolean;\n validation: { ok: boolean; errors: number; warnings: number } | null;\n failure_summary: IngestFailureSummary;\n errors: IngestStatusError[];\n updated: string | null;\n // Real wall-clock timing of the current/last run (elapsed, per-phase, serial ETA);\n // null before the first run writes timings.json.\n timings: TimingSummary | null;\n completed?: number;\n remaining?: number;\n complete?: boolean;\n next_episode?: number | null;\n parsed?: number;\n skipped?: number;\n skipped_episodes?: number[];\n has_skips?: boolean;\n skips?: IngestSkipSummary[];\n}\n\nfunction readTimings(root: string): TimingSummary | null {\n try {\n const t = JSON.parse(fs.readFileSync(path.join(root, \"timings.json\"), \"utf-8\")) as IngestTimings;\n return summarizeTimings(t, Date.now());\n } catch {\n return null;\n }\n}\n\ninterface Manifest {\n updated?: string;\n source?: { kind?: string };\n chunks?: number;\n episodes?: unknown[];\n current_error?: IngestErrorSidecar;\n skips?: VideoSkipRecord[];\n}\n\n// List files directly under a pass dir matching a suffix (non-recursive).\nfunction listSuffix(root: string, dir: string, suffix: string): string[] {\n const abs = path.join(root, dir);\n let names: string[];\n try {\n names = fs.readdirSync(abs);\n } catch {\n return [];\n }\n return names.filter((n) => n.endsWith(suffix)).sort();\n}\n\nconst countSuffix = (root: string, dir: string, suffix: string): number => listSuffix(root, dir, suffix).length;\nconst has = (root: string, rel: string): boolean => fs.existsSync(path.join(root, rel));\n\nfunction readManifest(root: string): Manifest | null {\n try {\n return JSON.parse(fs.readFileSync(path.join(root, \"manifest.json\"), \"utf-8\")) as Manifest;\n } catch {\n return null;\n }\n}\n\nfunction readValidation(root: string): IngestStatus[\"validation\"] {\n try {\n const v = JSON.parse(fs.readFileSync(path.join(root, \"validation.json\"), \"utf-8\")) as {\n ok?: boolean;\n errors?: unknown[];\n warnings?: unknown[];\n };\n return { ok: Boolean(v.ok), errors: v.errors?.length ?? 0, warnings: v.warnings?.length ?? 0 };\n } catch {\n return null;\n }\n}\n\nfunction legacyError(pass: string, unit: string, message: string): IngestStatusError {\n // Text pass2 sidecars are checkpointed normalization-unit failures whose\n // established recovery contract is to rerun that unit. Old video sidecars do\n // not carry enough information to determine retryability without guessing.\n const retryable = pass === \"pass2\";\n return {\n pass,\n unit,\n phase: pass,\n attempts: [],\n ...createOperationalFailure(\n { failure_type: \"unknown\", failure_code: \"legacy_unclassified\" },\n { retryable, message },\n ),\n };\n}\n\n// Collect the error sidecars a failed run leaves behind (cleared on unit success).\nfunction readError(root: string, pass: string, unit: string): IngestStatusError {\n try {\n const value: unknown = JSON.parse(fs.readFileSync(path.join(root, pass, `${unit}.error.json`), \"utf-8\"));\n const sidecar = parseIngestErrorSidecar(value);\n if (sidecar) {\n return {\n pass,\n unit,\n phase: sidecar.phase,\n attempts: sidecar.attempts,\n ...sidecar.failure,\n };\n }\n if (typeof value === \"object\" && value !== null && \"error\" in value && typeof value.error === \"string\") {\n return legacyError(pass, unit, value.error);\n }\n return legacyError(pass, unit, \"Error sidecar has an unsupported schema.\");\n } catch {\n return legacyError(pass, unit, \"Error sidecar is unreadable.\");\n }\n}\n\nfunction collectErrors(root: string, pass: string, ignoredUnits: ReadonlySet<string> = new Set()): IngestStatusError[] {\n return listSuffix(root, pass, \".error.json\")\n .map((name) => name.replace(/\\.error\\.json$/, \"\"))\n .filter((unit) => !ignoredUnits.has(unit))\n .map((unit) => readError(root, pass, unit));\n}\n\nfunction currentVideoError(\n manifest: Manifest,\n acceptedEpisodes: number,\n ignoredUnits: ReadonlySet<string>,\n): IngestStatusError[] {\n const sidecar = parseIngestErrorSidecar(manifest.current_error);\n if (!sidecar) return [];\n const unit = `ep_${String(sidecar.unit.episode).padStart(3, \"0\")}`;\n if (sidecar.unit.episode <= acceptedEpisodes || ignoredUnits.has(unit)) return [];\n return [{\n pass: \"ep\",\n unit,\n phase: sidecar.phase,\n attempts: sidecar.attempts,\n ...sidecar.failure,\n }];\n}\n\nfunction summarizeFailures(errors: IngestStatusError[]): IngestFailureSummary {\n const by_type: Partial<Record<FailureType, number>> = {};\n for (const error of errors) by_type[error.failure_type] = (by_type[error.failure_type] ?? 0) + 1;\n const retryable = errors.filter((error) => error.retryable).length;\n return { total: errors.length, retryable, terminal: errors.length - retryable, by_type };\n}\n\n// Episode count for the serial pass bar; derived from the assembled body.\nfunction readEpisodeCount(root: string): number {\n try {\n const s = JSON.parse(fs.readFileSync(path.join(root, \"body.json\"), \"utf-8\")) as { episodes?: unknown[] };\n return Array.isArray(s.episodes) ? s.episodes.length : 0;\n } catch {\n return 0;\n }\n}\n\nfunction readFinalizedVideoEpisodeCount(root: string): number | null {\n try {\n const script = JSON.parse(fs.readFileSync(path.join(root, \"script.json\"), \"utf-8\")) as ScriptV4;\n return script.version === 4 && Array.isArray(script.episodes) ? script.episodes.length : null;\n } catch {\n return null;\n }\n}\n\nfunction readAcceptedVideoEpisodeCount(root: string, total: number): number {\n try {\n const context = JSON.parse(fs.readFileSync(path.join(root, \"context.json\"), \"utf-8\")) as { lastEpisode?: unknown };\n return typeof context.lastEpisode === \"number\" && Number.isInteger(context.lastEpisode)\n ? Math.min(Math.max(context.lastEpisode, 0), total)\n : 0;\n } catch {\n return 0;\n }\n}\n\nfunction textPasses(root: string, manifest: Manifest): { passes: IngestPass[]; units: IngestUnit } {\n const total = manifest.chunks ?? 0;\n const normalize: IngestUnit = {\n total,\n done: listSuffix(root, \"pass2\", \".json\").filter((name) => /^chunk_\\d+\\.json$/.test(name)).length,\n failed: countSuffix(root, \"pass2\", \".error.json\"),\n };\n // Serial govern: one `serial/win_<start>_<end>.json` per finished window (a window\n // covers 1+ contiguous episodes). Progress = episodes covered = sum of ranges.\n const epTotal = readEpisodeCount(root);\n const serialDone = listSuffix(root, \"serial\", \".json\").reduce((n, name) => {\n const m = name.match(/^win_(\\d+)_(\\d+)\\.json$/);\n return m ? n + (Number(m[2]) - Number(m[1]) + 1) : n;\n }, 0);\n const serial: IngestUnit = { total: epTotal, done: serialDone, failed: 0 };\n const passes: IngestPass[] = [\n { name: \"normalize\", done: total > 0 && normalize.done >= total && normalize.failed === 0, unit: normalize },\n { name: \"assemble\", done: has(root, \"body.json\") },\n { name: \"serial\", done: epTotal > 0 && serialDone >= epTotal, unit: serial },\n { name: \"govern\", done: has(root, \"script.json\") },\n ];\n return { passes, units: normalize };\n}\n\nfunction videoPasses(\n root: string,\n manifest: Manifest,\n skips: readonly VideoSkipRecord[],\n acceptedPrefix: number,\n failedEpisodes: number,\n): { passes: IngestPass[]; units: IngestUnit; parsed: number } {\n const total = manifest.episodes?.length ?? 0;\n const parsed = acceptedPrefix - skips.filter((record) => record.episode <= acceptedPrefix).length;\n // context.json is the authoritative acceptance checkpoint. An episode JSON\n // written immediately before a crash is retried unless context includes it.\n const serial: IngestUnit = {\n total,\n done: acceptedPrefix,\n failed: failedEpisodes,\n };\n const passes: IngestPass[] = [\n { name: \"serial\", done: total > 0 && serial.done >= total && serial.failed === 0, unit: serial },\n { name: \"finalize\", done: acceptedPrefix >= total && readFinalizedVideoEpisodeCount(root) === acceptedPrefix },\n ];\n return { passes, units: serial, parsed };\n}\n\nexport function deriveIngestStatus(workspacePath: string): IngestStatus {\n const root = path.resolve(workspacePath);\n const manifest = readManifest(root);\n if (!manifest) {\n return {\n workspace: root, exists: false, kind: null, state: \"empty\", phase: \"none\",\n passes: [], units: null, script: false, validation: null,\n failure_summary: summarizeFailures([]), errors: [], updated: null, timings: null,\n };\n }\n const kind: IngestKind = manifest.source?.kind === \"text\" ? \"text\" : \"video\";\n const videoTotal = manifest.episodes?.length ?? 0;\n const acceptedVideoEpisodes = kind === \"video\" ? readAcceptedVideoEpisodeCount(root, videoTotal) : 0;\n const videoIncomplete = kind === \"video\" && acceptedVideoEpisodes < videoTotal;\n const skipRecords = kind === \"video\" ? manifest.skips ?? [] : [];\n const skippedUnits = new Set(skipRecords.map((record) => `ep_${String(record.episode).padStart(3, \"0\")}`));\n const videoErrors = kind === \"video\" && acceptedVideoEpisodes < videoTotal\n ? currentVideoError(manifest, acceptedVideoEpisodes, skippedUnits)\n : [];\n const video = kind === \"video\"\n ? videoPasses(root, manifest, skipRecords, acceptedVideoEpisodes, videoErrors.length)\n : null;\n const { passes, units } = kind === \"text\" ? textPasses(root, manifest) : video!;\n\n const errors = kind === \"text\" ? collectErrors(root, \"pass2\") : videoErrors;\n\n if (videoIncomplete) {\n const acceptedSkips = skipRecords.filter((record) => record.episode <= acceptedVideoEpisodes);\n return {\n workspace: root,\n exists: true,\n kind,\n state: errors.length > 0 ? \"failed\" : \"incomplete\",\n phase: \"serial\",\n passes,\n units,\n script: acceptedVideoEpisodes > 0,\n validation: null,\n failure_summary: summarizeFailures(errors),\n errors,\n updated: manifest.updated ?? null,\n timings: null,\n completed: acceptedVideoEpisodes,\n remaining: videoTotal - acceptedVideoEpisodes,\n complete: false,\n next_episode: acceptedVideoEpisodes + 1,\n parsed: video?.parsed ?? acceptedVideoEpisodes,\n skipped: acceptedSkips.length,\n skipped_episodes: skipRecords.map((record) => record.episode),\n has_skips: skipRecords.length > 0,\n skips: skipRecords.map((record) => ({\n episode: record.episode,\n skipped_at: record.skipped_at,\n reason: record.reason,\n failure_type: record.failure.failure_type,\n failure_code: record.failure.failure_code,\n })),\n };\n }\n\n const script = has(root, \"script.json\");\n const validation = readValidation(root);\n if (validation && !validation.ok) {\n errors.push({\n pass: \"finalize\",\n unit: \"script\",\n phase: \"validation\",\n attempts: [],\n ...createOperationalFailure(\n { failure_type: \"validation\", failure_code: \"script_validation_failed\" },\n { retryable: false, message: `Script validation failed with ${validation.errors} error(s).` },\n ),\n });\n }\n\n // State is a pure fold over the files: a final valid script is `ready`; a\n // hard error (validation failed OR leftover unit error sidecars) is `failed`;\n // otherwise the run started but didn't finish (`incomplete`). Liveness (is a\n // process still running?) is deliberately NOT here \u2014 it can't be read from\n // files; that's the watcher's / agent's concern.\n let state: IngestState;\n const allPassesDone = passes.length > 0 && passes.every((pass) => pass.done);\n if ((kind === \"text\" || allPassesDone) && script && validation?.ok) state = \"ready\";\n else if (errors.length > 0 || (validation && !validation.ok)) state = \"failed\";\n else state = \"incomplete\";\n\n const firstPending = passes.find((p) => !p.done);\n const phase = state === \"ready\" ? \"done\" : firstPending ? firstPending.name : \"done\";\n\n const videoProgress = kind === \"video\"\n ? {\n completed: units.done,\n remaining: Math.max(0, units.total - units.done),\n complete: units.total > 0 && units.done >= units.total && units.failed === 0,\n next_episode: units.done >= units.total ? null : units.done + 1,\n parsed: video?.parsed ?? 0,\n skipped: skipRecords.filter((record) => record.episode <= units.done).length,\n skipped_episodes: skipRecords.map((record) => record.episode),\n has_skips: skipRecords.length > 0,\n skips: skipRecords.map((record) => ({\n episode: record.episode,\n skipped_at: record.skipped_at,\n reason: record.reason,\n failure_type: record.failure.failure_type,\n failure_code: record.failure.failure_code,\n })),\n }\n : {};\n\n return {\n workspace: root, exists: true, kind, state, phase, passes, units,\n script, validation, failure_summary: summarizeFailures(errors), errors,\n updated: manifest.updated ?? null, timings: readTimings(root),\n ...videoProgress,\n };\n}\n\nfunction unitStr(u: IngestUnit): string {\n const base = `${u.done}/${u.total}`;\n return u.failed > 0 ? `${base} (${u.failed} failed)` : base;\n}\n\nfunction humanLines(s: IngestStatus): string[] {\n if (!s.exists) return [`no ingest workspace at ${s.workspace}`];\n const head = `${s.kind} ingest: ${s.state} (phase=${s.phase})`;\n const passLine = s.passes.map((p) => `${p.name} ${p.unit ? unitStr(p.unit) : p.done ? \"\u2713\" : \"-\"}`).join(\" \");\n const lines = [head, passLine];\n if (s.timings) lines.push(timingLine(s.timings));\n if (s.validation) lines.push(`validation: ${s.validation.ok ? \"ok\" : `${s.validation.errors} errors`}, ${s.validation.warnings} warnings`);\n if (s.has_skips) lines.push(`skipped episodes: ${s.skipped_episodes?.join(\", \")}`);\n if (s.state === \"failed\") {\n for (const error of s.errors.slice(0, 3)) {\n lines.push(`${error.unit}: ${error.failure_type}/${error.failure_code} \u00B7 ${error.retryable ? \"retryable\" : \"terminal\"}`);\n }\n if (s.failure_summary.retryable > 0) lines.push(\"rerun `scriptctl ingest` to resume retryable failures\");\n if ((s.failure_summary.by_type.policy ?? 0) > 0) lines.push(\"provider policy blocked the source; rerunning the same source is unlikely to help\");\n if ((s.failure_summary.by_type.authentication ?? 0) > 0 || (s.failure_summary.by_type.authorization ?? 0) > 0) {\n lines.push(\"check provider credentials and permissions before rerunning\");\n }\n }\n return lines;\n}\n\nfunction fmtDur(ms: number): string {\n const s = Math.round(ms / 1000);\n return s >= 60 ? `${Math.floor(s / 60)}m${String(s % 60).padStart(2, \"0\")}s` : `${s}s`;\n}\n\nfunction timingLine(t: TimingSummary): string {\n const parts = [`elapsed ${fmtDur(t.elapsedMs)}${t.done ? \"\" : \" (running)\"}`];\n const ser = t.serial;\n if (ser) {\n parts.push(`serial ${ser.doneWindows}/${ser.totalWindows} windows (${ser.doneEpisodes}/${ser.totalEpisodes} eps)`);\n if (ser.avgWindowMs != null) parts.push(`~${fmtDur(ser.avgWindowMs)}/window`);\n if (ser.etaMs != null && !t.done) parts.push(`eta ~${fmtDur(ser.etaMs)}`);\n }\n return parts.join(\" \u00B7 \");\n}\n\nexport function commandIngestStatus(opts: Dict): [CommandOutput, number] {\n const workspacePath = strOf(opts[\"workspace_path\"] || \"workspace\");\n const status = deriveIngestStatus(workspacePath);\n return [{ text: humanLines(status).join(\"\\n\"), data: { status } }, EXIT_OK];\n}\n", "import * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT, EXIT_OK, type CommandOutput } from \"../../common.js\";\nimport { emptyContext, type RunContext } from \"../../domain/ingest/video-context.js\";\nimport { emptyV4IdentityMap, type V4IdentityMap } from \"../../domain/script/v4/from-v3.js\";\nimport { withIngestWorkspaceLock } from \"../../infra/ingest/workspace-lock.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\nimport { parseIngestErrorSidecar } from \"./failure.js\";\nimport { deriveIngestStatus } from \"./status.js\";\nimport {\n deriveVideoTitle,\n migrateVideoManifest,\n publishFinalizedVideoWorkspace,\n readCurrentVideoManifest,\n} from \"./video-pipeline.js\";\nimport {\n assertVideoSkipSources,\n readVideoSkipLedger,\n reconcileVideoSkips,\n writeVideoSkipLedger,\n type VideoSkipRecord,\n} from \"./video-skip-state.js\";\n\ntype Dict = Record<string, unknown>;\n\nfunction inputError(message: string, code: string, hint: string, actual: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: code,\n hint,\n data: { actual },\n });\n}\n\nfunction episodeOf(value: unknown): number {\n const episode = Number(value);\n if (!Number.isInteger(episode) || episode <= 0) {\n throw inputError(\"--episode must be a positive integer.\", \"INGEST_SKIP_EPISODE_INVALID\", \"Pass the current next_episode from `scriptctl ingest status`.\", [String(value)]);\n }\n return episode;\n}\n\nasync function skipVideoEpisodeUnlocked(workspacePath: string, episode: number, reason: string): Promise<boolean> {\n const store = new WorkspaceStore(workspacePath);\n if (!store.has(\"manifest.json\")) {\n throw inputError(\"The ingest workspace does not exist.\", \"INGEST_SKIP_WORKSPACE_MISSING\", \"Run video ingest first, then retry the failed episode or skip it.\", [workspacePath]);\n }\n const header = store.readJson<{ source?: { kind?: string } }>(\"manifest.json\");\n if (header.source?.kind === \"text\") {\n throw inputError(\"Only video ingest episodes can be skipped.\", \"INGEST_SKIP_WRONG_PIPELINE\", \"Use skip only with a video ingest workspace.\", [workspacePath]);\n }\n const manifest = readCurrentVideoManifest(store);\n if (!manifest) {\n throw inputError(\"The video ingest manifest is missing.\", \"INGEST_SKIP_WORKSPACE_MISSING\", \"Run video ingest first.\", [workspacePath]);\n }\n const sourceEpisode = manifest.episodes.find((candidate) => candidate.episode === episode);\n if (!sourceEpisode) {\n throw inputError(\"The requested episode is not in the video source.\", \"INGEST_SKIP_EPISODE_NOT_FOUND\", \"Pass an episode listed in manifest.json.\", [`episode=${episode}`]);\n }\n\n const ledger = readVideoSkipLedger(store);\n assertVideoSkipSources(ledger.episodes, manifest.episodes);\n let ctx: RunContext = store.has(\"context.json\") ? store.readJson<RunContext>(\"context.json\") : emptyContext();\n const existing = ledger.episodes.find((record) => record.episode === episode);\n if (existing) {\n const currentManifest = migrateVideoManifest(store, manifest);\n ctx = reconcileVideoSkips(store, ctx, ledger.episodes);\n const identityMap = store.has(\"v4_identity_map.json\")\n ? store.readJson<V4IdentityMap>(\"v4_identity_map.json\")\n : emptyV4IdentityMap();\n publishFinalizedVideoWorkspace(store, currentManifest.episodes, ctx, deriveVideoTitle(currentManifest.source.path), identityMap, ledger.episodes);\n return false;\n }\n\n const nextEpisode = ctx.lastEpisode + 1;\n if (episode !== nextEpisode) {\n throw inputError(\n \"Only the next unresolved video episode can be skipped.\",\n \"INGEST_SKIP_NOT_NEXT\",\n \"Read status.next_episode and skip exactly that episode.\",\n [`requested=${episode}`, `next_episode=${nextEpisode}`],\n );\n }\n const episodeRel = `ep/ep_${String(episode).padStart(3, \"0\")}`;\n if (store.has(`${episodeRel}.json`)) {\n throw inputError(\"A parsed episode cannot be skipped.\", \"INGEST_SKIP_ALREADY_PARSED\", \"Continue ingest from the next unresolved episode.\", [`episode=${episode}`]);\n }\n if (!store.has(`${episodeRel}.error.json`)) {\n throw inputError(\n \"The episode has no recorded ingest failure.\",\n \"INGEST_SKIP_FAILURE_REQUIRED\",\n \"Run ingest for this episode first; a typed error sidecar is required before manual skip.\",\n [`episode=${episode}`],\n );\n }\n const sidecar = parseIngestErrorSidecar(store.readJson(`${episodeRel}.error.json`));\n if (!sidecar || sidecar.unit.episode !== episode) {\n throw inputError(\n \"The episode error sidecar is invalid.\",\n \"INGEST_SKIP_FAILURE_INVALID\",\n \"Regenerate the typed failure by rerunning video ingest.\",\n [`${episodeRel}.error.json`],\n );\n }\n\n const record: VideoSkipRecord = {\n episode,\n skipped_at: new Date().toISOString(),\n reason,\n source_sha256: sourceEpisode.sha256,\n failure: sidecar.failure,\n attempts: sidecar.attempts,\n };\n const currentManifest = migrateVideoManifest(store, manifest);\n const updatedSkips = [...ledger.episodes, record];\n store.writeJson(\"manifest.json\", {\n ...currentManifest,\n updated: record.skipped_at,\n current_error: undefined,\n skips: updatedSkips,\n });\n writeVideoSkipLedger(store, { schema_version: 1, episodes: updatedSkips });\n ctx = reconcileVideoSkips(store, ctx, updatedSkips);\n const identityMap = store.has(\"v4_identity_map.json\")\n ? store.readJson<V4IdentityMap>(\"v4_identity_map.json\")\n : emptyV4IdentityMap();\n publishFinalizedVideoWorkspace(\n store,\n currentManifest.episodes,\n ctx,\n deriveVideoTitle(currentManifest.source.path),\n identityMap,\n [...ledger.episodes, record],\n );\n return true;\n}\n\nexport async function commandSkipVideoEpisode(opts: Dict): Promise<[CommandOutput, number]> {\n const workspacePath = path.resolve(typeof opts[\"workspace_path\"] === \"string\" ? opts[\"workspace_path\"] : \"workspace\");\n const episode = episodeOf(opts[\"episode\"]);\n const reason = typeof opts[\"reason\"] === \"string\" ? opts[\"reason\"].trim() : \"\";\n if (!reason) {\n throw inputError(\"--reason is required.\", \"INGEST_SKIP_REASON_REQUIRED\", \"Record why this episode cannot be parsed.\", [\"--reason <text>\"]);\n }\n const changed = await withIngestWorkspaceLock(workspacePath, () => skipVideoEpisodeUnlocked(workspacePath, episode, reason));\n const status = deriveIngestStatus(workspacePath);\n const skippedEpisodes = readVideoSkipLedger(new WorkspaceStore(workspacePath)).episodes.map((record) => record.episode);\n return [{\n text: changed\n ? `Episode ${episode} skipped; ingest can continue at episode ${status.next_episode ?? \"end\"}.`\n : `Episode ${episode} was already skipped; no changes made.`,\n data: {\n workspace: workspacePath,\n episode,\n changed,\n skipped_episodes: skippedEpisodes,\n complete: status.complete ?? false,\n next_episode: status.next_episode ?? null,\n script_path: path.join(workspacePath, \"script.json\"),\n },\n }, EXIT_OK];\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\n\nimport {\n CliError,\n EXIT_INPUT,\n EXIT_OK,\n sha256Text,\n scriptJsonPath,\n type CommandOutput,\n} from \"../../common.js\";\nimport { emptyContext } from \"../../domain/ingest/video-context.js\";\nimport { buildVideoStateEvidencePlan } from \"../../domain/ingest/video-state-evidence.js\";\nimport {\n validateContinuousEpisodeSequence,\n type VideoSourceEpisodeIdentity,\n} from \"../../domain/ingest/video-source-evolution.js\";\nimport { videoSourceFingerprint } from \"../../infra/ingest/video-source-snapshot.js\";\nimport { requireScriptV4 } from \"../../domain/script/v4/parse.js\";\nimport { discoverEpisodes } from \"../../infra/ingest/video-discovery.js\";\nimport {\n materializeVideoStateEvidence,\n type VideoFrameExtractor,\n} from \"../../infra/ingest/video-state-evidence.js\";\nimport { resolveSource } from \"../../infra/ingest/source-resolver.js\";\nimport { withIngestWorkspaceLock } from \"../../infra/ingest/workspace-lock.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport interface GenerateVideoStateEvidenceInput {\n scriptPath: string;\n sourcePath: string;\n workspacePath: string;\n force?: boolean;\n signal?: AbortSignal;\n extractor?: VideoFrameExtractor;\n}\n\nexport interface GenerateVideoStateEvidenceResult {\n output: string;\n states: number;\n identities: number;\n samples: number;\n ready: number;\n unavailable: number;\n sourceSha256: string;\n}\n\nfunction inputError(message: string, code: string, hint: string, actual: string[]): CliError {\n return new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: code,\n hint,\n data: { actual },\n });\n}\n\n/**\n * Build cheap source identities from NAS metadata. This command only needs to\n * invalidate a derived frame cache; it must not reread every video byte merely\n * to calculate a cryptographic content digest before ffmpeg can seek into it.\n */\nfunction sourceIdentities(sourcePath: string): VideoSourceEpisodeIdentity[] {\n const episodes = discoverEpisodes(resolveSource(sourcePath));\n const sequenceError = validateContinuousEpisodeSequence(episodes);\n if (sequenceError) {\n throw inputError(\n \"Video episode files are not a continuous 1..N sequence.\",\n \"EVIDENCE_VIDEO_SEQUENCE_INVALID\",\n \"Rename the linked videos so every script episode has one matching numbered file.\",\n [sequenceError],\n );\n }\n return episodes.map((episode) => {\n const absolutePath = path.resolve(episode.path);\n const stat = fs.statSync(absolutePath);\n const sizeBytes = stat.size;\n const mtimeMs = Math.trunc(stat.mtimeMs);\n const probe = spawnSync(\"ffprobe\", [\n \"-v\", \"error\",\n \"-show_entries\", \"format=duration\",\n \"-of\", \"default=noprint_wrappers=1:nokey=1\",\n absolutePath,\n ], { encoding: \"utf-8\" });\n const durationSeconds = Number(probe.stdout.trim());\n const durationMs = probe.status === 0 && Number.isFinite(durationSeconds) && durationSeconds > 0\n ? Math.round(durationSeconds * 1_000)\n : undefined;\n return {\n episode: episode.episode,\n path: absolutePath,\n ext: episode.ext,\n mime: episode.mime,\n // The field name is retained for the existing evidence contract. For\n // this post-process its value intentionally fingerprints stable metadata.\n sha256: sha256Text(JSON.stringify({ absolutePath, sizeBytes, mtimeMs })),\n size_bytes: sizeBytes,\n mtime_ms: mtimeMs,\n duration_ms: durationMs,\n };\n });\n}\n\nexport async function generateVideoStateEvidence(\n input: GenerateVideoStateEvidenceInput,\n): Promise<GenerateVideoStateEvidenceResult> {\n const scriptPath = path.resolve(input.scriptPath);\n const sourcePath = path.resolve(input.sourcePath);\n const workspacePath = path.resolve(input.workspacePath);\n const script = requireScriptV4(JSON.parse(fs.readFileSync(scriptPath, \"utf-8\")));\n const sources = sourceIdentities(sourcePath);\n if (sources.length !== script.episodes.length) {\n throw inputError(\n \"The linked video count does not match the script episode count.\",\n \"EVIDENCE_VIDEO_EPISODE_COUNT_MISMATCH\",\n \"Bind the complete source-video folder for this script, then retry.\",\n [`script=${script.episodes.length}`, `videos=${sources.length}`],\n );\n }\n\n const sourceSha256 = videoSourceFingerprint(sources);\n // The standalone path deliberately consumes only the final Script v4. It\n // never consults Gemini ingest documents or makes a model request.\n const plan = buildVideoStateEvidencePlan([], script, emptyContext(), sources, sourceSha256);\n const manifest = await withIngestWorkspaceLock(workspacePath, async () => {\n const store = new WorkspaceStore(workspacePath);\n store.ensure();\n return materializeVideoStateEvidence(\n store,\n plan,\n input.signal,\n input.extractor,\n { reuseExistingFrames: input.force !== true },\n );\n });\n const samples = [\n ...manifest.items.flatMap((item) => item.samples),\n ...(manifest.identities ?? []).flatMap((item) => item.samples),\n ];\n return {\n output: path.join(workspacePath, \"evidence\", \"state-evidence.json\"),\n states: manifest.items.length,\n identities: manifest.identities?.length ?? 0,\n samples: samples.length,\n ready: samples.filter((sample) => sample.frame_status === \"ready\").length,\n unavailable: samples.filter((sample) => sample.frame_status === \"unavailable\").length,\n sourceSha256,\n };\n}\n\nexport async function commandGenerateVideoStateEvidence(opts: Dict): Promise<[CommandOutput, number]> {\n const scriptPath = scriptJsonPath(opts);\n const sourcePath = typeof opts[\"source_path\"] === \"string\" ? opts[\"source_path\"].trim() : \"\";\n const workspacePath = typeof opts[\"workspace_path\"] === \"string\" ? opts[\"workspace_path\"].trim() : \"\";\n if (!sourcePath) {\n throw inputError(\"--source-path is required.\", \"EVIDENCE_SOURCE_REQUIRED\", \"Pass the linked source-video file or folder.\", [\"--source-path <path>\"]);\n }\n if (!workspacePath) {\n throw inputError(\"--workspace-path is required.\", \"EVIDENCE_WORKSPACE_REQUIRED\", \"Pass the project workspace directory.\", [\"--workspace-path <path>\"]);\n }\n const result = await generateVideoStateEvidence({\n scriptPath,\n sourcePath,\n workspacePath,\n force: opts[\"force\"] === true,\n });\n return [{\n text: `Generated ${result.ready}/${result.samples} original-video reference frames for ${result.states} actor states.`,\n data: {\n output: result.output,\n states: result.states,\n identities: result.identities,\n samples: result.samples,\n ready: result.ready,\n unavailable: result.unavailable,\n source_sha256: result.sourceSha256,\n },\n }, EXIT_OK];\n}\n", "import { CliError, EXIT_INPUT } from \"../../../common.js\";\nimport {\n ACTION_TYPE_SET,\n IMPORTANCE_TIER_SET,\n NON_ACTOR_SPEAKER_KIND_SET,\n ROLE_TYPE_SET,\n type ExtensionMap,\n} from \"../shared/types.js\";\nimport { isV4Id } from \"./ids.js\";\nimport type {\n ActionV4,\n ActorRefV4,\n ActorSpeakerV4,\n ActorV4,\n EpisodeV4,\n LocationRefV4,\n LocationV4,\n NonActorSpeakerV4,\n PropRefV4,\n PropV4,\n SceneV4,\n ScriptV4,\n StateIdV4,\n StateV4,\n} from \"./types.js\";\nimport { validateScriptV4 } from \"./validation.js\";\n\ntype RecordValue = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is RecordValue {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction optionalString(record: RecordValue, key: string): boolean {\n return record[key] === undefined || typeof record[key] === \"string\";\n}\n\nfunction isJsonValue(value: unknown): boolean {\n if (\n value === null\n || typeof value === \"string\"\n || typeof value === \"number\"\n || typeof value === \"boolean\"\n ) return true;\n if (Array.isArray(value)) return value.every(isJsonValue);\n return isRecord(value) && Object.values(value).every(isJsonValue);\n}\n\nfunction hasValidExtension(record: RecordValue): record is RecordValue & { extend?: ExtensionMap } {\n return record.extend === undefined\n || (isRecord(record.extend) && Object.values(record.extend).every(isJsonValue));\n}\n\nfunction isStateId(value: unknown): value is StateIdV4 {\n return value === \"default\" || isV4Id(\"state\", value);\n}\n\nfunction isState(value: unknown): value is StateV4 {\n return isRecord(value)\n && isStateId(value.state_id)\n && typeof value.state_name === \"string\"\n && typeof value.description === \"string\"\n && hasValidExtension(value);\n}\n\nfunction hasAssetShape(value: RecordValue): boolean {\n return typeof value.importance === \"string\"\n && IMPORTANCE_TIER_SET.has(value.importance)\n && typeof value.description === \"string\"\n && (value.aliases === undefined\n || (Array.isArray(value.aliases) && value.aliases.every((alias) => typeof alias === \"string\")))\n && Array.isArray(value.states)\n && value.states.every(isState)\n && hasValidExtension(value);\n}\n\nfunction isActor(value: unknown): value is ActorV4 {\n return isRecord(value)\n && isV4Id(\"actor\", value.actor_id)\n && typeof value.actor_name === \"string\"\n && (value.role_type === undefined\n || (typeof value.role_type === \"string\" && ROLE_TYPE_SET.has(value.role_type)))\n && hasAssetShape(value);\n}\n\nfunction isLocation(value: unknown): value is LocationV4 {\n return isRecord(value)\n && isV4Id(\"location\", value.location_id)\n && typeof value.location_name === \"string\"\n && hasAssetShape(value);\n}\n\nfunction isProp(value: unknown): value is PropV4 {\n return isRecord(value)\n && isV4Id(\"prop\", value.prop_id)\n && typeof value.prop_name === \"string\"\n && hasAssetShape(value);\n}\n\nfunction isStateIds(value: unknown): value is StateIdV4[] {\n return Array.isArray(value) && value.every(isStateId);\n}\n\nfunction isActorRef(value: unknown): value is ActorRefV4 {\n return isRecord(value)\n && isV4Id(\"actor\", value.actor_id)\n && isStateIds(value.state_ids);\n}\n\nfunction isLocationRef(value: unknown): value is LocationRefV4 {\n return isRecord(value)\n && isV4Id(\"location\", value.location_id)\n && isStateIds(value.state_ids);\n}\n\nfunction isPropRef(value: unknown): value is PropRefV4 {\n return isRecord(value)\n && isV4Id(\"prop\", value.prop_id)\n && isStateIds(value.state_ids);\n}\n\nfunction isActorSpeaker(value: RecordValue): value is RecordValue & ActorSpeakerV4 {\n return isV4Id(\"actor\", value.actor_id)\n && (value.state_id === undefined || isStateId(value.state_id));\n}\n\nfunction isNonActorSpeaker(value: RecordValue): value is RecordValue & NonActorSpeakerV4 {\n return typeof value.kind === \"string\"\n && NON_ACTOR_SPEAKER_KIND_SET.has(value.kind)\n && optionalString(value, \"label\");\n}\n\nfunction isAction(value: unknown): value is ActionV4 {\n if (\n !isRecord(value)\n || !isV4Id(\"action\", value.action_id)\n || typeof value.type !== \"string\"\n || !ACTION_TYPE_SET.has(value.type)\n || typeof value.content !== \"string\"\n || !optionalString(value, \"parenthetical\")\n || !hasValidExtension(value)\n ) return false;\n if (value.type === \"dialogue\" || value.type === \"inner_thought\") {\n if (!isRecord(value.speaker)\n || (!isActorSpeaker(value.speaker) && !isNonActorSpeaker(value.speaker))) return false;\n }\n if (value.transition_prompt !== undefined) {\n if (\n !isRecord(value.transition_prompt)\n || (!isV4Id(\"actor\", value.transition_prompt.target)\n && !isV4Id(\"location\", value.transition_prompt.target)\n && !isV4Id(\"prop\", value.transition_prompt.target))\n || typeof value.transition_prompt.process !== \"string\"\n || typeof value.transition_prompt.contrast !== \"string\"\n ) return false;\n }\n return true;\n}\n\nfunction isScene(value: unknown): value is SceneV4 {\n if (\n !isRecord(value)\n || !isV4Id(\"scene\", value.scene_id)\n || !Array.isArray(value.actors)\n || !value.actors.every(isActorRef)\n || !Array.isArray(value.props)\n || !value.props.every(isPropRef)\n || !Array.isArray(value.actions)\n || !value.actions.every(isAction)\n || !hasValidExtension(value)\n ) return false;\n if (value.location !== null && !isLocationRef(value.location)) return false;\n if (value.environment !== undefined\n && (!isRecord(value.environment)\n || !optionalString(value.environment, \"space\")\n || !optionalString(value.environment, \"time\"))) return false;\n return true;\n}\n\nfunction isEpisode(value: unknown): value is EpisodeV4 {\n return isRecord(value)\n && isV4Id(\"episode\", value.episode_id)\n && optionalString(value, \"title\")\n && optionalString(value, \"synopsis\")\n && Array.isArray(value.scenes)\n && value.scenes.every(isScene)\n && hasValidExtension(value);\n}\n\nexport function isStructurallyReadableScriptV4(value: unknown): value is ScriptV4 {\n return isRecord(value)\n && value.version === 4\n && typeof value.title === \"string\"\n && typeof value.worldview === \"string\"\n && typeof value.style === \"string\"\n && optionalString(value, \"worldview_raw\")\n && optionalString(value, \"synopsis\")\n && optionalString(value, \"logline\")\n && optionalString(value, \"theme\")\n && (value.main_characters === undefined\n || (Array.isArray(value.main_characters)\n && value.main_characters.every((item) =>\n isRecord(item) && typeof item.name === \"string\" && typeof item.role === \"string\")))\n && Array.isArray(value.actors)\n && value.actors.every(isActor)\n && Array.isArray(value.locations)\n && value.locations.every(isLocation)\n && Array.isArray(value.props)\n && value.props.every(isProp)\n && Array.isArray(value.episodes)\n && value.episodes.every(isEpisode)\n && hasValidExtension(value);\n}\n\nexport function isScriptV4(value: unknown): value is ScriptV4 {\n return validateScriptV4(value).ok;\n}\n\nexport function requireScriptV4(value: unknown): ScriptV4 {\n const validation = validateScriptV4(value);\n if (validation.ok) return value as ScriptV4;\n throw new CliError(\"The local file is not a valid Script v4 document.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_V4_INVALID\",\n hint: \"Run `scriptctl validate --script-path <path>` and repair the reported v4 fields.\",\n data: { expected: [\"A valid Script v4 document\"], actual: validation.errors.slice(0, 20).map((issue) => `${issue.path}: ${issue.message}`) },\n });\n}\n\nexport function requireStructurallyReadableScriptV4(value: unknown): ScriptV4 {\n if (isStructurallyReadableScriptV4(value)) return value;\n throw new CliError(\"The local file is not a structurally readable Script v4 document.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_V4_SHAPE_INVALID\",\n hint: \"Repair the local Script v4 structure, then rerun the command.\",\n data: {\n expected: [\"Script v4 with typed assets, episodes, scenes, references, and actions\"],\n actual: [Array.isArray(value) ? \"array\" : typeof value],\n },\n });\n}\n", "// `scriptctl view` \u2014 top-level command (\u00A74). Renders a workspace's script.json\n// into review.html at the workspace root. No model. For a video workspace it\n// symlinks the episode media into <ws>/src/ep_NNN.mp4 so the review UI's relative\n// video paths resolve. Fails clearly when the workspace has no script.json yet.\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CliError, EXIT_INPUT, EXIT_OK, type CommandOutput } from \"../../common.js\";\nimport { renderReviewHtml } from \"../../infra/ingest/review-renderer.js\";\nimport { WorkspaceStore } from \"../../infra/ingest/workspace-store.js\";\nimport { runViewServer } from \"./view-server.js\";\n\ntype Dict = Record<string, unknown>;\nconst strOf = (v: unknown): string => (v === null || v === undefined ? \"\" : String(v));\nconst pad = (n: number): string => String(n).padStart(3, \"0\");\n\n// Symlink each episode's media into <ws>/src/ep_NNN.mp4 (best-effort; the review\n// UI seeks video by relative path). Only present for a video workspace.\nfunction linkMedia(store: WorkspaceStore): void {\n if (!store.has(\"manifest.json\")) return;\n const manifest = store.readJson<{ episodes?: Array<{ episode?: number; path?: string }> }>(\"manifest.json\");\n if (!Array.isArray(manifest.episodes)) return;\n const srcDir = store.path(\"src\");\n fs.mkdirSync(srcDir, { recursive: true });\n for (const e of manifest.episodes) {\n if (typeof e.episode !== \"number\" || typeof e.path !== \"string\") continue;\n const link = path.join(srcDir, `ep_${pad(e.episode)}.mp4`);\n try {\n fs.rmSync(link, { force: true });\n fs.symlinkSync(e.path, link);\n } catch {\n // best-effort: a missing source or unsupported fs just leaves the seek broken.\n }\n }\n}\n\nexport async function commandView(opts: Dict): Promise<[CommandOutput, number]> {\n // --watch: live monitor server (progress + artifacts + context, auto-refresh),\n // runs until Ctrl-C. Works while ingest is still running (no script.json yet).\n // Local-only: it blocks on a web server + opens a browser, which would hang a\n // headless sandbox run \u2014 refuse there (the sandbox injects SANDBOX_PROJECT_GROUP_NO).\n if (opts[\"watch\"]) {\n if ((process.env.SANDBOX_PROJECT_GROUP_NO ?? \"\").trim()) {\n throw new CliError(\"`view --watch` runs a local web server and opens a browser; it is local-only and unavailable in the sandbox.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"VIEW_WATCH_SANDBOX\",\n hint: \"Use `scriptctl ingest status` for progress in the sandbox; run `view --watch` on your local machine.\",\n });\n }\n return runViewServer(opts);\n }\n\n const workspacePath = strOf(opts[\"workspace_path\"] || \"workspace\");\n const store = new WorkspaceStore(path.resolve(workspacePath));\n if (!store.has(\"script.json\")) {\n throw new CliError(\"workspace has no script.json to render.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"VIEW_NO_SCRIPT\",\n hint: \"Run `scriptctl ingest --source-path <src> --workspace-path <dir>` first.\",\n data: { actual: [store.path(\"script.json\")] },\n });\n }\n linkMedia(store);\n const html = renderReviewHtml(store.readJson(\"script.json\"));\n store.writeText(\"review.html\", html);\n const output = store.path(\"review.html\");\n return [{ text: output, data: { output } }, EXIT_OK];\n}\n", "// Review HTML renderer (\u00A74 view / \u00A710 pass6). Pure: Script v3 doc \u2192 the verified\n// cezhi-verify review UI (dual-tab \u5267\u672C\u5BA1\u9605 / \u8D44\u4EA7\u603B\u89C8, left video + right script\n// rows, click a row to seek, per-actor state\u00D7episode matrix, scene chips). The\n// HTML/CSS/JS is ported VERBATIM from the scaffold's 06_build_review_html; only\n// the data it reads is transformed here from v3 into the shape that UI expects\n// (asset_name / actor_names / actor_states / scene_num / location_name /\n// action.extend.timestamp). Video is referenced relatively as src/ep_NNN.mp4\n// (the view command symlinks the media into the workspace).\n\ntype Obj = Record<string, unknown>;\nconst isObj = (v: unknown): v is Obj => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst isArr = (v: unknown): v is unknown[] => Array.isArray(v);\nconst S = (v: unknown): string => (typeof v === \"string\" ? v : \"\");\n\nconst SPACE_EN_TO_ZH: Record<string, string> = { interior: \"\u5185\", exterior: \"\u5916\" };\nconst TIME_EN_TO_ZH: Record<string, string> = { day: \"\u65E5\", night: \"\u591C\" };\nconst epNum = (episodeId: string): number => { const m = episodeId.match(/(\\d+)/); return m ? Number(m[1]) : 0; };\nconst scnNum = (sceneId: string): number => { const m = sceneId.match(/(\\d+)/); return m ? Number(m[1]) : 0; };\n\nfunction nameMap(list: unknown, idField: string, nameField: string): Map<string, string> {\n const m = new Map<string, string>();\n if (isArr(list)) for (const a of list) if (isObj(a) && typeof a[idField] === \"string\") m.set(a[idField] as string, S(a[nameField]));\n return m;\n}\nfunction stateNameMap(list: unknown, idField: string): Map<string, Map<string, string>> {\n const m = new Map<string, Map<string, string>>();\n if (isArr(list)) for (const a of list) {\n if (!isObj(a) || typeof a[idField] !== \"string\") continue;\n const sm = new Map<string, string>();\n for (const st of isArr(a.states) ? a.states : []) if (isObj(st) && typeof st.state_id === \"string\") sm.set(st.state_id, S(st.state_name));\n m.set(a[idField] as string, sm);\n }\n return m;\n}\n\n// v3 speaker \u2192 display string (actor name, or kind[:label]).\nfunction speakerLabel(speaker: unknown, actorNames: Map<string, string>): string {\n if (!isObj(speaker)) return \"\";\n if (typeof speaker.actor_id === \"string\") return actorNames.get(speaker.actor_id) ?? speaker.actor_id;\n if (typeof speaker.kind === \"string\") return `${speaker.kind}${speaker.label ? `:${S(speaker.label)}` : \"\"}`;\n return \"\";\n}\n\n// Transform a v3 script into the scaffold review-model consumed by the UI JS.\nfunction toReviewModel(doc: Obj): Obj {\n const actorNames = nameMap(doc.actors, \"actor_id\", \"actor_name\");\n const locNames = nameMap(doc.locations, \"location_id\", \"location_name\");\n const propNames = nameMap(doc.props, \"prop_id\", \"prop_name\");\n const actorStates = stateNameMap(doc.actors, \"actor_id\");\n\n const episodes = (isArr(doc.episodes) ? doc.episodes : []).filter(isObj).map((ep) => ({\n episode: epNum(S(ep.episode_id)),\n synopsis: S(ep.synopsis),\n scenes: (isArr(ep.scenes) ? ep.scenes : []).filter(isObj).map((sc) => {\n const loc = isObj(sc.location) ? (locNames.get(S(sc.location.location_id)) ?? S(sc.location.location_id)) : \"\";\n const anames: string[] = [];\n const astates: Record<string, string> = {};\n for (const r of isArr(sc.actors) ? sc.actors : []) {\n if (!isObj(r) || typeof r.actor_id !== \"string\") continue;\n const nm = actorNames.get(r.actor_id) ?? r.actor_id;\n if (!anames.includes(nm)) anames.push(nm);\n // Show the state's name whenever it HAS one \u2014 including a named `default`.\n // In the video path `default` is the character's real main outfit (e.g.\n // \u300C\u4EAC\u5317\u5927\u5B66\u767D\u8272\u7403\u8863\u300D), not an anonymous baseline, so excluding it hid the\n // dominant look under \u300C\u672A\u6807\u6CE8\u300D. A `default` with an empty name (the text\n // path's nameless baseline) still falls through to \u672A\u6807\u6CE8 as before.\n if (typeof r.state_id === \"string\") {\n const sn = actorStates.get(r.actor_id)?.get(r.state_id) ?? \"\";\n const label = sn || (r.state_id !== \"default\" ? r.state_id : \"\");\n if (label) astates[nm] = label;\n }\n }\n const pnames: string[] = [];\n for (const r of isArr(sc.props) ? sc.props : []) if (isObj(r) && typeof r.prop_id === \"string\") { const nm = propNames.get(r.prop_id) ?? r.prop_id; if (!pnames.includes(nm)) pnames.push(nm); }\n const env = isObj(sc.environment) ? sc.environment : {};\n return {\n scene_num: scnNum(S(sc.scene_id)),\n location_name: loc,\n environment: { space: SPACE_EN_TO_ZH[S(env.space)] ?? S(env.space), time: TIME_EN_TO_ZH[S(env.time)] ?? S(env.time) },\n actor_names: anames,\n actor_states: astates,\n prop_names: pnames,\n actions: (isArr(sc.actions) ? sc.actions : []).filter(isObj).map((a) => ({\n type: S(a.type),\n content: S(a.content),\n speaker: speakerLabel(a.speaker, actorNames),\n emotion: typeof a.emotion === \"string\" ? a.emotion : undefined,\n extend: isObj(a.extend) && typeof a.extend.timestamp === \"string\" ? { timestamp: a.extend.timestamp } : undefined,\n })),\n };\n }),\n }));\n\n const actors = (isArr(doc.actors) ? doc.actors : []).filter(isObj).map((a) => ({\n asset_name: S(a.actor_name),\n description: S(a.description),\n extend: {},\n }));\n return { title: S(doc.title), actors, episodes };\n}\n\nexport function renderReviewHtml(doc: unknown): string {\n if (!isObj(doc)) throw new Error(\"review renderer expects a script object\");\n const model = toReviewModel(doc);\n const data = JSON.stringify(model);\n const title = S(model.title);\n\n return `<!DOCTYPE html>\n<html lang=\"zh\">\n<head>\n<meta charset=\"utf-8\">\n<title>\u5267\u672C\u5BA1\u9605\u5668 \u00B7 ${title}</title>\n<style>\n * { box-sizing: border-box; }\n html, body { margin: 0; height: 100%; font: 14px/1.6 -apple-system, \"PingFang SC\", system-ui, sans-serif; color: #1a1a1a; }\n body { display: flex; flex-direction: column; height: 100vh; background: #f5f5f7; }\n header { display: flex; align-items: center; gap: 12px; padding: 8px 14px; background: #fff; border-bottom: 1px solid #ddd; flex: none; }\n header h1 { font-size: 15px; margin: 0; font-weight: 600; }\n header select, header .nav { font-size: 13px; padding: 4px 8px; border: 1px solid #ccc; border-radius: 6px; background: #fff; cursor: pointer; }\n header .spacer { flex: 1; }\n header .hint { color: #888; font-size: 12px; }\n main { flex: 1; display: flex; min-height: 0; }\n .left { width: 42%; min-width: 320px; max-width: 620px; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; position: relative; }\n .left video { width: 100%; height: auto; max-height: 72vh; background: #000; }\n .vbar { color: #ccc; font-size: 12px; padding: 6px 10px; width: 100%; display: flex; gap: 12px; align-items: center; background: #111; }\n .vbar b { color: #fff; font-variant-numeric: tabular-nums; }\n .right { flex: 1; overflow-y: auto; padding: 10px 4px 40vh 4px; background: #fafafa; }\n .syn { background: #fff7e6; border: 1px solid #ffe0a3; border-radius: 8px; padding: 10px 12px; margin: 8px 10px 14px; color: #5b4a1f; font-size: 13px; }\n .scene { margin: 0 10px 14px; border: 1px solid #e5e5e5; border-radius: 8px; overflow: hidden; background: #fff; }\n .scene-head { background: #eef2f7; padding: 6px 12px; font-size: 12px; color: #445; display: flex; gap: 14px; flex-wrap: wrap; }\n .scene-head .loc { font-weight: 600; color: #223; }\n .rows { }\n .row { display: flex; gap: 10px; padding: 5px 12px; border-top: 1px solid #f0f0f0; cursor: pointer; align-items: baseline; }\n .row:hover { background: #eef6ff; }\n .row.active { background: #d8ecff; }\n .row .ts { flex: none; width: 46px; color: #3a7; font-variant-numeric: tabular-nums; font-size: 12px; }\n .row .kind { flex: none; width: 58px; font-size: 12px; }\n .row .kind.act { color: #999; }\n .row .kind.dlg { color: #c60; font-weight: 600; }\n .row .kind.think { color: #96c; font-style: italic; }\n .row .body { flex: 1; }\n .row .spk { color: #c60; font-weight: 600; margin-right: 4px; }\n .row .emo { color: #a8a; font-size: 12px; margin-left: 4px; }\n .row .body .subtitle { color: #b00; } /* \u753B\u9762\u5B57\u5E55\u5F15\u8FF0\uFF0C\u7EA2\u8272\u6807\u51FA */\n /* ===== Tab ===== */\n header .tabs { display: flex; gap: 4px; }\n header .tab { font-size: 13px; padding: 5px 14px; border: 1px solid #ccc; border-radius: 6px; background: #fff; cursor: pointer; color: #555; }\n header .tab.active { background: #1a6dff; color: #fff; border-color: #1a6dff; font-weight: 600; }\n header .ep-ctl { display: flex; gap: 8px; align-items: center; }\n /* ===== \u8D44\u4EA7\u603B\u89C8 ===== */\n .assets { flex: 1; overflow-y: auto; padding: 16px 18px 30vh; background: #f5f5f7; }\n .asset-sec { margin: 0 0 26px; }\n .asset-sec > h2 { font-size: 15px; margin: 4px 0 12px; color: #223; display: flex; align-items: center; gap: 8px; }\n .asset-sec > h2 .cnt { font-size: 12px; font-weight: 400; color: #888; background: #ececf0; padding: 1px 8px; border-radius: 10px; }\n .acard { background: #fff; border: 1px solid #e3e3e6; border-radius: 10px; padding: 14px 16px; margin-bottom: 12px; }\n .acard .ah { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }\n .acard .ah .nm { font-size: 17px; font-weight: 700; color: #1a1a1a; }\n .acard .ah .id { font-size: 12px; color: #aaa; font-variant-numeric: tabular-nums; }\n .acard .ah .meta { margin-left: auto; font-size: 12px; color: #888; display: flex; gap: 6px; }\n .acard .ah .meta .tag { background: #f0f0f3; border-radius: 6px; padding: 1px 8px; }\n .acard .desc { font-size: 13px; color: #555; margin: 7px 0 4px; }\n .acard .anchor { font-size: 12px; color: #999; margin-bottom: 8px; }\n /* \u72B6\u6001\u00D7\u96C6 \u77E9\u9635 */\n .mtx { overflow-x: auto; margin-top: 8px; border: 1px solid #eee; border-radius: 8px; }\n table.tl { border-collapse: collapse; font-size: 12px; width: 100%; }\n table.tl th, table.tl td { border: 1px solid #eee; padding: 5px 7px; text-align: center; white-space: nowrap; }\n table.tl thead th { background: #f7f7f9; color: #556; font-weight: 600; position: sticky; top: 0; }\n table.tl .stname { text-align: left; font-weight: 600; color: #333; background: #fafafa; position: sticky; left: 0; min-width: 130px; max-width: 220px; white-space: normal; }\n table.tl .stname.unmk { color: #999; font-weight: 400; }\n table.tl .stname .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }\n table.tl .stname .sc { color: #aaa; font-weight: 400; font-size: 11px; margin-left: 4px; }\n table.tl td.cell { color: #ccc; }\n table.tl td.hit { background: #fff0f0; }\n table.tl td.hit.unmk { background: #f2f2f2; }\n .scc { display: inline-block; min-width: 20px; margin: 1px; padding: 1px 6px; border-radius: 6px; font-variant-numeric: tabular-nums; cursor: pointer; }\n .scc.on { background: #f4c9c9; color: #7a1f1f; border: 1px solid #e8a9a9; }\n .scc.on.unmk { background: #dcdcdc; color: #555; border-color: #c9c9c9; }\n .scc.on:hover { filter: brightness(0.94); }\n</style>\n</head>\n<body>\n<header>\n <h1>${title || \"\u5267\u672C\u5BA1\u9605\u5668\"}</h1>\n <div class=\"tabs\">\n <button class=\"tab active\" id=\"tab-script\">\u5267\u672C\u5BA1\u9605</button>\n <button class=\"tab\" id=\"tab-assets\">\u8D44\u4EA7\u603B\u89C8</button>\n </div>\n <span class=\"ep-ctl\">\n <select id=\"epsel\"></select>\n <button class=\"nav\" id=\"prev\">\u25C0 \u4E0A\u4E00\u96C6</button>\n <button class=\"nav\" id=\"next\">\u4E0B\u4E00\u96C6 \u25B6</button>\n </span>\n <span class=\"spacer\"></span>\n <span class=\"hint\" id=\"hint\">\u70B9\u4EFB\u610F\u5267\u672C\u884C \u2192 \u89C6\u9891\u8DF3\u5230\u8BE5\u65F6\u95F4\u6233</span>\n</header>\n<main id=\"view-script\">\n <div class=\"left\">\n <video id=\"vid\" controls preload=\"metadata\"></video>\n <div class=\"vbar\"><span>\u5F53\u524D <b id=\"cur\">00:00</b></span><span id=\"epinfo\"></span></div>\n </div>\n <div class=\"right\" id=\"right\"></div>\n</main>\n<div id=\"view-assets\" class=\"assets\" style=\"display:none\"></div>\n<script>\nconst SCRIPT = ${data};\nconst eps = SCRIPT.episodes.slice().sort((a,b)=>a.episode-b.episode);\nconst vid = document.getElementById('vid');\nconst right = document.getElementById('right');\nconst epsel = document.getElementById('epsel');\nconst cur = document.getElementById('cur');\nconst epinfo = document.getElementById('epinfo');\nlet curEp = eps.length?eps[0].episode:1;\n\nfunction pad(n){return String(n).padStart(2,'0');}\nfunction fmt(sec){sec=Math.max(0,sec|0);return pad(sec/60|0)+':'+pad(sec%60);}\nfunction tsToSec(ts){if(!ts)return null;const m=String(ts).match(/(?:(\\\\d{1,2}):)?(\\\\d{1,2}):(\\\\d{2}(?:\\\\.\\\\d{1,3})?)/);return m?(+(m[1]||0))*3600+(+m[2])*60+(+m[3]):null;}\nfunction epId(n){return 'ep_'+String(n).padStart(3,'0');}\nfunction actKind(t){return t==='dialogue'?'dlg':t==='inner_thought'?'think':'act';}\nfunction actTs(a){return a && a.extend ? a.extend.timestamp : undefined;}\n\nfunction renderBody(content){\n const esc = content.replace(/&/g,'&').replace(/</g,'<');\n return esc.replace(/(\u753B\u9762(?:\u5B57\u5E55|\u6587\u5B57)[:\uFF1A][^\u3002\uFF01\uFF1F\\\\n]*)/g,'<span class=\"subtitle\">$1</span>');\n}\n\nfor(const e of eps){\n const o=document.createElement('option');\n o.value=e.episode; o.textContent='\u7B2C '+e.episode+' \u96C6';\n epsel.appendChild(o);\n}\n\nfunction loadEp(n, targetScene){\n curEp=n;\n epsel.value=n;\n vid.src='src/'+epId(n)+'.mp4';\n const ep=eps.find(e=>e.episode===n);\n if(!ep)return;\n epinfo.textContent='\u7B2C'+n+'\u96C6 \u00B7 '+ep.scenes.length+'\u573A';\n right.innerHTML='';\n if(ep.synopsis){const s=document.createElement('div');s.className='syn';s.textContent='\u6897\u6982\uFF1A'+ep.synopsis;right.appendChild(s);}\n for(const sc of ep.scenes){\n const box=document.createElement('div');box.className='scene';\n box.dataset.scene=sc.scene_num;\n const head=document.createElement('div');head.className='scene-head';\n const env=(sc.environment&&(sc.environment.space||'')+' '+(sc.environment.time||''))||'';\n const chNames=sc.actor_names||[]; const chSt=sc.actor_states||{};\n head.innerHTML='<span class=\"loc\">\u573A\u666F'+sc.scene_num+' \u00B7 '+(sc.location_name||'')+'</span>'+\n '<span>'+env+'</span>'+\n (chNames.length?'<span>\u89D2\u8272: '+chNames.map(nm=>nm+(chSt[nm]?'('+chSt[nm]+')':'')).join('\u3001')+'</span>':'');\n box.appendChild(head);\n const rows=document.createElement('div');rows.className='rows';\n for(const a of sc.actions){\n const ts=actTs(a); const kd=actKind(a.type); const sec=tsToSec(ts);\n const row=document.createElement('div');row.className='row';row.dataset.sec=sec==null?'':sec;\n const spk=a.speaker?'<span class=\"spk\">'+a.speaker+'</span>':'';\n const emo=a.emotion?'<span class=\"emo\">['+a.emotion+']</span>':'';\n row.innerHTML='<span class=\"ts\">'+(ts||'')+'</span>'+\n '<span class=\"kind '+kd+'\">'+kd+'</span>'+\n '<span class=\"body\">'+spk+renderBody(a.content)+emo+'</span>';\n if(sec!=null)row.addEventListener('click',()=>{vid.currentTime=sec;vid.play();});\n rows.appendChild(row);\n }\n box.appendChild(rows);right.appendChild(box);\n }\n if(targetScene){\n const tb=right.querySelector('.scene[data-scene=\"'+targetScene+'\"]');\n if(tb){tb.scrollIntoView({block:'start'}); tb.style.outline='2px solid #1a6dff'; setTimeout(()=>tb.style.outline='',1600);}\n } else { right.scrollTop=0; }\n}\n\nvid.addEventListener('timeupdate',()=>{\n cur.textContent=fmt(vid.currentTime);\n const t=vid.currentTime;\n const rows=[...right.querySelectorAll('.row')].filter(r=>r.dataset.sec!=='');\n let active=null;\n for(const r of rows){ if(+r.dataset.sec<=t+0.25) active=r; else break; }\n right.querySelectorAll('.row.active').forEach(r=>r.classList.remove('active'));\n if(active){active.classList.add('active');}\n});\n\nepsel.addEventListener('change',()=>loadEp(+epsel.value));\ndocument.getElementById('prev').addEventListener('click',()=>{const i=eps.findIndex(e=>e.episode===curEp);if(i>0)loadEp(eps[i-1].episode);});\ndocument.getElementById('next').addEventListener('click',()=>{const i=eps.findIndex(e=>e.episode===curEp);if(i<eps.length-1)loadEp(eps[i+1].episode);});\n\nif(eps.length)loadEp(curEp);\n\n// ===================== \u8D44\u4EA7\u603B\u89C8 =====================\nconst allEps = eps.map(e=>e.episode).sort((a,b)=>a-b);\nconst actorMeta = {};\nfor(const a of (SCRIPT.actors||[])){\n const ext=a.extend||{};\n actorMeta[a.asset_name]={role:a.description||'',anchor:ext.anchor||''};\n}\n\nfunction aggAssets(){\n const person={}, loc={}, prop={};\n const addP=(nm,st,n,idx)=>{(person[nm]=person[nm]||{});(person[nm][st]=person[nm][st]||new Map()).set(n+':'+idx,{n,idx});};\n const addX=(bag,nm,n,idx)=>{(bag[nm]=bag[nm]||new Map()).set(n+':'+idx,{n,idx});};\n for(const ep of eps){ const n=ep.episode;\n for(const sc of ep.scenes){ const idx=sc.scene_num;\n const names=sc.actor_names||[]; const st=sc.actor_states||{};\n for(const nm of names) addP(nm, st[nm]||'\u672A\u6807\u6CE8', n, idx);\n if(sc.location_name) addX(loc, sc.location_name, n, idx);\n for(const p of (sc.prop_names||[])) addX(prop, p, n, idx);\n }\n }\n return {person,loc,prop};\n}\nconst AG = aggAssets();\n\nfunction epsOf(occMaps){ const s=new Set(); for(const m of occMaps) for(const {n} of m.values()) s.add(n); return [...s].sort((a,b)=>a-b); }\nfunction sceneChips(occMap, unmk){\n const byEp={}; for(const {n,idx} of occMap.values()){(byEp[n]=byEp[n]||[]).push(idx);}\n return byEp;\n}\nfunction chipEl(n, idx, unmk){\n const c=document.createElement('span'); c.className='scc on'+(unmk?' unmk':''); c.textContent=idx;\n c.title='\u7B2C'+n+'\u96C6 \u00B7 \u573A'+idx+' \u2192 \u8DF3\u8F6C';\n c.addEventListener('click',(e)=>{e.stopPropagation();gotoScene(n,idx);});\n return c;\n}\nfunction gotoScene(n, idx){ switchTab('script'); loadEp(n, idx); }\n\nfunction personCard(name){\n const states=AG.person[name]; const stKeys=Object.keys(states);\n const involved=epsOf(Object.values(states));\n const card=document.createElement('div'); card.className='acard';\n const meta=actorMeta[name]||{};\n const totalScenes=new Set(); for(const m of Object.values(states)) for(const k of m.keys()) totalScenes.add(k);\n const head=document.createElement('div'); head.className='ah';\n head.innerHTML='<span class=\"nm\">'+esc(name)+'</span>'+\n '<span class=\"meta\"><span class=\"tag\">'+totalScenes.size+' \u573A</span><span class=\"tag\">'+involved.length+' \u96C6</span><span class=\"tag\">'+stKeys.length+' \u72B6\u6001</span></span>';\n card.appendChild(head);\n if(meta.role){const d=document.createElement('div');d.className='desc';d.textContent=meta.role;card.appendChild(d);}\n if(meta.anchor){const d=document.createElement('div');d.className='anchor';d.textContent='\u951A\u70B9\uFF1A'+meta.anchor;card.appendChild(d);}\n const wrap=document.createElement('div'); wrap.className='mtx';\n const tb=document.createElement('table'); tb.className='tl';\n let thead='<thead><tr><th class=\"stname\">\u72B6\u6001\uFF3C\u96C6</th>';\n for(const n of involved) thead+='<th>'+n+'</th>';\n thead+='</tr></thead>';\n const ordered=stKeys.filter(s=>s!=='\u672A\u6807\u6CE8').sort((a,b)=>states[b].size-states[a].size);\n if(states['\u672A\u6807\u6CE8']) ordered.push('\u672A\u6807\u6CE8');\n const tbody=document.createElement('tbody');\n for(const st of ordered){\n const unmk=st==='\u672A\u6807\u6CE8';\n const byEp=sceneChips(states[st], unmk);\n const tr=document.createElement('tr');\n const th=document.createElement('td'); th.className='stname'+(unmk?' unmk':'');\n th.innerHTML='<span class=\"dot\" style=\"background:'+(unmk?'#bbb':'#d9534f')+'\"></span>'+esc(st)+'<span class=\"sc\">'+states[st].size+'</span>';\n tr.appendChild(th);\n for(const n of involved){\n const td=document.createElement('td'); td.className='cell'+(byEp[n]?' hit'+(unmk?' unmk':''):'');\n if(byEp[n]){ for(const idx of byEp[n].sort((a,b)=>a-b)) td.appendChild(chipEl(n,idx,unmk)); }\n tr.appendChild(td);\n }\n tbody.appendChild(tr);\n }\n tb.innerHTML=thead; tb.appendChild(tbody);\n wrap.appendChild(tb); card.appendChild(wrap);\n return card;\n}\n\nfunction occCard(name, occMap){\n const involved=epsOf([occMap]);\n const card=document.createElement('div'); card.className='acard';\n const head=document.createElement('div'); head.className='ah';\n head.innerHTML='<span class=\"nm\">'+esc(name)+'</span>'+\n '<span class=\"meta\"><span class=\"tag\">'+occMap.size+' \u573A</span><span class=\"tag\">'+involved.length+' \u96C6</span></span>';\n card.appendChild(head);\n const wrap=document.createElement('div'); wrap.className='mtx';\n const tb=document.createElement('table'); tb.className='tl';\n let thead='<thead><tr><th class=\"stname\">\u51FA\u73B0\uFF3C\u96C6</th>';\n for(const n of involved) thead+='<th>'+n+'</th>'; thead+='</tr></thead>';\n const byEp=sceneChips(occMap,false);\n const tbody=document.createElement('tbody'); const tr=document.createElement('tr');\n const th=document.createElement('td'); th.className='stname';\n th.innerHTML='<span class=\"dot\" style=\"background:#5b8def\"></span>\u51FA\u73B0';\n tr.appendChild(th);\n for(const n of involved){ const td=document.createElement('td'); td.className='cell'+(byEp[n]?' hit':'');\n if(byEp[n]){ for(const idx of byEp[n].sort((a,b)=>a-b)) td.appendChild(chipEl(n,idx,false)); } tr.appendChild(td);}\n tbody.appendChild(tr); tb.innerHTML=thead; tb.appendChild(tbody);\n wrap.appendChild(tb); card.appendChild(wrap);\n return card;\n}\n\nfunction esc(s){return String(s).replace(/&/g,'&').replace(/</g,'<');}\n\nlet assetsRendered=false;\nfunction renderAssets(){\n if(assetsRendered) return; assetsRendered=true;\n const root=document.getElementById('view-assets');\n const persons=Object.keys(AG.person).sort((a,b)=>{\n const ea=new Set(),eb=new Set();\n for(const m of Object.values(AG.person[a])) for(const {n} of m.values()) ea.add(n);\n for(const m of Object.values(AG.person[b])) for(const {n} of m.values()) eb.add(n);\n return eb.size-ea.size;\n });\n const secP=document.createElement('div'); secP.className='asset-sec';\n secP.innerHTML='<h2>\u4EBA\u7269 <span class=\"cnt\">'+persons.length+'</span></h2>';\n for(const nm of persons) secP.appendChild(personCard(nm));\n root.appendChild(secP);\n const locs=Object.keys(AG.loc).sort((a,b)=>AG.loc[b].size-AG.loc[a].size);\n const secL=document.createElement('div'); secL.className='asset-sec';\n secL.innerHTML='<h2>\u573A\u666F <span class=\"cnt\">'+locs.length+'</span></h2>';\n for(const nm of locs) secL.appendChild(occCard(nm,AG.loc[nm]));\n root.appendChild(secL);\n const props=Object.keys(AG.prop).sort((a,b)=>AG.prop[b].size-AG.prop[a].size);\n const secD=document.createElement('div'); secD.className='asset-sec';\n secD.innerHTML='<h2>\u9053\u5177 <span class=\"cnt\">'+props.length+'</span></h2>';\n for(const nm of props) secD.appendChild(occCard(nm,AG.prop[nm]));\n root.appendChild(secD);\n}\n\nconst tabScript=document.getElementById('tab-script'), tabAssets=document.getElementById('tab-assets');\nconst viewScript=document.getElementById('view-script'), viewAssets=document.getElementById('view-assets');\nconst epCtl=document.querySelector('.ep-ctl'), hint=document.getElementById('hint');\nfunction switchTab(which){\n const asset=which==='assets';\n tabScript.classList.toggle('active',!asset); tabAssets.classList.toggle('active',asset);\n viewScript.style.display=asset?'none':'flex'; viewAssets.style.display=asset?'block':'none';\n epCtl.style.display=asset?'none':'flex';\n hint.textContent=asset?'\u70B9\u573A\u53F7 \u2192 \u8DF3\u56DE\u5267\u672C\u5BA1\u9605\u5BF9\u5E94\u96C6/\u573A':'\u70B9\u4EFB\u610F\u5267\u672C\u884C \u2192 \u89C6\u9891\u8DF3\u5230\u8BE5\u65F6\u95F4\u6233';\n if(asset) renderAssets();\n}\ntabScript.addEventListener('click',()=>switchTab('script'));\ntabAssets.addEventListener('click',()=>switchTab('assets'));\n</script>\n</body>\n</html>`;\n}\n", "// `scriptctl view --watch` \u2014 a live workspace monitor for TEXT or VIDEO ingest.\n// Starts a tiny stdlib HTTP server (no deps) that a self-refreshing HTML dashboard\n// polls: ingest progress (deriveIngestStatus), the artifact tree (text serial\n// context/window md + provisional/final script, OR video per-episode transcript +\n// context-fed-to-model + parsed json + registry + timing.jsonl), and any single\n// file's content. The dashboard auto-refreshes so a running `scriptctl ingest` is\n// watched live and each unit's products stream in as they finish. Runs until Ctrl-C.\n// Text and video workspaces use disjoint layouts, so the artifact groups union\n// cleanly \u2014 a workspace only populates the groups its pipeline produces.\n\nimport * as http from \"node:http\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { spawn } from \"node:child_process\";\n\nimport { EXIT_OK, type CommandOutput } from \"../../common.js\";\nimport { deriveIngestStatus } from \"./status.js\";\nimport type { UsageReport } from \"./usage-report.js\";\n\ntype Dict = Record<string, unknown>;\nconst strOf = (v: unknown): string => (v === null || v === undefined ? \"\" : String(v));\n\ninterface FileMeta { rel: string; size: number; mtime: number }\n\n// Curated artifact list for the sidebar, grouped and ordered for reviewing an\n// ingest run. Only files that exist are returned.\nexport function listArtifacts(root: string): Record<string, FileMeta[]> {\n const meta = (rel: string): FileMeta | null => {\n try { const s = fs.statSync(path.join(root, rel)); return { rel, size: s.size, mtime: s.mtimeMs }; } catch { return null; }\n };\n const dirFiles = (dir: string, filter: (n: string) => boolean): FileMeta[] => {\n let names: string[] = [];\n try { names = fs.readdirSync(path.join(root, dir)); } catch { return []; }\n return names.filter(filter).sort().map((n) => meta(`${dir}/${n}`)).filter((m): m is FileMeta => !!m);\n };\n const only = (arr: (FileMeta | null)[]): FileMeta[] => arr.filter((m): m is FileMeta => !!m);\n const epFile = (suffix: string): FileMeta[] =>\n dirFiles(\"ep\", (n) => n.endsWith(suffix) && !n.endsWith(\".error.json\"));\n return {\n \u7ED3\u679C: only([meta(\"script.json\"), meta(\"validation.json\"), meta(\"asset-audit.json\"), meta(\"usage.json\"), meta(\"review.html\"), meta(\"timings.json\")]),\n // Text serial artifacts (empty for a video workspace).\n \u4E0A\u4E0B\u6587: dirFiles(\"serial\", (n) => n.startsWith(\"context_\") && n.endsWith(\".md\")),\n \u6BCF\u7A97\u66F4\u65B0: dirFiles(\"serial\", (n) => n.startsWith(\"win_\") && n.endsWith(\".json\")),\n \u7BC7\u7AE0\u6897\u6982: dirFiles(\"serial\", (n) => n.startsWith(\"arc_\") && n.endsWith(\".md\")),\n \u524D\u6BB5: dirFiles(\"pass2\", (n) => /^chunk_\\d+\\.json$/.test(n)),\n // Video serial artifacts (empty for a text workspace). Grouped by kind so an\n // episode's whole story is one scan down the list.\n \u8F6C\u5F55: epFile(\".md\").filter((m) => !m.rel.endsWith(\".context.md\")),\n \u9001\u6A21\u4E0A\u4E0B\u6587: epFile(\".context.md\"),\n \u89E3\u6790: epFile(\".json\"),\n \u82B1\u540D\u518C: only([meta(\"context.json\")]),\n \u8BA1\u65F6: only([meta(\"timing.jsonl\")]),\n \u4E2D\u95F4\u4EA7\u7269: only([meta(\"script.initial.json\"), meta(\"provisional_assets.json\"), meta(\"notes.json\"), meta(\"id_map.json\"), meta(\"manifest.json\")]),\n };\n}\n\n// Parse timing.jsonl (one episode per line) into a compact summary the dashboard\n// shows without shipping the whole file. Tolerant: skips malformed lines. Only the\n// video pipeline writes timing.jsonl; a text workspace yields an empty summary.\nexport function readTiming(root: string): {\n episodes: Array<{ episode: number; transcodeMs?: number; uploadMs?: number; generateMs?: number; uploadMB?: string; transcoded?: boolean }>;\n totalMs: number;\n} {\n let text = \"\";\n try { text = fs.readFileSync(path.join(root, \"timing.jsonl\"), \"utf-8\"); } catch { return { episodes: [], totalMs: 0 }; }\n const episodes: Array<{ episode: number; transcodeMs?: number; uploadMs?: number; generateMs?: number; uploadMB?: string; transcoded?: boolean }> = [];\n let totalMs = 0;\n for (const line of text.split(/\\r?\\n/)) {\n const t = line.trim();\n if (!t) continue;\n try {\n const j = JSON.parse(t) as { episode?: number; transcodeMs?: number; uploadMs?: number; generateMs?: number; uploadMB?: string; transcoded?: boolean };\n if (typeof j.episode !== \"number\") continue;\n const row: (typeof episodes)[number] = { episode: j.episode };\n if (typeof j.transcodeMs === \"number\") { row.transcodeMs = j.transcodeMs; totalMs += j.transcodeMs; }\n if (typeof j.uploadMs === \"number\") { row.uploadMs = j.uploadMs; totalMs += j.uploadMs; }\n if (typeof j.generateMs === \"number\") { row.generateMs = j.generateMs; totalMs += j.generateMs; }\n if (typeof j.uploadMB === \"string\") row.uploadMB = j.uploadMB;\n if (typeof j.transcoded === \"boolean\") row.transcoded = j.transcoded;\n episodes.push(row);\n } catch { /* skip malformed line */ }\n }\n return { episodes, totalMs };\n}\n\n// Token accounting written by the pipelines \u2192 usage.json. Returns null when absent\n// (run hasn't reached the point where spend is persisted yet).\nexport function readUsage(root: string): UsageReport | null {\n try {\n const j = JSON.parse(fs.readFileSync(path.join(root, \"usage.json\"), \"utf-8\")) as UsageReport;\n return j;\n } catch { return null; }\n}\n\n// Read a workspace file, guarding against path traversal outside the root.\nexport function readSafe(root: string, rel: string): { ok: true; text: string } | { ok: false } {\n const abs = path.resolve(root, rel);\n if (abs !== root && !abs.startsWith(root + path.sep)) return { ok: false };\n try { return { ok: true, text: fs.readFileSync(abs, \"utf-8\") }; } catch { return { ok: false }; }\n}\n\nfunction send(res: http.ServerResponse, code: number, type: string, body: string): void {\n res.writeHead(code, { \"Content-Type\": type, \"Cache-Control\": \"no-store\" });\n res.end(body);\n}\n\nexport async function runViewServer(opts: Dict): Promise<[CommandOutput, number]> {\n const root = path.resolve(strOf(opts[\"workspace_path\"] || \"workspace\"));\n const port = Number(opts[\"port\"]) || 0; // 0 \u2192 OS-assigned ephemeral (no conflicts)\n\n const server = http.createServer((req, res) => {\n const u = new URL(req.url ?? \"/\", \"http://localhost\");\n if (u.pathname === \"/\") return send(res, 200, \"text/html; charset=utf-8\", DASHBOARD_HTML);\n if (u.pathname === \"/api/state\") {\n const status = deriveIngestStatus(root);\n return send(res, 200, \"application/json\", JSON.stringify({ root, status, groups: listArtifacts(root), timing: readTiming(root), usage: readUsage(root) }));\n }\n if (u.pathname === \"/api/file\") {\n const rel = u.searchParams.get(\"path\") ?? \"\";\n const r = readSafe(root, rel);\n return r.ok ? send(res, 200, \"text/plain; charset=utf-8\", r.text) : send(res, 404, \"text/plain\", \"not found\");\n }\n send(res, 404, \"text/plain\", \"not found\");\n });\n\n const actualPort = await new Promise<number>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, \"127.0.0.1\", () => resolve((server.address() as { port: number }).port));\n });\n const url = `http://127.0.0.1:${actualPort}/`;\n process.stderr.write(`Ingest monitor: ${url}\\nWorkspace: ${root}\\nPress Ctrl-C to stop.\\n`);\n if (process.platform === \"darwin\" && process.stderr.isTTY) {\n try { spawn(\"open\", [url], { detached: true, stdio: \"ignore\" }).unref(); } catch { /* best-effort */ }\n }\n\n // The listening server keeps the process alive after the startup result is\n // emitted. Closing it on either signal lets the CLI exit cleanly.\n process.once(\"SIGINT\", () => server.close());\n process.once(\"SIGTERM\", () => server.close());\n return [{ text: url, data: { url, workspace: root } }, EXIT_OK];\n}\n\nconst DASHBOARD_HTML = `<!doctype html><html lang=\"zh\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>scriptctl ingest \u76D1\u542C</title>\n<style>\n:root{--bg:#f6f7f9;--panel:#ffffff;--panel2:#f0f2f5;--line:#e3e6ea;--fg:#1f2430;--dim:#6b7280;--acc:#2563eb;--ok:#16a34a;--warn:#d97706;--err:#dc2626}\n*{box-sizing:border-box}body{margin:0;font:13px/1.5 -apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif;background:var(--bg);color:var(--fg);height:100vh;display:grid;grid-template-rows:auto auto 1fr}\nheader{padding:12px 16px;background:var(--panel);border-bottom:1px solid var(--line);display:flex;gap:16px;align-items:center;flex-wrap:wrap}\nheader .title{font-weight:700;font-size:15px}\n.now{font-size:14px}.now b{color:var(--acc)}\n.state{padding:3px 12px;border-radius:20px;font-weight:600;font-size:12px}\n.state.ready{background:#e7f6ee;color:var(--ok)}.state.incomplete{background:#e8f0fe;color:var(--acc)}.state.failed{background:#fde8e8;color:var(--err)}.state.empty{background:var(--panel2);color:var(--dim)}\n.dim{color:var(--dim)}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}\n/* overall bar + stage stepper */\n.progress{background:var(--panel);border-bottom:1px solid var(--line);padding:12px 16px}\n.ovwrap{display:flex;align-items:center;gap:10px;margin-bottom:12px}\n.ovtrack{flex:1;height:10px;background:var(--panel2);border-radius:6px;overflow:hidden}\n.ovtrack i{display:block;height:100%;background:linear-gradient(90deg,#3b82f6,#2563eb);border-radius:6px;transition:width .4s}\n.ovpct{font-weight:700;min-width:44px;text-align:right}\n.stages{display:flex;align-items:stretch;gap:0}\n.stage{flex:1;padding:8px 12px;border:1px solid var(--line);background:var(--panel);border-radius:8px;margin-right:8px}\n.stage:last-child{margin-right:0}\n.stage-h{display:flex;align-items:center;gap:7px;font-weight:600}\n.stage .dot{width:9px;height:9px;border-radius:50%;background:#cbd2dc;flex:none}\n.stage .cnt{margin-left:auto;font-size:12px;color:var(--dim)}\n.stage .track{height:6px;background:var(--panel2);border-radius:4px;margin-top:8px;overflow:hidden}\n.stage .track i{display:block;height:100%;width:0;border-radius:4px;transition:width .4s}\n.stage.wait{opacity:.7}\n.stage.done{border-color:#bfe6cd}.stage.done .dot{background:var(--ok)}.stage.done .track i{background:var(--ok)}.stage.done .stage-h b{color:var(--ok)}\n.stage.run{border-color:#bcd3fb;box-shadow:0 0 0 2px #e8f0fe}.stage.run .dot{background:var(--acc);animation:pulse 1.2s infinite}.stage.run .track i{background:var(--acc)}\n.stage.fail{border-color:#f3bcbc}.stage.fail .dot{background:var(--err)}.stage.fail .track i{background:var(--err)}\n@keyframes pulse{50%{opacity:.35}}\nmain{display:grid;grid-template-columns:280px 1fr;min-height:0}\naside{background:var(--panel);border-right:1px solid var(--line);overflow:auto;padding:8px}\n.grp{margin:8px 4px 2px;color:var(--dim);font-size:11px;font-weight:700;letter-spacing:.04em}\n.f{padding:4px 8px;border-radius:6px;cursor:pointer;display:flex;justify-content:space-between;gap:8px;white-space:nowrap;overflow:hidden}\n.f:hover{background:var(--panel2)}.f.sel{background:#e8f0fe;color:var(--acc);font-weight:600}\n.f .sz{color:var(--dim);font-size:11px}\nsection{overflow:auto;background:var(--panel)}\n.toolbar{position:sticky;top:0;background:var(--panel2);border-bottom:1px solid var(--line);padding:6px 12px;display:flex;gap:14px;align-items:center;font-size:12px}\nlabel{cursor:pointer;user-select:none}.empty{color:var(--dim);padding:34px;text-align:center}\n#view{padding:14px 18px;white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px}\n#view h1,#view h2{margin:14px 0 4px}#view h1{color:var(--acc);font-size:15px}#view h2{color:var(--warn);font-size:13px}\n#view .b{color:var(--dim)}\n/* per-episode timing table (video only) */\n.timing{padding:8px 16px 4px;background:var(--panel);border-bottom:1px solid var(--line);overflow:auto;max-height:132px}\ntable.tm{border-collapse:collapse;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}\ntable.tm th,table.tm td{padding:2px 10px 2px 0;text-align:right}table.tm th:first-child,table.tm td:first-child{text-align:left}\ntable.tm th{color:var(--dim);font-weight:600;border-bottom:1px solid var(--line)}\ntable.tm td.slow{color:var(--warn)}\n</style></head><body>\n<header>\n <span class=\"title\">scriptctl ingest</span>\n <span id=\"stateBadge\" class=\"state empty\">\u2014</span>\n <span class=\"now\">\u5F53\u524D\uFF1A<b id=\"curState\">\u2014</b></span>\n <span class=\"now\">\u8017\u65F6 <b id=\"elapsed\">\u2014</b></span>\n <span class=\"dim\" id=\"eta\"></span>\n <span class=\"now\" id=\"tokWrap\" style=\"display:none\">Token <b id=\"tokTotal\">\u2014</b> <span class=\"dim\" id=\"tokIO\"></span></span>\n <span class=\"dim mono\" id=\"root\" style=\"margin-left:auto\"></span>\n <span class=\"dim\" id=\"tick\"></span>\n</header>\n<div class=\"progress\">\n <div class=\"ovwrap\"><span class=\"dim\">\u603B\u8FDB\u5EA6</span><div class=\"ovtrack\"><i id=\"ovBar\"></i></div><span class=\"ovpct\" id=\"ovPct\">0%</span></div>\n <div class=\"stages\" id=\"stages\"></div>\n</div>\n<div class=\"timing\" id=\"timingWrap\" style=\"display:none\"><table class=\"tm\" id=\"tmTable\"></table></div>\n<div class=\"timing\" id=\"usageWrap\" style=\"display:none\"><table class=\"tm\" id=\"usageTable\"></table></div>\n<main>\n <aside id=\"side\"></aside>\n <section>\n <div class=\"toolbar\">\n <span id=\"cur\" class=\"mono dim\">\u672A\u9009\u62E9\u6587\u4EF6</span>\n <label style=\"margin-left:auto\"><input type=\"checkbox\" id=\"follow\" checked> \u8DDF\u968F\u6700\u65B0\u96C6</label>\n </div>\n <div id=\"view\"><div class=\"empty\">\u5DE6\u4FA7\u9009\u62E9\u6587\u4EF6\uFF0C\u6216\u7B49\u5F85 ingest \u4EA7\u51FA\u2026</div></div>\n </section>\n</main>\n<script>\nvar NAMES={normalize:'\u89C4\u8303\u5316',assemble:'\u88C5\u914D',serial:'\u4E32\u884C\u89E3\u6790',govern:'\u6CBB\u7406\u6210\u7A3F',finalize:'\u6CBB\u7406\u6210\u7A3F',transcribe:'\u8F6C\u5199',roster:'\u89D2\u8272\u5408\u5E76',correct:'\u6821\u6B63',speaker:'\u53D1\u58F0\u6E90'};\nvar cur=null, follow=true, lastLatest=null;\nvar timing=null, timingAt=0; // last status.timings + client time it arrived (avoids clock skew)\nfunction $(s){return document.querySelector(s)}\nfunction fmtDur(ms){if(ms==null)return '\u2014';var s=Math.round(ms/1000);return s>=60?(Math.floor(s/60)+'m'+('0'+(s%60)).slice(-2)+'s'):s+'s'}\n// per-episode timing table (video only; hidden when there is no timing.jsonl)\nfunction fmtTok(n){if(n==null)return '\u2014';if(n>=1e6)return (n/1e6).toFixed(2)+'M';if(n>=1e3)return (n/1e3).toFixed(1)+'k';return ''+n}\nvar TASKNAMES={'ingest.body-start':'\u6B63\u6587\u5B9A\u4F4D','ingest.text-normalize':'\u89C4\u8303\u5316','ingest.serial-govern':'\u4E32\u884C\u6CBB\u7406','ingest.name-fix':'\u547D\u540D\u4FEE\u590D','ingest.episode-assets':'\u5206\u96C6\u8D44\u4EA7','ingest.asset-curate':'\u8D44\u4EA7\u7504\u9009','ingest.asset-govern':'\u8D44\u4EA7\u603B\u89C8','ingest.arc-summary':'\u7BC7\u7AE0\u6897\u6982','ingest.state-reconcile':'\u72B6\u6001\u5F52\u5E76','ingest.asset-audit':'\u8D44\u4EA7\u5BA1\u8BA1','ingest.mention-resolve':'\u6307\u79F0\u6D88\u89E3','ingest.video-serial':'\u89C6\u9891\u4E32\u884C'};\n// Token accounting table + header badge. Hidden until usage.json exists.\nfunction renderUsage(u){\n if(!u||!u.totals){$('#usageWrap').style.display='none';$('#tokWrap').style.display='none';return}\n var t=u.totals;\n $('#tokWrap').style.display='';\n $('#tokTotal').textContent=fmtTok(t.totalTokens);\n var cacheHit=(t.cachedInputTokens||0),cacheNew=(t.cacheCreationTokens||0);\n var cacheStr=(cacheHit||cacheNew)?' \u00B7 \u7F13\u5B58\u547D\u4E2D '+fmtTok(cacheHit)+(cacheNew?'/\u5EFA '+fmtTok(cacheNew):''):'';\n $('#tokIO').textContent='(\u5165 '+fmtTok(t.inputTokens)+' / \u51FA '+fmtTok(t.outputTokens)+cacheStr+' \u00B7 '+t.calls+'\u6B21'+(t.reused?' \u00B7 \u590D\u7528'+t.reused:'')+')';\n var rows=[];\n (u.byTask||[]).forEach(function(task){\n (task.byModel||[]).forEach(function(model){\n var r=model.totals||{};\n if(r.calls>0||r.reused>0||r.inputTokens>0||r.outputTokens>0)rows.push({task:task.task,model:model.model,provider:model.provider,totals:r});\n });\n });\n if(!rows.length){$('#usageWrap').style.display='none';return}\n rows.sort(function(a,b){return (b.totals.totalTokens||0)-(a.totals.totalTokens||0)});\n $('#usageWrap').style.display='block';\n var h=['<tr><th>\u4EFB\u52A1</th><th>\u6A21\u578B</th><th>\u8C03\u7528</th><th>\u5931\u8D25</th><th>\u590D\u7528</th><th>\u5165token</th><th title=\"\u7F13\u5B58\u547D\u4E2D/\u65B0\u5EFA\uFF0C\u5747\u4E3A\u5165token\u7684\u5B50\u96C6\">\u7F13\u5B58(\u547D\u4E2D/\u5EFA)</th><th>\u51FAtoken</th><th>\u5408\u8BA1</th></tr>'];\n rows.forEach(function(row){\n var r=row.totals,ch=r.cachedInputTokens||0,cn=r.cacheCreationTokens||0;\n h.push('<tr><td>'+(TASKNAMES[row.task]||row.task)+'</td><td class=\"mono\">'+row.provider+'/'+row.model+'</td><td>'+r.calls+'</td><td>'+(r.failed||0)+'</td><td>'+(r.reused||0)+'</td><td>'+fmtTok(r.inputTokens)+'</td><td class=\"dim\">'+(ch||cn?fmtTok(ch)+'/'+fmtTok(cn):'\u2014')+'</td><td>'+fmtTok(r.outputTokens)+'</td><td>'+fmtTok(r.totalTokens)+'</td></tr>');\n });\n h.push('<tr><td class=\"dim\">\u5408\u8BA1</td><td></td><td class=\"dim\">'+t.calls+'</td><td class=\"dim\">'+t.failed+'</td><td class=\"dim\">'+t.reused+'</td><td class=\"dim\">'+fmtTok(t.inputTokens)+'</td><td class=\"dim\">'+(t.cachedInputTokens||t.cacheCreationTokens?fmtTok(t.cachedInputTokens||0)+'/'+fmtTok(t.cacheCreationTokens||0):'\u2014')+'</td><td class=\"dim\">'+fmtTok(t.outputTokens)+'</td><td class=\"dim\">'+fmtTok(t.totalTokens)+'</td></tr>');\n $('#usageTable').innerHTML=h.join('');\n}\nfunction renderEpTiming(tm){\n if(!tm||!tm.episodes||!tm.episodes.length){$('#timingWrap').style.display='none';return}\n $('#timingWrap').style.display='block';\n var rows=['<tr><th>\u96C6</th><th>\u8F6C\u7801</th><th>\u5927\u5C0F</th><th>\u4E0A\u4F20</th><th>\u89E3\u6790</th></tr>'];\n tm.episodes.forEach(function(e){\n var slow=e.generateMs>60000?' class=\"slow\"':'';\n rows.push('<tr><td>ep'+('00'+e.episode).slice(-3)+'</td><td>'+fmtDur(e.transcodeMs)+(e.transcoded===false?'*':'')+'</td><td>'+(e.uploadMB||'?')+'M</td><td>'+fmtDur(e.uploadMs)+'</td><td'+slow+'>'+fmtDur(e.generateMs)+'</td></tr>');\n });\n rows.push('<tr><td class=\"dim\">\u7D2F\u8BA1</td><td></td><td></td><td></td><td class=\"dim\">'+fmtDur(tm.totalMs)+'</td></tr>');\n $('#tmTable').innerHTML=rows.join('');\n}\n// tick the total elapsed locally between polls; serial ETA/rate from the summary\nfunction renderTiming(){\n if(!timing){$('#elapsed').textContent='\u2014';$('#eta').textContent='';return}\n var live=timing.elapsedMs+(timing.done?0:(Date.now()-timingAt));\n $('#elapsed').textContent=fmtDur(live)+(timing.done?'':' \u2026');\n var ser=timing.serial,eta='';\n if(ser){\n eta='\u4E32\u884C '+ser.doneWindows+'/'+ser.totalWindows+' \u7A97\u53E3';\n if(ser.avgWindowMs!=null)eta+=' \u00B7 ~'+fmtDur(ser.avgWindowMs)+'/\u7A97';\n if(ser.etaMs!=null&&!timing.done)eta+=' \u00B7 \u9884\u8BA1\u5269\u4F59 '+fmtDur(ser.etaMs);\n }\n $('#eta').textContent=eta;\n}\n$('#follow').onchange=function(e){follow=e.target.checked};\nfunction esc(s){return s.replace(/[&<>]/g,function(c){return{'&':'&','<':'<','>':'>'}[c]})}\nfunction renderContent(rel,text){\n if(rel.endsWith('.jsonl')){$('#view').textContent=text.split('\\\\n').map(function(l){try{return JSON.stringify(JSON.parse(l))}catch(e){return l}}).join('\\\\n');return}\n if(rel.endsWith('.json')){try{text=JSON.stringify(JSON.parse(text),null,2)}catch(e){}$('#view').textContent=text;return}\n if(rel.endsWith('.md')){\n $('#view').innerHTML=text.split('\\\\n').map(function(l){\n if(l.indexOf('## ')===0)return '<h2>'+esc(l.slice(3))+'</h2>';\n if(l.indexOf('# ')===0)return '<h1>'+esc(l.slice(2))+'</h1>';\n if(l.indexOf(' ')===0||l.indexOf('- ')===0||l.indexOf('> ')===0)return '<span class=\"b\">'+esc(l)+'</span>';\n return esc(l)||' ';\n }).join('\\\\n');return}\n $('#view').textContent=text;\n}\nfunction loadFile(rel){\n cur=rel;$('#cur').textContent=rel;\n var fs=document.querySelectorAll('.f');for(var i=0;i<fs.length;i++)fs[i].classList.toggle('sel',fs[i].dataset.rel===rel);\n fetch('/api/file?path='+encodeURIComponent(rel)).then(function(r){return r.text()}).then(function(t){renderContent(rel,t)}).catch(function(){});\n}\nfunction frac(p){return p.unit&&p.unit.total?p.unit.done/p.unit.total:(p.done?1:0)}\nfunction poll(){\n fetch('/api/state').then(function(r){return r.json()}).then(function(d){\n var s=d.status,passes=s.passes||[];\n $('#root').textContent=d.root;\n $('#stateBadge').className='state '+s.state;\n $('#stateBadge').textContent={ready:'\u5DF2\u5B8C\u6210',incomplete:'\u8FDB\u884C\u4E2D',failed:'\u5931\u8D25',empty:'\u7A7A'}[s.state]||s.state;\n // overall progress = mean of per-stage fractions\n var sum=0;passes.forEach(function(p){sum+=frac(p)});\n var pct=passes.length?Math.round(100*sum/passes.length):0;\n $('#ovBar').style.width=pct+'%';$('#ovPct').textContent=pct+'%';\n // current stage\n var curP=null;for(var i=0;i<passes.length;i++){if(!passes[i].done){curP=passes[i];break}}\n $('#curState').textContent=s.state==='ready'?'\u5DF2\u5B8C\u6210 \u2713':(curP?(NAMES[curP.name]||curP.name)+(curP.unit?' \u00B7 '+curP.unit.done+'/'+curP.unit.total:''):'\u2014');\n // per-phase durations from timings (real wall-clock)\n var ph={};((s.timings&&s.timings.phases)||[]).forEach(function(x){ph[x.name]=x});\n // staged stepper with per-stage bars + real durations\n $('#stages').innerHTML=passes.map(function(p){\n var st=p.done?'done':(p.unit&&p.unit.failed?'fail':(p.unit&&p.unit.done>0||p===curP?'run':'wait'));\n var cnt=p.unit?(p.unit.done+'/'+p.unit.total+(p.unit.failed?' \u2717'+p.unit.failed:'')):(p.done?'\u2713':'\u2014');\n var d=ph[p.name]?('<span class=\"cnt\">'+fmtDur(ph[p.name].ms)+(ph[p.name].running?' \u2026':'')+'</span>'):'';\n return '<div class=\"stage '+st+'\"><div class=\"stage-h\"><span class=\"dot\"></span><b>'+(NAMES[p.name]||p.name)+'</b><span class=\"cnt\">'+cnt+'</span></div><div class=\"track\"><i style=\"width:'+Math.round(frac(p)*100)+'%\"></i></div>'+(d?'<div class=\"dim\" style=\"margin-top:4px\">'+d+'</div>':'')+'</div>';\n }).join('');\n timing=s.timings||null;timingAt=Date.now();renderTiming();\n renderEpTiming(d.timing);\n renderUsage(d.usage);\n // sidebar\n var html='',latest=null;\n Object.keys(d.groups).forEach(function(grp){\n var files=d.groups[grp];if(!files.length)return;html+='<div class=\"grp\">'+grp+'</div>';\n files.forEach(function(f){\n html+='<div class=\"f\" data-rel=\"'+f.rel+'\"><span>'+f.rel.split('/').pop()+'</span><span class=\"sz\">'+(f.size>1024?(f.size/1024).toFixed(0)+'k':f.size)+'</span></div>';\n if(grp==='\u6BCF\u7A97\u66F4\u65B0'||grp==='\u4E0A\u4E0B\u6587'||grp==='\u8F6C\u5F55'||grp==='\u89E3\u6790')latest=f.rel;\n });\n });\n $('#side').innerHTML=html;\n var els=document.querySelectorAll('.f');\n for(var j=0;j<els.length;j++){(function(el){el.onclick=function(){follow=false;$('#follow').checked=false;loadFile(el.dataset.rel)};if(el.dataset.rel===cur)el.classList.add('sel')})(els[j])}\n $('#tick').textContent='\u25CF '+new Date().toLocaleTimeString();\n if(follow&&latest&&latest!==lastLatest){lastLatest=latest;loadFile(latest)}\n else if(cur){loadFile(cur)}\n }).catch(function(){$('#tick').textContent='\u25CF \u79BB\u7EBF'});\n}\npoll();setInterval(poll,1500);setInterval(renderTiming,1000);\n</script></body></html>`;\n", "import * as path from \"node:path\";\n\nimport { EXIT_NEEDS_AGENT, EXIT_OK, type CommandOutput } from \"../../common.js\";\nimport { atomicWriteJson, assertScriptUnchanged } from \"../../infra/script-working-copy.js\";\nimport { PRODUCTION_LLM_COMPOSITION, type LlmComposition } from \"../../llm/composition.js\";\nimport { assetAuditIssueLine, auditScriptAssets } from \"../ingest/final-asset-audit.js\";\nimport { loadScriptForEdit } from \"./session.js\";\nimport { type Dict, strOf } from \"../../domain/script/shared.js\";\n\nexport async function commandAuditAssets(\n opts: Dict,\n composition: LlmComposition = PRODUCTION_LLM_COMPOSITION,\n): Promise<[CommandOutput, number]> {\n const session = await loadScriptForEdit(opts);\n const executor = composition.createExecutor(strOf(opts[\"llm_config\"]).trim() || undefined);\n const audit = await auditScriptAssets(session.script, executor);\n\n // A model call can take long enough for another process to edit script.json.\n // Never attach the old audit to a newer script revision.\n if (session.scriptPath) assertScriptUnchanged(session.scriptPath, session.baselineHash);\n const baseDir = session.scriptPath ? path.dirname(session.scriptPath) : path.resolve(session.workspace);\n const outputPath = path.resolve(strOf(opts[\"output\"]).trim() || path.join(baseDir, \"asset-audit.json\"));\n atomicWriteJson(outputPath, audit);\n\n const hasIssues = audit.issues.length > 0;\n const issueLines = audit.issues.map(assetAuditIssueLine);\n const summary = `${audit.summary.issues} issues; confidence high=${audit.summary.high} medium=${audit.summary.medium} low=${audit.summary.low}`;\n const hint = \"Inspect each finding, repair confirmed duplicates, then rerun `scriptctl audit-assets` and `scriptctl validate`.\";\n const report: CommandOutput = {\n text: [summary, ...issueLines, `output: ${outputPath}`, ...(hasIssues ? [hint] : [])].join(\"\\n\"),\n data: {\n op: \"script.audit-assets\",\n changed: false,\n issues: audit.issues,\n output: outputPath,\n asset_audit: audit,\n config_source: executor.configSource,\n llm_routes: executor.usage(),\n },\n };\n return [report, hasIssues ? EXIT_NEEDS_AGENT : EXIT_OK];\n}\n", "import { CliError, EXIT_INPUT } from \"../../common.js\";\nimport { requireScriptV3 } from \"./v3/parse.js\";\nimport type { ScriptV3 } from \"./v3/types.js\";\nimport { requireScriptV4, requireStructurallyReadableScriptV4 } from \"./v4/parse.js\";\nimport type { ScriptV4 } from \"./v4/types.js\";\nimport { validateScriptV4 } from \"./v4/validation.js\";\nimport { validateScriptV3 } from \"./v3/validation.js\";\nimport type { ValidationResult } from \"./shared/validation.js\";\n\nexport type ScriptVersion = 3 | 4;\nexport type ScriptDocument = ScriptV3 | ScriptV4;\nexport const SUPPORTED_SCRIPT_VERSIONS: readonly ScriptVersion[] = [3, 4];\n\ntype Versioned<T> = Readonly<Record<ScriptVersion, T>>;\n\nexport interface ScriptDialect {\n readonly version: ScriptVersion;\n readonly require: (value: unknown) => ScriptDocument;\n readonly requireStructurallyReadable: (value: unknown) => ScriptDocument;\n readonly validate: (value: unknown) => ValidationResult;\n}\n\nconst DIALECTS: Versioned<ScriptDialect> = {\n 3: {\n version: 3,\n require: requireScriptV3,\n requireStructurallyReadable: requireScriptV3,\n validate: validateScriptV3,\n },\n 4: {\n version: 4,\n require: requireScriptV4,\n requireStructurallyReadable: requireStructurallyReadableScriptV4,\n validate: validateScriptV4,\n },\n};\n\nexport function isSupportedScriptVersion(value: unknown): value is ScriptVersion {\n return typeof value === \"number\"\n && SUPPORTED_SCRIPT_VERSIONS.some((version) => version === value);\n}\n\nexport function scriptVersionOf(value: unknown): ScriptVersion {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new CliError(\"script.json must be an object with an explicit version.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_VERSION_MISSING\",\n data: { expected: [\"version: 3 or version: 4\"], actual: [Array.isArray(value) ? \"array\" : typeof value] },\n });\n }\n const version = (value as Record<string, unknown>).version;\n if (isSupportedScriptVersion(version)) return version;\n throw new CliError(\"script.json must declare version 3 or version 4.\", {\n exitCode: EXIT_INPUT,\n errorCode: version === undefined ? \"SCRIPT_VERSION_MISSING\" : \"SCRIPT_VERSION_UNSUPPORTED\",\n hint: \"Use an explicit supported script version; scriptctl does not infer a version from document shape.\",\n data: { expected: [\"version: 3 or version: 4\"], actual: [String(version)] },\n });\n}\n\nexport function dialectFor(value: unknown): ScriptDialect {\n return DIALECTS[scriptVersionOf(value)];\n}\n\nexport function requireScriptDocument(value: unknown): ScriptDocument {\n return dialectFor(value).require(value);\n}\n\nexport function requireStructurallyReadableScriptDocument(value: unknown): ScriptDocument {\n return dialectFor(value).requireStructurallyReadable(value);\n}\n\nexport function validateScriptDocument(value: unknown): ValidationResult {\n return dialectFor(value).validate(value);\n}\n", "// fast-json-patch ships as CommonJS with no named ESM exports, so under Node's\n// ESM resolver only the default (the module.exports object) is available. Pull\n// `compare` off it rather than importing it by name (which fails at runtime).\nimport fastJsonPatch from \"fast-json-patch\";\nconst { compare } = fastJsonPatch;\n\nimport {\n ScriptOutputApiError,\n type PatchScriptOptions,\n type PublishPatchOptions,\n type ReplaceScriptOptions,\n type SaveValidationOptions,\n type ScriptSnapshot,\n type ScriptOutputStore,\n} from \"./script-output-store.js\";\n\n// Re-export the shared error/types so existing callers that import them from\n// this module keep compiling. New code should import directly from\n// ./script-output-store.js \u2014 the shared module is the single source of truth.\nexport {\n ScriptOutputApiError,\n type ScriptOutputApiErrorOptions,\n type PatchScriptOptions,\n type PublishPatchOptions,\n type ReplaceScriptOptions,\n type SaveValidationOptions,\n type ScriptSnapshot,\n type ScriptOutputStore,\n} from \"./script-output-store.js\";\n\nconst SCRIPT_OUTPUT_PREFIX = \"/api/anime/workbench/script-output/project-groups\";\n// V2 adds an isolated publish endpoint while preserving the legacy PUT/PATCH\n// contracts. Same gateway base + the same\n// X-Access-Key auth as V1; only the path prefix and the write shape differ.\nconst SCRIPT_V2_PREFIX = \"/api/anime/workbench/v2/script/project-groups\";\n// Project-group metadata lives on a DIFFERENT controller (not under the\n// script-output prefix). Same gateway base + X-Access-Key auth, same\n// {code,msg,data} envelope. \"\u6709\u503C\u624D\u66F4\u65B0\": send only the fields we want changed.\nconst PROJECT_GROUP_UPDATE_PATH = \"/api/anime/workbench/projectGroup/updateProjectGroupInfo\";\n// Best-effort metadata write \u2014 keep its timeout short so a hung gateway can't\n// stall init's exit for the full 30s default the script writes use.\nconst PROJECT_GROUP_UPDATE_TIMEOUT_MS = 5000;\nconst IMPORT_BODY_LIMIT_BYTES = 8 * 1024 * 1024;\n\nexport function normalizeGatewayBase(value: string): string {\n let base = value.trim().replace(/\\/+$/, \"\");\n for (const suffix of [\"/api/anime/workbench\", \"/api/sandbox\"]) {\n if (base.endsWith(suffix)) {\n base = base.slice(0, -suffix.length);\n break;\n }\n }\n return base.replace(/\\/+$/, \"\");\n}\n\nexport function quotePath(value: string): string {\n return encodeURIComponent(String(value));\n}\n\nfunction apiErrorFromText(text: string, status: number, path: string): ScriptOutputApiError {\n if (status === 404 && path.includes(\"/imports\")) {\n return new ScriptOutputApiError(\"backend lacks episode import API\", { status, payload: text });\n }\n let payload: unknown = null;\n try {\n payload = text ? JSON.parse(text) : null;\n } catch {\n payload = null;\n }\n if (payload && typeof payload === \"object\") {\n const obj = payload as Record<string, unknown>;\n const message = String(obj.msg ?? obj.message ?? `HTTP ${status}`);\n return new ScriptOutputApiError(message, { status, code: (obj.code as number | string | null) ?? null, payload: obj });\n }\n return new ScriptOutputApiError(text || `HTTP ${status}`, { status, payload: text });\n}\n\nfunction assertImportBodySize(label: string, body: unknown): void {\n const bytes = Buffer.byteLength(JSON.stringify(body), \"utf8\");\n if (bytes <= IMPORT_BODY_LIMIT_BYTES) return;\n // V2 sends the whole document (root) or an RFC6902 diff (patch) in one body \u2014\n // neither is chunkable by episode/scene, so keep the message generic.\n throw new ScriptOutputApiError(\n `script ${label} body too large: ${bytes} bytes (limit ${IMPORT_BODY_LIMIT_BYTES})`,\n );\n}\n\n// Shared gateway transport for both V1 (RemoteScriptOutputStore) and V2\n// (ScriptV2OutputStore): same X-Access-Key auth, same timeout/abort handling,\n// same `{code,msg,data}` envelope unwrap and `\u5267\u672C\u4E0D\u5B58\u5728` \u2192 null (allowMissing)\n// convention. Extracted so the two stores can't drift on error handling.\nasync function gatewayRequest(\n gatewayBase: string,\n accessKey: string,\n timeoutMs: number,\n method: string,\n path: string,\n opts: { body?: unknown; allowMissing?: boolean } = {},\n): Promise<unknown> {\n const rawBody = opts.body === undefined ? undefined : JSON.stringify(opts.body);\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n \"X-Access-Key\": accessKey,\n };\n if (rawBody !== undefined) headers[\"Content-Type\"] = \"application/json; charset=utf-8\";\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let status: number;\n let text: string;\n try {\n const response = await fetch(`${gatewayBase}${path}`, {\n method,\n headers,\n body: rawBody,\n signal: controller.signal,\n });\n status = response.status;\n text = await response.text();\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new ScriptOutputApiError(\"Gateway request timed out\");\n }\n const reason = err instanceof Error ? err.message : String(err);\n throw new ScriptOutputApiError(`Gateway request failed: ${reason}`);\n } finally {\n clearTimeout(timer);\n }\n\n if (status >= 400) throw apiErrorFromText(text, status, path);\n\n let payload: unknown = null;\n if (text) {\n try {\n payload = JSON.parse(text);\n } catch {\n throw new ScriptOutputApiError(\"Gateway response is not valid JSON\", { status, payload: text });\n }\n }\n if (payload === null) return null;\n if (typeof payload !== \"object\") return payload;\n\n const obj = payload as Record<string, unknown>;\n const code = obj.code;\n if (code !== undefined && code !== null && String(code) !== \"200\") {\n const message = String(obj.msg ?? obj.message ?? \"script-output API failed\");\n if (opts.allowMissing && typeof message === \"string\" && message.includes(\"\u5267\u672C\u4E0D\u5B58\u5728\")) return null;\n throw new ScriptOutputApiError(message, { status, code: code as number | string, payload: obj });\n }\n if (\"data\" in obj) return obj.data;\n return obj;\n}\n\n/**\n * V2 script-output store. Same gateway base + X-Access-Key auth as V1, but:\n * - publishPatch uses the dedicated strict-CAS publish endpoint.\n * - replaceScript and patchScript retain the legacy endpoint contracts.\n * - patchScript sends an RFC6902 PATCH (the compare() diff of old\u2192edited),\n * which V1 cannot do (it degrades to a whole-document replace).\n *\n * Selected over V1 by the `SCRIPT_OUTPUT_API_VERSION=v2` env (see\n * remoteScriptOutputStoreFromEnv). Endpoints:\n * GET {prefix}/{projectGroupNo}\n * GET {prefix}/{projectGroupNo}/revision\n * GET {prefix}/{projectGroupNo}/snapshot\n * PATCH {prefix}/{projectGroupNo}/publish { baseRevision, patch, validation }\n * PATCH {prefix}/{projectGroupNo} RFC6902 patch array (wrapped with requestId)\n * DELETE {prefix}/{projectGroupNo}\n */\nexport class ScriptV2OutputStore implements ScriptOutputStore {\n readonly gatewayBase: string;\n readonly projectGroupNo: string;\n readonly accessKey: string;\n readonly timeoutMs: number;\n\n constructor(opts: {\n gatewayBase: string;\n projectGroupNo: string;\n accessKey: string;\n timeoutMs?: number;\n }) {\n this.gatewayBase = opts.gatewayBase;\n this.projectGroupNo = opts.projectGroupNo;\n this.accessKey = opts.accessKey;\n // checkout/publish may transfer a full large snapshot over a weak network.\n this.timeoutMs = opts.timeoutMs ?? 300_000;\n }\n\n static fromEnv(projectGroupNo?: string | null): ScriptV2OutputStore {\n const resolved = (projectGroupNo ?? process.env.SANDBOX_PROJECT_GROUP_NO ?? \"\").trim();\n if (!resolved) {\n throw new ScriptOutputApiError(\n \"projectGroupNo missing; pass --project-group-no or set SANDBOX_PROJECT_GROUP_NO\",\n { configMissing: \"project\" },\n );\n }\n const gatewayBase = normalizeGatewayBase(process.env.AWB_BASE_URL || \"\");\n if (!gatewayBase) {\n throw new ScriptOutputApiError(\"gateway URL missing; set AWB_BASE_URL\", { configMissing: \"gateway\" });\n }\n const accessKey = (process.env.LINGJING_AWB_ACCESS_KEY || \"\").trim();\n if (!accessKey) {\n throw new ScriptOutputApiError(\"access key missing; set LINGJING_AWB_ACCESS_KEY\", { configMissing: \"access\" });\n }\n return new ScriptV2OutputStore({ gatewayBase, projectGroupNo: resolved, accessKey });\n }\n\n private get projectPrefix(): string {\n return `${SCRIPT_V2_PREFIX}/${quotePath(this.projectGroupNo)}`;\n }\n\n async getScript(): Promise<Record<string, unknown> | null> {\n return (await this.request(\"GET\", this.projectPrefix, { allowMissing: true })) as\n | Record<string, unknown>\n | null;\n }\n\n async getRevision(): Promise<Record<string, unknown> | null> {\n return (await this.request(\"GET\", `${this.projectPrefix}/revision`, { allowMissing: true })) as\n | Record<string, unknown>\n | null;\n }\n\n async getSnapshot(): Promise<ScriptSnapshot | null> {\n return (await this.request(\"GET\", `${this.projectPrefix}/snapshot`, { allowMissing: true })) as ScriptSnapshot | null;\n }\n\n async publishPatch(opts: PublishPatchOptions): Promise<Record<string, unknown>> {\n return (await this.request(\"PATCH\", `${this.projectPrefix}/publish`, {\n body: {\n baseRevision: opts.baseRevision,\n patch: compare(opts.old, opts.edited),\n validation: opts.validation,\n },\n })) as Record<string, unknown>;\n }\n\n async replaceScript(opts: ReplaceScriptOptions): Promise<Record<string, unknown>> {\n // V2 takes the whole script in one PUT \u2014 assert the same body-size limit as\n // V1's begin body so an oversized document fails fast with the same error.\n const body = {\n requestId: opts.requestId,\n baseRevision: opts.baseRevision,\n source: opts.source ?? \"ctl\",\n script: opts.script,\n };\n assertImportBodySize(\"root\", body);\n return (await this.request(\"PUT\", this.projectPrefix, { body })) as Record<string, unknown>;\n }\n\n // True incremental edit: send the RFC6902 diff of old\u2192edited. An empty diff\n // (no observable change) still goes through so the gateway can bump/no-op the\n // revision consistently with replaceScript's idempotency contract.\n async patchScript(opts: PatchScriptOptions): Promise<Record<string, unknown>> {\n const patch = compare(opts.old, opts.edited);\n const body = {\n requestId: opts.requestId,\n baseRevision: opts.baseRevision,\n source: opts.source ?? \"ctl\",\n patch,\n };\n // patchScript is now the primary save path \u2014 guard the diff body against the\n // same import-size limit replaceScript uses, so an oversized edit fails fast\n // with a clear error instead of an opaque gateway/Spring 413.\n assertImportBodySize(\"patch\", body);\n return (await this.request(\"PATCH\", this.projectPrefix, { body })) as Record<string, unknown>;\n }\n\n async saveValidationResult(opts: SaveValidationOptions): Promise<Record<string, unknown> | null> {\n // V2 has its own validation-result endpoint (the script lives in script_v2,\n // not the V1 tables, so the V1 path would 404 \"\u5267\u672C\u4E0D\u5B58\u5728\"). Same body shape;\n // the V2 backend persists status/summary on the row and ignores issues.\n return (await this.request(\n \"POST\",\n `${SCRIPT_V2_PREFIX}/${quotePath(this.projectGroupNo)}/validation-result`,\n {\n body: {\n revision: opts.revision,\n validationStatus: opts.validationStatus,\n validationSummary: opts.validationSummary,\n issues: opts.issues,\n },\n },\n )) as Record<string, unknown> | null;\n }\n\n // Best-effort: set the project group's episode_count. Only episodeCount is\n // sent so the cover key is left untouched (\"\u6709\u503C\u624D\u66F4\u65B0\"). Callers wrap this in\n // syncEpisodeCount, which swallows failures \u2014 never let it fail a script write.\n async updateEpisodeCount(episodeCount: number): Promise<void> {\n await gatewayRequest(\n this.gatewayBase,\n this.accessKey,\n Math.min(this.timeoutMs, PROJECT_GROUP_UPDATE_TIMEOUT_MS),\n \"POST\",\n PROJECT_GROUP_UPDATE_PATH,\n { body: { projectGroupNo: this.projectGroupNo, episodeCount } },\n );\n }\n\n private async request(\n method: string,\n path: string,\n opts: { body?: unknown; allowMissing?: boolean } = {},\n ): Promise<unknown> {\n return gatewayRequest(this.gatewayBase, this.accessKey, this.timeoutMs, method, path, opts);\n }\n}\n\n/**\n * Build the remote script-output store. The CLI is V2-only: every write goes to\n * the single-PUT / incremental-PATCH blob store, the same backend the frontend\n * writes to \u2014 so the two never split-brain across V1/V2. The legacy begin\u2192commit\n * V1 client was removed; there is no version flag.\n */\nexport function remoteScriptOutputStoreFromEnv(projectGroupNo?: string | null): ScriptV2OutputStore {\n return ScriptV2OutputStore.fromEnv(projectGroupNo);\n}\n", "import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nimport {\n CliError,\n EXIT_INPUT,\n EXIT_NEEDS_AGENT,\n EXIT_OK,\n EXIT_RUNTIME,\n EXIT_USAGE,\n type CommandOutput,\n directDir,\n exists,\n readJson,\n readText,\n scriptJsonPath,\n sha256Text,\n writeJson,\n} from \"../../common.js\";\nimport { applyPatchOperations } from \"../../domain/script/patch/apply.js\";\nimport { blankScript } from \"../../domain/script/lookups.js\";\nimport { collectAssetRefs, collectStateRefs } from \"../../domain/script/refs.js\";\nimport {\n expandSelectorToActionRefs,\n isDangerousRegex,\n MAX_GREP_PATTERN_LEN,\n parseInSelector,\n selectorSingleActionPoint,\n type InSelector,\n} from \"../../domain/script/selector.js\";\nimport {\n parseAnyAddress,\n parseActionRef,\n parseAssetTarget,\n parseSceneRef,\n parseStateTarget,\n} from \"../../domain/script/address.js\";\nimport { validateScriptV3 } from \"../../domain/ingest/validation.js\";\nimport {\n scriptVersionOf,\n validateScriptDocument,\n type ScriptVersion,\n} from \"../../domain/script/dispatch.js\";\nimport { PATCH_OP_SCHEMA } from \"../../domain/script/schema.js\";\nimport { remoteScriptOutputStoreFromEnv } from \"../../infra/script-output-api.js\";\nimport {\n assertScriptUnchanged,\n atomicWriteJson,\n semanticScriptHash,\n} from \"../../infra/script-working-copy.js\";\nimport { LocalScriptOutputStore } from \"../../infra/local-script-output-store.js\";\nimport {\n ScriptOutputApiError,\n resolveOutputModeOrThrow,\n type ConfigMissingSlot,\n type ScriptOutputStore,\n} from \"../../infra/script-output-store.js\";\nimport { summarizeIssues } from \"../../domain/script/text-util.js\";\nimport { sortDeep } from \"../../domain/script/text-util.js\";\nimport {\n asList,\n type Dict,\n isDict,\n isList,\n strOf,\n} from \"../../domain/script/shared.js\";\n\nexport function parseBound(v: unknown): number | null {\n if (v === null || v === undefined || v === \"\") return null;\n const n = Number(v);\n if (!Number.isFinite(n)) {\n throw new CliError(\"--min-chars / --max-chars must be a non-negative integer.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"INSPECT_BOUND_INVALID\",\n hint: \"Pass --min-chars 1000 (positive integer).\",\n data: { expected: [\"non-negative integer\"], actual: [strOf(v)] },\n });\n }\n return Math.max(0, Math.floor(n));\n}\n\ninterface EpisodeCharCounts {\n total: number;\n dialogue: number;\n action: number;\n}\n\n// Count characters in an episode's actions. Splits dialogue-class (`dialogue`,\n// `inner_thought`) from narrative/screen-text (`action`) so agents can answer\n// \"which episodes exceed N spoken chars\" vs. raw size. Overlap dialogue stores\n// content on `lines[].content`; non-overlap stores it on `content`.\nexport function episodeCharCounts(scenes: Dict[]): EpisodeCharCounts {\n let dialogue = 0;\n let action = 0;\n for (const scene of scenes) {\n for (const a of asList<Dict>(scene[\"actions\"])) {\n const kind = strOf(a[\"type\"]).trim();\n let chars = strOf(a[\"content\"]).length;\n for (const line of asList<Dict>(a[\"lines\"])) {\n chars += strOf(line[\"content\"]).length;\n }\n if (kind === \"dialogue\" || kind === \"inner_thought\") dialogue += chars;\n else action += chars;\n }\n }\n return { total: dialogue + action, dialogue, action };\n}\n\n// ---------------------------------------------------------------------------\n// ScriptEditSession\n// ---------------------------------------------------------------------------\n\nexport class ScriptEditSession {\n workspace: string;\n script: Dict;\n readonly version: ScriptVersion;\n // Deep snapshot of the script as loaded, taken BEFORE any edit mutates\n // `script` in place. It is the baseline for the RFC6902 diff a V2 store sends\n // on save (patchScript). V1/local stores ignore it and replace the whole\n // document, so the snapshot is harmless overhead there.\n readonly baseline: Dict;\n readonly baselineHash: string;\n scriptPath: string | null;\n client: ScriptOutputStore | null;\n projectGroupNo: string | null;\n revision: number | null;\n\n constructor(opts: {\n workspace: string;\n script: Dict;\n scriptPath?: string | null;\n client?: ScriptOutputStore | null;\n projectGroupNo?: string | null;\n revision?: number | null;\n }) {\n this.workspace = opts.workspace;\n this.script = opts.script;\n this.version = scriptVersionOf(opts.script);\n this.baseline = structuredClone(opts.script);\n this.baselineHash = semanticScriptHash(opts.script);\n this.scriptPath = opts.scriptPath ?? null;\n this.client = opts.client ?? null;\n this.projectGroupNo = opts.projectGroupNo ?? null;\n this.revision = opts.revision ?? null;\n }\n\n get remote(): boolean {\n return this.client !== null;\n }\n\n get artifactLabel(): string {\n if (this.remote) {\n // Public label \u2014 strips the internal `db:/script-output/project-groups/`\n // storage prefix (which leaks implementation), but keeps the project id\n // and revision so two different project groups at the same revision stay\n // distinguishable in user-visible report.artifacts entries. The project\n // id is not a secret: the user supplies it themselves via\n // `--project-group-no` or env config.\n return `script-output/${this.projectGroupNo}@revision/${this.revision ?? 0}`;\n }\n return this.scriptPath ?? \"\";\n }\n}\n\n/**\n * Validate that the target-selection flags on `opts` are coherent, throwing a\n * CliError on any contradiction. The SINGLE conflict gate for every file-capable\n * entry point (loadScriptForEdit AND commandCreate) \u2014 neither may resolve a\n * target without passing through here, so a store flag can never be silently\n * dropped on the local-file branch (the wrong-target write this design forbids).\n *\n * `--remote`/`--local`/`--project-group-no` select a STORE; `--script-path`\n * selects a local FILE. The two are mutually exclusive.\n */\nexport function assertTargetCoherent(opts: Dict): void {\n const scriptPath = strOf(opts[\"script_path\"]).trim() !== \"\";\n const remote = Boolean(opts[\"remote\"]);\n const local = Boolean(opts[\"local\"]);\n const projectGroup = strOf(opts[\"project_group_no\"]).trim() !== \"\";\n const targetFlagConflict = (received: string[]): CliError =>\n new CliError(\"The selected output-target flags are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"TARGET_FLAG_CONFLICT\",\n hint: \"Keep a single target selector and drop the others.\",\n data: {\n expected: [\"one of: --script-path (a local file), or --remote/--local (the store)\"],\n actual: received,\n },\n });\n\n // Most fundamental first, so the message names the real contradiction even\n // when several conflicting flags are passed at once.\n if (remote && local) throw targetFlagConflict([\"--remote\", \"--local\"]);\n if ((remote || local) && scriptPath) {\n throw targetFlagConflict([remote ? \"--remote\" : \"--local\", \"--script-path\"]);\n }\n // A project group names a REMOTE target, so it cannot combine with any local\n // target \u2014 a local file (--script-path) OR the local store (--local).\n // `--remote --project-group-no` is the one valid pairing and is left alone.\n if (projectGroup && (scriptPath || local)) {\n throw targetFlagConflict([\"--project-group-no\", scriptPath ? \"--script-path\" : \"--local\"]);\n }\n}\n\nexport function scriptOutputClient(opts: Dict): ScriptOutputStore {\n const mode = resolveOutputModeOrThrow({\n remote: opts[\"remote\"],\n local: opts[\"local\"],\n projectGroupNo: opts[\"project_group_no\"],\n });\n try {\n if (mode === \"local\") {\n return LocalScriptOutputStore.fromEnv(strOf(opts[\"workspace_path\"]).trim() || undefined);\n }\n return remoteScriptOutputStoreFromEnv(strOf(opts[\"project_group_no\"]).trim() || null);\n } catch (exc) {\n // ScriptOutputApiError carries a `configMissing` discriminator so callers\n // can show the user which slot is unconfigured without naming the env var.\n if (exc instanceof ScriptOutputApiError) {\n const { title, message } = describeConfigMissing(mode, exc.configMissing);\n throw new CliError(message, {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_API_CONFIG_MISSING\",\n hint: \"Run `scriptctl doctor` to identify missing configuration.\",\n data: { expected: [\n mode === \"local\"\n ? \"SCRIPTCTL_OUTPUT_DIR\"\n : \"AWB_BASE_URL, LINGJING_AWB_ACCESS_KEY, and SANDBOX_PROJECT_GROUP_NO (or --project-group-no)\",\n ], actual: [exc.message, `configMissing: ${exc.configMissing ?? \"unknown\"}`] },\n });\n }\n // Belt-and-suspenders: anything else that escapes RemoteScriptOutputStore.fromEnv\n // (a TypeError on a malformed gateway URL, future programmer errors) still\n // surfaces as a clean CliError envelope rather than the generic\n // the generic runtime-error path in cli.ts.\n const raw = exc instanceof Error ? exc.message : String(exc);\n throw new CliError(mode === \"local\"\n ? \"Local output dir is not configured for this environment.\"\n : \"Gateway is not configured for this environment.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_API_CONFIG_MISSING\",\n hint: \"Run `scriptctl doctor` to identify missing configuration.\",\n data: { expected: [mode === \"local\" ? \"valid local output dir\" : \"valid gateway configuration\"], actual: [raw] },\n });\n }\n}\n\nfunction describeConfigMissing(\n mode: \"local\" | \"remote\",\n slot: ConfigMissingSlot | null,\n): { title: string; message: string } {\n // Mode wins over slot \u2014 if the caller is in local mode, the failure is\n // unambiguously about the output dir even if the underlying error tagged\n // the slot differently.\n // NOTE: this early return short-circuits the exhaustive switch below. New\n // ConfigMissingSlot values for remote-mode callers are guarded by the\n // switch (TS will flag a missing case); values intended for local-mode-only\n // callers must be handled explicitly above this guard.\n if (mode === \"local\") {\n return {\n title: \"SCRIPT API BLOCKED: local output dir missing\",\n message:\n \"Local output dir is not configured. Set `SCRIPTCTL_OUTPUT_DIR` to a writable directory.\",\n };\n }\n // Unknown / unspecified failures in remote mode default to the gateway\n // bucket \u2014 keeps the pre-0.7.0 UX stable.\n if (slot === null) {\n return {\n title: \"SCRIPT API BLOCKED: gateway not configured\",\n message: \"Gateway is not configured for this environment.\",\n };\n }\n // After the two guards above, `slot` is narrowed to ConfigMissingSlot. TS\n // exhaustiveness on the switch means adding a new slot without handling it\n // here is a compile error \u2014 `assertNever` makes the intent explicit.\n switch (slot) {\n case \"output\":\n return {\n title: \"SCRIPT API BLOCKED: local output dir missing\",\n message:\n \"Local output dir is not configured. Set `SCRIPTCTL_OUTPUT_DIR` to a writable directory.\",\n };\n case \"project\":\n return {\n title: \"SCRIPT API BLOCKED: project identifier missing\",\n message:\n \"Project identifier is not configured. Pass `--project-group-no <id>` or configure the project for this environment.\",\n };\n case \"access\":\n return {\n title: \"SCRIPT API BLOCKED: access credential missing\",\n message: \"Access credential is not configured for this environment.\",\n };\n case \"gateway\":\n return {\n title: \"SCRIPT API BLOCKED: gateway not configured\",\n message: \"Gateway is not configured for this environment.\",\n };\n default:\n return assertNever(slot);\n }\n}\n\nfunction assertNever(x: never): never {\n throw new Error(`describeConfigMissing: unhandled ConfigMissingSlot ${JSON.stringify(x)}`);\n}\n\nexport function apiErrorToCli(title: string, exc: ScriptOutputApiError): CliError {\n const rawMessage = exc.message || \"script-output API failed\";\n // Use the gateway's own canonical Chinese keywords as the only signal. Free\n // text like \"revision\" or \"not found\" can leak in from upstream proxies,\n // DNS errors (\"name not found\"), or HTTP 404 routing mismatches \u2014 matching on\n // those substrings would misroute auth/network failures into the conflict /\n // missing-script UX. The current CAS endpoint uses code 9002; the Chinese\n // keyword keeps the retained legacy endpoint compatible.\n const isConflict = String(exc.code) === \"9002\" || rawMessage.includes(\"\u7248\u672C\u51B2\u7A81\");\n const isMissing = rawMessage.includes(\"\u5267\u672C\u4E0D\u5B58\u5728\");\n const publicMessage = isConflict\n ? \"Script has been updated by another revision; keep local work and merge before retrying.\"\n : isMissing\n ? \"Script not found on the gateway.\"\n : \"Gateway request failed.\";\n return new CliError(publicMessage, {\n exitCode: exc.status !== null && exc.status >= 500 ? EXIT_RUNTIME : EXIT_INPUT,\n errorCode: isConflict\n ? \"REVISION_CONFLICT\"\n : isMissing\n ? \"SCRIPT_NOT_FOUND\"\n : \"SCRIPT_API_FAILED\",\n hint: isConflict\n ? \"Keep the local file, inspect the latest remote snapshot, and merge before publishing again.\"\n : isMissing\n ? \"Run `scriptctl publish` to publish a script first.\"\n : \"Run `scriptctl doctor` to verify gateway configuration; retry if it was transient.\",\n data: { expected: [\"successful script-output gateway request\"], actual: [rawMessage, `status: ${exc.status ?? \"<unknown>\"}`] },\n });\n}\n\nexport async function currentRevisionOrZero(client: ScriptOutputStore): Promise<number> {\n try {\n const revision = await client.getRevision();\n if (!revision) return 0;\n return Number(revision[\"revision\"] ?? 0);\n } catch (exc) {\n if (exc instanceof ScriptOutputApiError) {\n throw apiErrorToCli(\"SCRIPT API BLOCKED: Revision query failed\", exc);\n }\n throw exc;\n }\n}\n\nexport async function loadRemoteScript(opts: Dict, workspace: string): Promise<ScriptEditSession> {\n const client = scriptOutputClient(opts);\n let script: Record<string, unknown> | null;\n let revision: Record<string, unknown> | null;\n try {\n script = await client.getScript();\n revision = await client.getRevision();\n } catch (exc) {\n if (exc instanceof ScriptOutputApiError) {\n throw apiErrorToCli(\"SCRIPT API BLOCKED: Script query failed\", exc);\n }\n throw exc;\n }\n if (script === null) {\n throw new CliError(\"No script has been published for this project.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_NOT_FOUND\",\n hint: \"Run `scriptctl publish` first, or pass `--script-path` to edit a local script JSON.\",\n data: { expected: [\"existing script-output project document\"], actual: [`projectGroupNo=${client.projectGroupNo}`] },\n });\n }\n if (!isDict(script)) {\n throw new CliError(\"script root invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SCRIPT_ROOT_INVALID\",\n hint: \"Replace the final script with a valid script document object.\",\n data: { expected: [\"script root object\"], actual: [typeof script] },\n });\n }\n return new ScriptEditSession({\n workspace,\n script,\n client,\n projectGroupNo: client.projectGroupNo,\n revision: Number((revision ?? {})[\"revision\"] ?? 0),\n });\n}\n\nexport async function loadScriptForEdit(opts: Dict): Promise<ScriptEditSession> {\n const workspace = strOf(opts[\"workspace_path\"] || \"workspace\");\n const p = scriptJsonPath(opts);\n if (!exists(p)) {\n throw new CliError(\"Local script file not found.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_NOT_FOUND\",\n hint: \"Run `scriptctl checkout`, `scriptctl create`, or pass --script-path to an existing script.\",\n data: { expected: [\"existing local script JSON\"], actual: [p] },\n });\n }\n let data: unknown;\n try {\n data = readJson(p);\n } catch (exc) {\n throw new CliError(\"script JSON invalid.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_JSON_INVALID\",\n hint: \"Fix the local script JSON syntax before editing.\",\n data: { expected: [\"valid JSON\"], actual: [`${p}: ${(exc as Error).message}`] },\n });\n }\n if (!isDict(data)) {\n throw new CliError(\"script root invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SCRIPT_ROOT_INVALID\",\n hint: \"Use a valid script document object.\",\n data: { expected: [\"script root object\"], actual: [Array.isArray(data) ? \"array\" : typeof data] },\n });\n }\n return new ScriptEditSession({ workspace, scriptPath: p, script: data });\n}\n\n// Validate the IN-MEMORY script as Script v3. On a dry-run the edits live only\n// in session.script (never written), so validating the object (not the on-disk\n// file) is what makes \"would pass\" honest. requireSource is accepted for call-\n// site compatibility but ignored \u2014 v3 scripts carry no source-coverage contract.\nexport function validateSession(session: ScriptEditSession, _opts: { requireSource?: boolean } = {}): Dict {\n const report = validateScriptReport(session.script);\n if (session.remote) report[\"script_path\"] = session.artifactLabel;\n return report;\n}\n\nfunction validationResultReport(\n script: Dict,\n validation: ReturnType<typeof validateScriptDocument>,\n): Dict {\n const { ok, errors, warnings } = validation;\n const issues: Dict[] = [\n ...errors.map((e) => ({\n severity: \"error\",\n code: e.code,\n path: e.path,\n summary: e.message,\n ...(e.repair_hint ? { repair_hint: e.repair_hint } : {}),\n })),\n ...warnings.map((w) => ({\n severity: \"warning\",\n code: w.code,\n path: w.path,\n summary: w.message,\n ...(w.repair_hint ? { repair_hint: w.repair_hint } : {}),\n })),\n ];\n const episodes = asList<Dict>(script[\"episodes\"]);\n let scenes = 0;\n let actions = 0;\n for (const ep of episodes) {\n for (const sc of asList<Dict>(ep[\"scenes\"])) {\n scenes += 1;\n actions += asList<Dict>(sc[\"actions\"]).length;\n }\n }\n return {\n passed: ok,\n has_blocking: !ok,\n issues,\n stats: {\n actors: asList<Dict>(script[\"actors\"]).length,\n locations: asList<Dict>(script[\"locations\"]).length,\n props: asList<Dict>(script[\"props\"]).length,\n episodes: episodes.length,\n scenes,\n actions,\n },\n };\n}\n\n// Adapt a versioned validator's {ok, errors, warnings} into the report shape\n// consumed by CLI output and gateway validation sync.\nexport function validateScriptReport(script: Dict): Dict {\n return validationResultReport(script, validateScriptDocument(script));\n}\n\nexport function validateScriptV3Report(script: Dict): Dict {\n return validationResultReport(script, validateScriptV3(script));\n}\n\nfunction validationIssueKey(issue: Dict): string {\n return JSON.stringify([\n strOf(issue[\"code\"]),\n strOf(issue[\"path\"]),\n strOf(issue[\"summary\"]),\n ]);\n}\n\nexport function mutationValidationWarnings(\n session: ScriptEditSession,\n validation: Dict,\n): Dict[] {\n const baseline = validateScriptReport(session.baseline);\n const baselineCounts = new Map<string, number>();\n for (const issue of asList<Dict>(baseline[\"issues\"])) {\n const key = validationIssueKey(issue);\n baselineCounts.set(key, (baselineCounts.get(key) ?? 0) + 1);\n }\n const warnings: Dict[] = [];\n for (const issue of asList<Dict>(validation[\"issues\"])) {\n const key = validationIssueKey(issue);\n const remaining = baselineCounts.get(key) ?? 0;\n if (remaining > 0) {\n baselineCounts.set(key, remaining - 1);\n continue;\n }\n warnings.push({\n ...issue,\n validation_severity: issue[\"severity\"],\n severity: \"warning\",\n });\n }\n return warnings;\n}\n\nfunction validationIssuePath(issue: Dict): string | null {\n if (issue[\"path\"]) return strOf(issue[\"path\"]);\n const parts: string[] = [];\n if (issue[\"episode\"] !== null && issue[\"episode\"] !== undefined) parts.push(strOf(issue[\"episode\"]));\n if (issue[\"scene\"] !== null && issue[\"scene\"] !== undefined) parts.push(strOf(issue[\"scene\"]));\n if (issue[\"action_index\"] !== null && issue[\"action_index\"] !== undefined) parts.push(`action[${issue[\"action_index\"]}]`);\n return parts.length > 0 ? parts.join(\"/\") : null;\n}\n\nfunction validationIssueSeverity(raw: unknown): string {\n const severity = strOf(raw || \"info\");\n if (severity === \"blocking\" || severity === \"error\") return \"error\";\n if (severity === \"warning\") return \"warning\";\n return \"info\";\n}\n\nfunction validationToApiPayload(validation: Dict): [string, Dict, Dict[]] {\n const issues = asList<Dict>(validation[\"issues\"]);\n const status = validation[\"passed\"] ? \"valid\" : \"invalid\";\n const summary: Dict = {\n passed: Boolean(validation[\"passed\"]),\n hasBlocking: Boolean(validation[\"has_blocking\"]),\n stats: validation[\"stats\"] ?? {},\n issueCount: issues.length,\n };\n const apiIssues: Dict[] = [];\n for (const issue of issues) {\n if (!isDict(issue)) continue;\n const payload: Dict = { ...issue };\n for (const key of [\"severity\", \"code\", \"path\", \"summary\", \"repair_hint\"]) delete payload[key];\n apiIssues.push({\n severity: validationIssueSeverity(issue[\"severity\"]),\n code: strOf(issue[\"code\"] || \"SCRIPT_VALIDATION_ISSUE\"),\n path: validationIssuePath(issue),\n summary: strOf(issue[\"summary\"]),\n repairHint: issue[\"repair_hint\"],\n payload,\n });\n }\n return [status, summary, apiIssues];\n}\n\nexport async function syncValidationResult(session: ScriptEditSession, validation: Dict, revision?: number | null): Promise<void> {\n if (!session.remote || session.client === null) return;\n const targetRevision = Number(revision ?? session.revision ?? 0);\n if (targetRevision <= 0) return;\n const [status, summary, issues] = validationToApiPayload(validation);\n try {\n await session.client.saveValidationResult({\n revision: targetRevision,\n validationStatus: status,\n validationSummary: summary,\n issues,\n });\n } catch (exc) {\n if (exc instanceof ScriptOutputApiError) {\n throw apiErrorToCli(\"SCRIPT API BLOCKED: Validation sync failed\", exc);\n }\n throw exc;\n }\n}\n\n// Idempotency key for gateway writes. Returns the agent-provided --request-id\n// when present, otherwise derives a deterministic key from (op, post-mutation\n// script content). baseRevision is intentionally NOT in the hash: in a\n// partial-success retry the client reloads at a new baseRevision but the\n// post-mutation script is identical, so the hash matches and the gateway can\n// dedupe. The cost of including baseRevision (an old version of this code)\n// was that retries produced different ids and committed redundant no-op\n// revisions to the gateway history.\nexport function requestIdForScriptWrite(\n opts: Dict,\n op: string,\n payload: { script: Dict },\n): string {\n const explicit = strOf(opts[\"request_id\"]).trim();\n if (explicit) return explicit;\n const canonical = JSON.stringify(sortDeep({\n op,\n script: payload.script,\n }));\n return `scriptctl:${op}:${sha256Text(canonical)}`;\n}\n\nexport async function saveScriptSession(session: ScriptEditSession, _opts: Dict, _op: string): Promise<[number | null, boolean]> {\n if (session.scriptPath === null) throw new Error(\"local script session missing script path\");\n assertScriptUnchanged(session.scriptPath, session.baselineHash);\n atomicWriteJson(session.scriptPath, session.script);\n return [null, false];\n}\n\nexport function scriptSourceText(workspace: string): string {\n const sourcePath = path.join(workspace, \"source.txt\");\n return exists(sourcePath) ? readText(sourcePath) : \"\";\n}\n\nexport function patchOperationsFromPayload(payload: unknown): Dict[] {\n let operations: unknown[];\n if (isList(payload)) {\n operations = payload;\n } else if (isDict(payload) && isList(payload[\"ops\"])) {\n operations = payload[\"ops\"];\n } else if (isDict(payload) && isList(payload[\"operations\"])) {\n operations = payload[\"operations\"];\n } else if (isDict(payload)) {\n operations = [payload];\n } else {\n throw new CliError(\"Patch schema invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"PATCH_BLOCKED_PATCH_SCHEMA_INVALID\",\n hint: \"Fix patch JSON and rerun patch.\",\n data: { expected: [\"object, array, object with ops[], or object with operations[]\"], actual: [Array.isArray(payload) ? \"array\" : typeof payload] },\n });\n }\n if (operations.some((op) => !isDict(op))) {\n throw new CliError(\"Patch operation invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"PATCH_BLOCKED_PATCH_OPERATION_INVALID\",\n hint: \"Fix patch JSON and rerun patch.\",\n data: { expected: [\"each operation must be an object\"], actual: [JSON.stringify(operations).slice(0, 500)] },\n });\n }\n return operations as Dict[];\n}\n\n// ---------------------------------------------------------------------------\n// commandScriptValidate / commandScriptInspect\n// ---------------------------------------------------------------------------\n\n// ===========================================================================\n// do \u2014 verb-script transaction (the agent-friendly alternative to JSON patch)\n// ===========================================================================\n\n// Minimal shell-like tokenizer: whitespace-split honoring \"...\"/'...' quoting\n// and backslash escapes. Enough to carry screenplay content with spaces/quotes.\n", "import type { ScriptV4 } from \"./types.js\";\n\nexport function blankScriptV4(title = \"\"): ScriptV4 {\n return {\n version: 4,\n title,\n worldview: \"\",\n style: \"\",\n actors: [],\n locations: [],\n props: [],\n episodes: [],\n };\n}\n", "// v3 scene-ref accessors. In Script v3 a scene's cast/props/location live as\n// top-level scene fields \u2014 scene.actors[] / scene.props[] (arrays of\n// {actor_id|prop_id, state_id?}) and scene.location ({location_id, state_id?} |\n// null, single-valued) \u2014 NOT the legacy scene.context{} bag. These two functions\n// are the ONLY place the patch ops touch that storage, so the whole context.*\n// op family operates on v3 through the same {actors,locations,props} bag shape\n// the ops already expect. `locations` is synthesized as a 0-or-1 array from the\n// single scene.location so multi-location callers keep working (location stays\n// single-valued: setSceneRefs writes locations[0] back as scene.location).\nimport { asList, type Dict, isDict, isList } from \"../shared.js\";\n\nexport function sceneRefs(scene: Dict): Dict {\n const loc = isDict(scene[\"location\"]) ? (scene[\"location\"] as Dict) : null;\n return {\n actors: isList(scene[\"actors\"]) ? (scene[\"actors\"] as Dict[]) : [],\n props: isList(scene[\"props\"]) ? (scene[\"props\"] as Dict[]) : [],\n locations: loc && String(loc[\"location_id\"] ?? \"\").trim() ? [loc] : [],\n };\n}\n\n// Clean a single ref to v3 shape: keep the id key, keep state_id ONLY when it is\n// a real (non-null, non-empty) materialized id \u2014 v3 validation rejects a\n// state_id: null (it reads as \"declared but not materialized\").\nfunction cleanRef(ref: Dict, idKey: string): Dict {\n const out: Dict = { [idKey]: ref[idKey] };\n const state = ref[\"state_id\"];\n if (state != null && String(state).trim()) out[\"state_id\"] = state;\n return out;\n}\n\nexport function setSceneRefs(scene: Dict, refs: Dict): void {\n scene[\"actors\"] = asList<Dict>(refs[\"actors\"]).map((r) => cleanRef(r, \"actor_id\"));\n scene[\"props\"] = asList<Dict>(refs[\"props\"]).map((r) => cleanRef(r, \"prop_id\"));\n const loc = asList<Dict>(refs[\"locations\"])[0];\n scene[\"location\"] = loc && String(loc[\"location_id\"] ?? \"\").trim() ? cleanRef(loc, \"location_id\") : null;\n}\n", "import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nimport {\n CliError,\n EXIT_INPUT,\n EXIT_OK,\n EXIT_RUNTIME,\n EXIT_USAGE,\n type CommandOutput,\n directDir,\n exists,\n readJson,\n readText,\n scriptJsonPath,\n sha256Text,\n writeJson,\n} from \"../../common.js\";\nimport { applyPatchOperationsV4 } from \"../../domain/script/v4/patch/apply.js\";\nimport { isV4Id } from \"../../domain/script/v4/ids.js\";\nimport { requireStructurallyReadableScriptV4 } from \"../../domain/script/v4/parse.js\";\nimport type { ScriptV4 } from \"../../domain/script/v4/types.js\";\nimport { validateScriptV4 } from \"../../domain/script/v4/validation.js\";\nimport { blankScript } from \"../../domain/script/lookups.js\";\nimport { collectAssetRefs, collectStateRefs } from \"../../domain/script/refs.js\";\nimport { sceneRefs } from \"../../domain/script/scene-refs.js\";\nimport {\n expandSelectorToActionRefs,\n isDangerousRegex,\n MAX_GREP_PATTERN_LEN,\n parseInSelector,\n selectorSingleActionPoint,\n WHOLE_SCRIPT,\n type InSelector,\n} from \"../../domain/script/selector.js\";\nimport {\n parseAnyAddress,\n parseActionRef,\n parseAssetTarget,\n parseSceneRef,\n parseStateTarget,\n} from \"../../domain/script/address.js\";\nimport { parseV4Address } from \"../../domain/script/v4/address.js\";\nimport { PATCH_OP_SCHEMA } from \"../../domain/script/schema.js\";\nimport { LocalScriptOutputStore } from \"../../infra/local-script-output-store.js\";\nimport {\n ScriptOutputApiError,\n resolveOutputMode,\n type ConfigMissingSlot,\n type ScriptOutputStore,\n} from \"../../infra/script-output-store.js\";\nimport { summarizeIssues } from \"../../domain/script/text-util.js\";\nimport { sortDeep } from \"../../domain/script/text-util.js\";\nimport {\n asList,\n type Dict,\n idNum,\n isDict,\n isList,\n strOf,\n} from \"../../domain/script/shared.js\";\nimport {\n ScriptEditSession, scriptOutputClient, apiErrorToCli, currentRevisionOrZero,\n loadScriptForEdit, validateSession, saveScriptSession, syncValidationResult,\n scriptSourceText, patchOperationsFromPayload, parseBound, episodeCharCounts, requestIdForScriptWrite,\n mutationValidationWarnings,\n} from \"./session.js\";\nimport { resolveActionTargetsV4 } from \"./v4/queries.js\";\nimport { actionTimestampFilter, actionTimestampMatches } from \"./timestamp-filter.js\";\nimport { applyVersionedMutations } from \"./dispatch.js\";\nimport {\n assertInsertCommandFlags,\n assertMoveCommandFlags,\n assertSceneRefCommandFlags,\n buildTimestampOperation,\n type InsertCommandFlags,\n} from \"./command-constraints.js\";\n// A tokenized word, carrying whether any of its characters came from inside a\n// quote or a backslash escape. `quoted` is the bit `--`-detection needs: a\n// quoted `\"--foo\"` is a literal value, NOT a flag \u2014 without this the tokenizer\n// would strip the quotes and a value like `--content \"-- \u7B2C\u4E00\u5E55 --\"` would be\n// mistaken for a flag.\nexport interface DoToken { text: string; quoted: boolean }\n\nexport function tokenizeLine(line: string): DoToken[] {\n const out: DoToken[] = [];\n let cur = \"\";\n let started = false;\n let quoted = false;\n let inSingle = false;\n let inDouble = false;\n const flush = () => { if (started) { out.push({ text: cur, quoted }); cur = \"\"; started = false; quoted = false; } };\n for (let i = 0; i < line.length; i++) {\n const ch = line[i]!;\n if (inSingle) {\n if (ch === \"'\") inSingle = false;\n else { cur += ch; quoted = true; }\n } else if (inDouble) {\n if (ch === '\"') inDouble = false;\n else if (ch === \"\\\\\" && i + 1 < line.length) { cur += line[++i]; quoted = true; }\n else { cur += ch; quoted = true; }\n } else if (ch === \"'\") { inSingle = true; started = true; }\n else if (ch === '\"') { inDouble = true; started = true; }\n else if (ch === \"\\\\\" && i + 1 < line.length) { cur += line[++i]; started = true; quoted = true; }\n else if (ch === \" \" || ch === \"\\t\" || ch === \"\\r\") { flush(); }\n else { cur += ch; started = true; }\n }\n flush();\n return out;\n}\n\n// A token is a flag only if it was unquoted AND starts with `--`.\nfunction isDoFlag(t: DoToken): boolean {\n return !t.quoted && t.text.startsWith(\"--\");\n}\n\n// Per-verb flag arity. Everything else takes the next token as its value.\n\nexport const DO_BOOL_FLAGS: Record<string, Set<string>> = {\n replace: new Set([\"all\", \"regex\"]),\n transition: new Set([\"clear\"]),\n emotion: new Set([\"clear\"]),\n parenthetical: new Set([\"remove\"]),\n timestamp: new Set([\"remove\"]),\n \"scene-ref\": new Set([\"clear\", \"remove\", \"append\"]),\n delete: new Set([\"force\"]),\n extend: new Set([\"clear\", \"json-value\"]),\n};\n\nexport const DO_REPEAT_FLAGS: Record<string, Set<string>> = {\n alias: new Set([\"add\", \"remove\"]),\n \"add-actor\": new Set([\"alias\"]),\n \"scene-ref\": new Set([\"state\"]),\n insert: new Set([\"state\"]),\n};\n\nexport interface ParsedDoLine { verb: string; args: string[]; flags: Dict; }\n\nfunction pushFlag(flags: Dict, repeats: Set<string>, name: string, val: string): void {\n if (repeats.has(name)) {\n const arr = (flags[name] as string[]) ?? [];\n arr.push(val);\n flags[name] = arr;\n } else {\n flags[name] = val;\n }\n}\n\nexport function parseDoLine(tokens: DoToken[]): ParsedDoLine {\n if (tokens.length === 0 || isDoFlag(tokens[0]!)) {\n throw doErr(\"a line must start with a verb (not a flag)\");\n }\n const verb = tokens[0]!.text;\n const bools = DO_BOOL_FLAGS[verb] ?? new Set<string>();\n const repeats = DO_REPEAT_FLAGS[verb] ?? new Set<string>();\n const args: string[] = [];\n const flags: Dict = {};\n for (let i = 1; i < tokens.length; i++) {\n const t = tokens[i]!;\n if (isDoFlag(t)) {\n let name = t.text.slice(2);\n // Support `--flag=value` (a common CLI habit) alongside `--flag value`.\n const eq = name.indexOf(\"=\");\n if (eq >= 0) {\n const inlineVal = name.slice(eq + 1);\n name = name.slice(0, eq);\n if (!name) throw doErr(`empty flag name in \"${t.text}\"`);\n // A boolean flag written as `--all=false` must become false, not the\n // truthy string \"false\" \u2014 `--force=false` especially must NOT force.\n if (bools.has(name)) {\n flags[name] = ![\"false\", \"0\", \"no\", \"off\"].includes(inlineVal.toLowerCase());\n } else {\n pushFlag(flags, repeats, name, inlineVal);\n }\n continue;\n }\n if (!name) throw doErr(`empty flag name \"${t.text}\"`);\n if (bools.has(name)) { flags[name] = true; continue; }\n // A value-taking flag must be followed by an actual value, not another\n // unquoted `--flag` (or end-of-line) \u2014 otherwise `--to --from x` silently\n // binds '--from' as --to's value. A quoted `\"--x\"` IS a valid value.\n const next = tokens[i + 1];\n if (next === undefined || isDoFlag(next)) {\n throw doErr(`--${name} needs a value`);\n }\n pushFlag(flags, repeats, name, tokens[++i]!.text);\n } else {\n args.push(t.text);\n }\n }\n return { verb, args, flags };\n}\n\nexport function doErr(detail: string): CliError {\n return new CliError(detail, {\n exitCode: EXIT_USAGE,\n errorCode: \"DO_LINE_INVALID\",\n hint: \"Each line is a scriptctl verb minus the leading `scriptctl`; see `scriptctl do --help`.\",\n data: { expected: [\"a valid <verb> ...args... line\"], actual: [detail] },\n });\n}\n\n// ---- shared op-template builders ------------------------------------------\n// One source of truth for the verbs whose op has validation/defaults, so the\n// typed CLI handler and `do`'s lineToOp can never drift. Each returns the op\n// WITHOUT `at` (the caller adds the single address or sweeps it over a selector)\n// and throws the SAME CliError the handler used to throw inline.\n\nexport function stateChangeTemplate(target: string, f: { to?: unknown; from?: unknown; effective?: unknown; clear?: boolean }): Dict {\n const toSet = f.to !== undefined;\n const clearSet = Boolean(f.clear);\n if (toSet && clearSet) {\n throw new CliError(\"state-change: --to and --clear are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"STATE_CHANGE_FLAG_CONFLICT\",\n hint: \"Pick one and retry.\",\n data: { expected: [\"exactly one of --to <state> / --clear\"], actual: [\"--to\", \"--clear\"] },\n });\n }\n if (!toSet && !clearSet) {\n throw new CliError(\"state-change: must specify --to <state> or --clear.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"STATE_CHANGE_FLAG_MISSING\",\n hint: \"Pick exactly one flag.\",\n data: { expected: [\"one of --to <state> / --clear\"], actual: [\"<missing>\"] },\n });\n }\n // v3 has no per-action state_changes; state lives on scene.ref.* only.\n throw new CliError(\"state-change was removed in v3; set a scene ref's state instead.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"STATE_CHANGE_REMOVED\",\n hint: \"Use `scene-ref <ep/scn> <kind:id> --state <state_id>` (op scene.ref.set).\",\n data: { expected: [\"scene-ref state edit\"], actual: [\"state-change\"] },\n });\n}\n\nexport function transitionTemplate(target: string, f: { process?: unknown; contrast?: unknown; clear?: boolean }): Dict {\n const setBoth = f.process !== undefined || f.contrast !== undefined;\n const clearSet = Boolean(f.clear);\n if (setBoth && clearSet) {\n throw new CliError(\"transition: --clear is mutually exclusive with --process/--contrast.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"TRANSITION_FLAG_CONFLICT\",\n hint: \"Pick one mode and retry.\",\n data: { expected: [\"either --clear, or --process + --contrast\"], actual: [\"--clear\", \"--process/--contrast\"] },\n });\n }\n if (!setBoth && !clearSet) {\n throw new CliError(\"transition: must specify --process/--contrast or --clear.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"TRANSITION_FLAG_MISSING\",\n hint: \"Pick exactly one mode.\",\n data: { expected: [\"--process + --contrast, or --clear\"], actual: [\"<missing>\"] },\n });\n }\n return clearSet\n ? { op: \"action.transition.clear\", target }\n : { op: \"action.transition.set\", target, process: f.process, contrast: f.contrast };\n}\n\nexport function emotionTemplate(f: { emotion?: unknown; clear?: boolean }): Dict {\n const emotionSet = f.emotion !== undefined;\n const clearSet = Boolean(f.clear);\n if (emotionSet && clearSet) {\n throw new CliError(\"emotion: value and --clear are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"EMOTION_FLAG_CONFLICT\",\n hint: \"Pick one mode and retry.\",\n data: { expected: [\"either <emotion>, or --clear\"], actual: [\"<emotion>\", \"--clear\"] },\n });\n }\n if (!emotionSet && !clearSet) {\n throw new CliError(\"emotion: must specify <emotion> or --clear.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"EMOTION_VALUE_MISSING\",\n hint: \"Pass an emotion label, or use --clear.\",\n data: { expected: [\"<emotion>, or --clear\"], actual: [\"<missing>\"] },\n });\n }\n return clearSet\n ? { op: \"action.emotion.clear\" }\n : { op: \"action.emotion.set\", emotion: f.emotion };\n}\n\nexport function contextTemplate(target: string, f: {\n state?: unknown;\n clear?: boolean;\n remove?: boolean;\n append?: boolean;\n occurrence?: unknown;\n}): Dict {\n const stateSet = f.state !== undefined;\n const clearSet = Boolean(f.clear);\n const removeSet = Boolean(f.remove);\n const n = (stateSet ? 1 : 0) + (clearSet ? 1 : 0) + (removeSet ? 1 : 0);\n if (n === 0) {\n throw new CliError(\"context: must specify --state X, --clear, or --remove.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CONTEXT_FLAG_MISSING\",\n hint: \"Pick exactly one flag.\",\n data: { expected: [\"one of --state <state_id> / --clear / --remove\"], actual: [\"<missing>\"] },\n });\n }\n if (n > 1) {\n const passed: string[] = [];\n if (stateSet) passed.push(\"--state\");\n if (clearSet) passed.push(\"--clear\");\n if (removeSet) passed.push(\"--remove\");\n throw new CliError(\"context: --state / --clear / --remove are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"CONTEXT_FLAG_CONFLICT\",\n hint: \"Pick one and retry.\",\n data: { expected: [\"exactly one of --state / --clear / --remove\"], actual: passed },\n });\n }\n const append = Boolean(f.append);\n const occurrenceRaw = strOf(f.occurrence).trim();\n const occurrence = occurrenceRaw ? Number(occurrenceRaw) : undefined;\n if (occurrence !== undefined && (!Number.isInteger(occurrence) || occurrence < 1)) {\n throw new CliError(\"scene-ref: --occurrence must be a positive integer.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SCENE_REF_OCCURRENCE_INVALID\",\n hint: \"Use 1 for the first matching scene ref, 2 for the second, and so on.\",\n data: { expected: [\"--occurrence <positive integer> (1-based)\"], actual: [occurrenceRaw] },\n });\n }\n if (append && (!stateSet || occurrence !== undefined)) {\n throw new CliError(\"scene-ref: --append requires --state and cannot be combined with --occurrence.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SCENE_REF_APPEND_FLAG_CONFLICT\",\n hint: \"Append a new actor ref with --state <state_id> --append, or target an existing ref with --occurrence <n>.\",\n data: { expected: [\"--state <state_id> --append\"], actual: [append ? \"--append\" : \"\", occurrence !== undefined ? \"--occurrence\" : \"\", clearSet ? \"--clear\" : \"\", removeSet ? \"--remove\" : \"\"].filter(Boolean) },\n });\n }\n if (removeSet) return { op: \"scene.ref.remove\", target, occurrence };\n if (clearSet) return { op: \"scene.ref.clear\", target, occurrence };\n return { op: \"scene.ref.set\", target, state: f.state === \"none\" ? \"\" : f.state, append, occurrence };\n}\n\n// v3 dialogue speaker: a single inline speaker \u2014 an actor, OR a non-actor kind\n// (system|broadcast|offscreen|group) with an optional label.\nexport function dialogueTemplate(f: { actor?: unknown; kind?: unknown; label?: unknown }): Dict {\n const actorId = strOf(f.actor).trim();\n const speakerKind = strOf(f.kind).trim();\n const label = strOf(f.label).trim();\n if (actorId && speakerKind) {\n throw new CliError(\"dialogue: --actor and --kind are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SPEAKER_AMBIGUOUS\",\n hint: \"Keep --actor for a character, or --kind for a non-actor source.\",\n data: { expected: [\"exactly one of --actor <actor_id> or --kind <non-actor kind>\"], actual: [\"--actor\", \"--kind\"] },\n });\n }\n if (actorId && label) {\n throw new CliError(\"dialogue: --label is only valid with --kind.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SPEAKER_LABEL_WITHOUT_KIND\",\n hint: \"Remove --label for an actor line, or use --kind for a labeled non-actor source.\",\n data: { expected: [\"omit --label with --actor, or pair --label with --kind\"], actual: [\"--actor\", \"--label\"] },\n });\n }\n if (actorId) return { op: \"dialogue.speaker.set\", actor_id: actorId };\n if (speakerKind) return { op: \"dialogue.speaker.set\", kind: speakerKind, label: label || undefined };\n throw new CliError(\"dialogue: pass --actor <id> or --kind <system|broadcast|offscreen|group>.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"DIALOGUE_SPEAKER_MISSING\",\n hint: \"Set --actor for an actor line, or --kind for a non-actor line.\",\n data: { expected: [\"--actor <actor_id> or --kind <non-actor kind>\"], actual: [\"<missing>\"] },\n });\n}\n\n// Translate one parsed verb line into a patch op dict (the SAME ops `patch`\n// consumes). `do` = the human/agent-friendly notation for those ops: no JSON,\n// no field-name guessing \u2014 the verbs you already type. Multipolar verbs\n// (delete/move/insert/merge/describe) pick their op by the address kind.\n\nfunction repeatedDoFlag(raw: unknown): string[] {\n if (raw === undefined) return [];\n return Array.isArray(raw) ? raw.map(strOf) : [strOf(raw)];\n}\n\nfunction doInsertFlags(flags: Dict): InsertCommandFlags {\n return {\n type: flags[\"type\"],\n content: flags[\"content\"],\n emotion: flags[\"emotion\"],\n parenthetical: flags[\"parenthetical\"],\n actionId: flags[\"action-id\"],\n at: flags[\"at\"],\n before: flags[\"before\"],\n after: flags[\"after\"],\n actor: flags[\"actor\"],\n speaker: flags[\"speaker\"],\n speakerState: flags[\"speaker-state\"],\n kind: flags[\"kind\"],\n label: flags[\"label\"],\n location: flags[\"location\"],\n time: flags[\"time\"],\n space: flags[\"space\"],\n sceneId: flags[\"scene-id\"],\n states: repeatedDoFlag(flags[\"state\"]),\n };\n}\n\nexport function lineToOp(verb: string, args: string[], flags: Dict, scriptVersion: 3 | 4 = 3): Dict {\n const a0 = strOf(args[0]);\n const a1 = strOf(args[1]);\n const parseAddress = (raw: string) =>\n scriptVersion === 4 ? parseV4Address(raw) : parseAnyAddress(raw);\n switch (verb) {\n case \"replace\":\n return flags[\"regex\"]\n ? { op: \"action.content.regex-replace\", at: a0, pattern: regexPattern(strOf(flags[\"from\"])), to: flags[\"to\"] ?? \"\", all: Boolean(flags[\"all\"]) }\n : { op: \"action.content.replace\", at: a0, from: strOf(flags[\"from\"]), to: flags[\"to\"] ?? \"\", all: Boolean(flags[\"all\"]) };\n case \"type\":\n return { op: \"action.type.set\", at: a0, type: a1 };\n case \"actor\":\n return { op: \"action.actor.set\", at: a0, actor_id: a1 };\n case \"transition\":\n return { ...transitionTemplate(a1, { process: flags[\"process\"], contrast: flags[\"contrast\"], clear: Boolean(flags[\"clear\"]) }), at: a0 };\n case \"emotion\":\n if (scriptVersion === 4) throw doErr(\"emotion belongs to Script v3; use parenthetical for Script v4\");\n return { ...emotionTemplate({ emotion: args[1], clear: Boolean(flags[\"clear\"]) }), at: a0 };\n case \"parenthetical\":\n if (scriptVersion === 3) throw doErr(\"parenthetical belongs to Script v4; use emotion for Script v3\");\n if (Boolean(flags[\"remove\"]) === (flags[\"set\"] !== undefined)) {\n throw doErr(\"parenthetical needs exactly one of --set <text> or --remove\");\n }\n return Boolean(flags[\"remove\"])\n ? { op: \"action.parenthetical.remove\", at: a0 }\n : { op: \"action.parenthetical.set\", at: a0, parenthetical: strOf(flags[\"set\"]) };\n case \"timestamp\":\n return buildTimestampOperation(a0, flags[\"set\"], Boolean(flags[\"remove\"]));\n case \"scene-ref\": {\n const sceneRefFlags = {\n states: repeatedDoFlag(flags[\"state\"]),\n clear: Boolean(flags[\"clear\"]),\n remove: Boolean(flags[\"remove\"]),\n append: Boolean(flags[\"append\"]),\n occurrence: flags[\"occurrence\"],\n };\n assertSceneRefCommandFlags(scriptVersion, sceneRefFlags);\n if (scriptVersion === 4) {\n return sceneRefFlags.remove\n ? { op: \"scene.ref.remove\", at: a0, target: a1 }\n : { op: \"scene.ref.set\", at: a0, target: a1, state_ids: sceneRefFlags.states };\n }\n return {\n ...contextTemplate(a1, {\n state: sceneRefFlags.states[0],\n clear: sceneRefFlags.clear,\n remove: sceneRefFlags.remove,\n append: sceneRefFlags.append,\n occurrence: sceneRefFlags.occurrence,\n }),\n at: a0,\n };\n }\n case \"dialogue\":\n if (scriptVersion === 3 && flags[\"state\"] !== undefined) {\n throw doErr(\"dialogue --state belongs to Script v4\");\n }\n return {\n ...dialogueTemplate({ actor: flags[\"actor\"], kind: flags[\"kind\"], label: flags[\"label\"] }),\n ...(scriptVersion === 4 && flags[\"state\"] !== undefined ? { state_id: flags[\"state\"] } : {}),\n at: a0,\n };\n case \"rename\":\n return { op: \"asset.rename\", target: a0, name: a1 };\n case \"role\":\n return { op: \"asset.role.set\", target: a0, role_type: a1 };\n case \"worldview\":\n return { op: \"meta.worldview.set\", worldview: a0 };\n case \"synopsis\": {\n if (args.length === 0) throw doErr(\"synopsis needs <text> or <episode_id> <text>\");\n if (args.length > 2) throw doErr(\"synopsis text with spaces must be quoted\");\n if (args.length === 1) {\n if (/^ep_/.test(a0) || /^ep[1-9A-HJ-NP-Za-km-z]{6}$/.test(a0)) {\n throw doErr(`synopsis for ${a0} needs text`);\n }\n return { op: \"meta.synopsis.set\", synopsis: a0 };\n }\n const addr = parseAddress(a0);\n if (addr.kind !== \"episode\") throw doErr(`synopsis target must be an episode id or omitted for global (${a0})`);\n return { op: \"episode.synopsis.set\", episode_id: \"id\" in addr ? addr.id : addr.episodeId, synopsis: a1 };\n }\n case \"alias\": {\n const add = (flags[\"add\"] as string[]) ?? [];\n const remove = (flags[\"remove\"] as string[]) ?? [];\n if (add.length) return { op: \"asset.alias.add\", target: a0, alias: add };\n if (remove.length) return { op: \"asset.alias.remove\", target: a0, alias: remove };\n throw doErr(\"alias needs --add <alias> or --remove <alias>\");\n }\n case \"describe\": {\n const addr = parseAddress(a0);\n if (addr.kind === \"state\") return { op: \"state.describe\", target: a0, description: a1 };\n if (addr.kind === \"asset\") return { op: \"asset.describe\", target: a0, description: a1 };\n throw doErr(`describe cannot operate on a ${addr.kind} address (${a0}); use an asset or asset/state target`);\n }\n case \"extend\": {\n if (a0 !== \"global\") parseAddress(a0);\n if (flags[\"clear\"]) {\n if (args.length >= 3) throw doErr(\"extend --clear takes no value (drop --clear to set, or drop the value to delete)\");\n return { op: \"extend.clear\", at: a0, key: a1 || undefined };\n }\n if (args.length < 3) throw doErr(\"extend needs <addr> <key> <value> (or --clear)\");\n let value: unknown = args[2];\n if (flags[\"json-value\"]) {\n try { value = JSON.parse(strOf(args[2])); }\n catch { throw doErr(\"extend --json-value: value is not valid JSON\"); }\n }\n return { op: \"extend.set\", at: a0, key: a1, value };\n }\n case \"state-add\":\n return { op: \"state.add\", target: a0, name: a1, description: flags[\"description\"], state_id: flags[\"state-id\"] };\n case \"state-rename\":\n return { op: \"state.rename\", target: a0, name: a1 };\n case \"state-delete\":\n return { op: \"state.delete\", target: a0, strategy: flags[\"strategy\"], replacement: flags[\"replacement\"] };\n case \"add-actor\":\n return { op: \"actor.add\", actor_id: flags[\"id\"], name: a0, role_type: flags[\"role\"], description: flags[\"description\"], aliases: (flags[\"alias\"] as string[]) ?? undefined };\n case \"add-location\":\n return { op: \"location.add\", location_id: flags[\"id\"], name: a0, description: flags[\"description\"] };\n case \"add-prop\":\n return { op: \"prop.add\", prop_id: flags[\"id\"], name: a0, description: flags[\"description\"] };\n case \"add-episode\":\n return { op: \"episode.add\", title: flags[\"title\"], episode_id: flags[\"id\"] };\n case \"importance\":\n return { op: \"importance.set\", target: a0, importance: a1 };\n case \"split\":\n return scriptVersion === 4\n ? { op: \"scene.split\", at: a0, at_action: flags[\"at\"], new_scene_id: flags[\"new-scene-id\"] }\n : { op: \"scene.split\", at: a0, at_index: Number(flags[\"at\"]), new_scene_id: flags[\"new-scene-id\"] };\n case \"delete\": {\n const addr = parseAddress(a0);\n if (addr.kind === \"action\") return { op: \"action.delete\", at: a0 };\n if (addr.kind === \"scene\") return { op: \"scene.delete\", at: a0, force: Boolean(flags[\"force\"]) };\n if (addr.kind === \"state\") return { op: \"state.delete\", target: a0, strategy: flags[\"strategy\"], replacement: flags[\"replacement\"] };\n if (addr.kind === \"asset\") return { op: \"asset.delete\", target: a0, strategy: flags[\"strategy\"], replacement: flags[\"replacement\"] };\n throw doErr(`delete cannot operate on a ${addr.kind} address (${a0})`);\n }\n case \"move\": {\n assertMoveCommandFlags(scriptVersion, {\n at: flags[\"at\"],\n before: flags[\"before\"],\n after: flags[\"after\"],\n });\n const addr = parseAddress(a0);\n if (addr.kind === \"scene\") {\n return scriptVersion === 4\n ? { op: \"scene.move\", at: a0, to: a1, before: flags[\"before\"], after: flags[\"after\"] }\n : { op: \"scene.move\", at: a0, to: a1, at_index: flags[\"at\"] };\n }\n if (addr.kind === \"action\") {\n return scriptVersion === 4\n ? { op: \"action.move\", at: a0, to: a1, before: flags[\"before\"], after: flags[\"after\"] }\n : { op: \"action.move\", at: a0, to: a1 };\n }\n throw doErr(`move cannot operate on a ${addr.kind} address (${a0}); move an action or a scene`);\n }\n case \"merge\": {\n const addr = parseAddress(a0);\n if (addr.kind === \"scene\") return { op: \"scene.merge\", from: a0, into: strOf(flags[\"into\"]) };\n if (addr.kind === \"asset\") return { op: \"asset.merge\", from: a0, into: strOf(flags[\"into\"]) };\n throw doErr(`merge cannot operate on a ${addr.kind} address (${a0}); merge two assets or two scenes`);\n }\n case \"insert\": {\n const addr = parseAddress(a0);\n const insertFlags = doInsertFlags(flags);\n if (addr.kind === \"episode\") {\n assertInsertCommandFlags(scriptVersion, \"scene\", insertFlags);\n return {\n op: \"scene.insert\",\n at: a0,\n location: flags[\"location\"],\n time: flags[\"time\"],\n space: flags[\"space\"],\n ...(scriptVersion === 4\n ? { location_state_ids: insertFlags.states, before: flags[\"before\"], after: flags[\"after\"] }\n : { at_index: flags[\"at\"], before: flags[\"before\"], after: flags[\"after\"] }),\n scene_id: flags[\"scene-id\"],\n };\n }\n if (addr.kind === \"scene\") {\n assertInsertCommandFlags(scriptVersion, \"action\", insertFlags);\n return {\n op: \"action.insert\",\n at: a0,\n type: flags[\"type\"],\n content: flags[\"content\"],\n before: flags[\"before\"],\n after: flags[\"after\"],\n actor_id: flags[\"actor\"],\n kind: flags[\"kind\"],\n label: flags[\"label\"],\n ...(scriptVersion === 4\n ? {\n action_id: flags[\"action-id\"],\n state_id: flags[\"speaker-state\"],\n parenthetical: flags[\"parenthetical\"],\n }\n : {\n at_index: flags[\"at\"],\n speaker_id: flags[\"speaker\"],\n emotion: flags[\"emotion\"],\n }),\n };\n }\n throw doErr(`insert needs ep_NNN (scene insert) or ep_NNN/scn_NNN (action insert), got a ${addr.kind} address (${a0})`);\n }\n default:\n throw doErr(`unknown verb '${verb}' (structural/edit/create verbs are supported; queries are not)`);\n }\n}\n\nexport function actionAddress(epId: string, sceneId: string, idx: number): string {\n return `${epId}/${sceneId}#${idx}`;\n}\n\n// The action's authored timeline position, carried in extend.timestamp as a\n// \"M:SS\" / \"MM:SS\" string (episode-local by convention). Empty string when the\n// action carries no timestamp. This is the anchor event-level alignment reads:\n// an event's span is the delta between its first and last action timestamp.\nexport function actionTimestamp(action: Dict): string {\n const extend = isDict(action[\"extend\"]) ? (action[\"extend\"] as Dict) : {};\n return strOf(extend[\"timestamp\"]).trim();\n}\n\n// First and last non-empty action timestamps within a scene, in document order.\n// Timestamps are monotonic within an episode, so first = t_start, last = t_end.\nexport function sceneTimeSpan(scene: Dict): { t_start: string; t_end: string } {\n let t_start = \"\";\n let t_end = \"\";\n for (const action of asList<Dict>(scene[\"actions\"])) {\n const ts = actionTimestamp(action);\n if (!ts) continue;\n if (!t_start) t_start = ts;\n t_end = ts;\n }\n return { t_start, t_end };\n}\n\nexport function actionDisplayFields(epId: string, sceneId: string, idx: number, action: Dict): Record<string, unknown> {\n const actorId = actionActorId(action);\n const s = isDict(action[\"speaker\"]) ? (action[\"speaker\"] as Dict) : null;\n // For a non-actor speaker ({kind,label}) surface it under `speaker`; an actor\n // line surfaces under `actor` (its id). Narrative lines have neither.\n const speaker = s && !actorId ? (strOf(s[\"label\"]).trim() || strOf(s[\"kind\"]).trim()) : \"\";\n return {\n addr: actionAddress(epId, sceneId, idx),\n timestamp: actionTimestamp(action),\n type: strOf(action[\"type\"]).trim() || \"action\",\n speaker,\n actor: actorId,\n emotion: strOf(action[\"emotion\"]).trim(),\n content: strOf(action[\"content\"]),\n };\n}\n\nexport function formatInspectAction(epId: string, sceneId: string, idx: number, action: Dict): string {\n const fields = actionDisplayFields(epId, sceneId, idx, action);\n const addr = strOf(fields[\"addr\"]);\n const type = strOf(fields[\"type\"]);\n const delivery = strOf(fields[\"delivery\"]);\n const tag = delivery ? `${type} ${delivery}` : type;\n // Prefer the speaker_id (concrete) over actor_id (asset), and skip both when\n // the action is narrative (no speaker). Format kept on a single line so agents\n // can grep the output.\n const speakerId = strOf(fields[\"speaker\"]);\n const actorId = strOf(fields[\"actor\"]);\n const who = speakerId || actorId;\n const emotion = strOf(fields[\"emotion\"]);\n const timestamp = strOf(fields[\"timestamp\"]);\n const content = strOf(fields[\"content\"]);\n const meta = [tag, timestamp ? `t=${timestamp}` : \"\", emotion ? `emotion=${emotion}` : \"\", who].filter((v) => v).join(\" \");\n const prefix = `${addr} [${meta}]`;\n return content ? `${prefix} ${content}` : prefix;\n}\n\n// ---------------------------------------------------------------------------\n// command_script_patch\n// ---------------------------------------------------------------------------\n\nexport const SKIPPABLE_EDIT_CODES = new Set([\n \"REGEX_NO_MATCH\",\n \"FROM_TEXT_NOT_FOUND\",\n \"OVERLAP_DIALOGUE_UNSUPPORTED\",\n]);\n\nexport function applyPatchOperationsForSession(\n session: ScriptEditSession,\n source: string,\n operations: Dict[],\n): string[] {\n return applyVersionedMutations(session.version, session.script, source, operations);\n}\n\nexport interface V4MutationCounts {\n episodes: number;\n scenes: number;\n actions: number;\n actors: number;\n locations: number;\n props: number;\n states: number;\n}\n\nexport interface V4MutationPlanStep {\n index: number;\n operation: Dict;\n targets: string[];\n status: \"applied\" | \"skipped\";\n before: V4MutationCounts;\n after: V4MutationCounts;\n created_ids: string[];\n removed_ids: string[];\n retained_ids: string[];\n}\n\nexport interface V4MutationPlan {\n version: 1;\n script_version: 4;\n baseline: string;\n operations: Dict[];\n targets: string[];\n steps: V4MutationPlanStep[];\n before: V4MutationCounts;\n after: V4MutationCounts;\n created_ids: string[];\n removed_ids: string[];\n retained_ids: string[];\n untouched_ids: string[];\n validation: ReturnType<typeof validateScriptV4>;\n}\n\nexport interface V4MutationPlanResult {\n plan: V4MutationPlan;\n digest: string;\n applied: string[];\n}\n\nfunction v4Counts(script: ScriptV4): V4MutationCounts {\n return {\n episodes: script.episodes.length,\n scenes: script.episodes.reduce((sum, episode) => sum + episode.scenes.length, 0),\n actions: script.episodes.reduce(\n (sum, episode) => sum + episode.scenes.reduce(\n (sceneSum, scene) => sceneSum + scene.actions.length,\n 0,\n ),\n 0,\n ),\n actors: script.actors.length,\n locations: script.locations.length,\n props: script.props.length,\n states: [...script.actors, ...script.locations, ...script.props]\n .reduce((sum, asset) => sum + asset.states.length, 0),\n };\n}\n\nfunction v4CanonicalIds(script: ScriptV4): string[] {\n return [\n ...script.actors.flatMap((asset) => [\n asset.actor_id,\n ...asset.states.map((state) => `${asset.actor_id}/${state.state_id}`),\n ]),\n ...script.locations.flatMap((asset) => [\n asset.location_id,\n ...asset.states.map((state) => `${asset.location_id}/${state.state_id}`),\n ]),\n ...script.props.flatMap((asset) => [\n asset.prop_id,\n ...asset.states.map((state) => `${asset.prop_id}/${state.state_id}`),\n ]),\n ...script.episodes.flatMap((episode) => [\n episode.episode_id,\n ...episode.scenes.flatMap((scene) => [\n scene.scene_id,\n ...scene.actions.map((action) => action.action_id),\n ]),\n ]),\n ];\n}\n\nfunction orderedIntersection(left: readonly string[], right: ReadonlySet<string>): string[] {\n return left.filter((value) => right.has(value));\n}\n\nfunction v4OperationTargets(operation: Dict): string[] {\n const values: string[] = [];\n const isIdentity = (value: string): boolean => {\n if (value === \"global\") return true;\n if (\n isV4Id(\"episode\", value)\n || isV4Id(\"scene\", value)\n || isV4Id(\"action\", value)\n || isV4Id(\"actor\", value)\n || isV4Id(\"location\", value)\n || isV4Id(\"prop\", value)\n ) return true;\n const slash = value.indexOf(\"/\");\n if (slash < 0 || slash !== value.lastIndexOf(\"/\")) return false;\n const owner = value.slice(0, slash);\n const state = value.slice(slash + 1);\n return (\n isV4Id(\"actor\", owner)\n || isV4Id(\"location\", owner)\n || isV4Id(\"prop\", owner)\n ) && (state === \"default\" || isV4Id(\"state\", state));\n };\n const add = (value: unknown): void => {\n if (typeof value !== \"string\" || value.trim() === \"\") return;\n const normalized = value.trim();\n if (isIdentity(normalized)) values.push(normalized);\n };\n const first = (...fields: string[]): unknown => {\n for (const field of fields) {\n const value = operation[field];\n if (typeof value === \"string\" && value.trim() !== \"\") return value;\n }\n return undefined;\n };\n const addState = (ownerValue: unknown, stateValue: unknown): void => {\n const owner = strOf(ownerValue).trim();\n const state = strOf(stateValue).trim();\n if (owner && state) add(`${owner}/${state}`);\n };\n const addStates = (ownerValue: unknown, stateValues: unknown): void => {\n if (!Array.isArray(stateValues)) return;\n stateValues.forEach((state) => addState(ownerValue, state));\n };\n const addPlacement = (): void => {\n add(operation[\"before\"]);\n add(operation[\"after\"]);\n };\n const kind = strOf(operation[\"op\"]);\n switch (kind) {\n case \"action.parenthetical.set\":\n case \"action.parenthetical.remove\":\n case \"action.timestamp.set\":\n case \"action.timestamp.remove\":\n case \"action.content.replace\":\n case \"action.content.regex-replace\":\n case \"action.type.set\":\n case \"action.delete\":\n case \"action.transition.clear\":\n add(operation[\"at\"]);\n break;\n case \"action.actor.set\":\n case \"dialogue.speaker.set\":\n add(operation[\"at\"]);\n add(operation[\"actor_id\"]);\n addState(operation[\"actor_id\"], operation[\"state_id\"]);\n break;\n case \"action.insert\":\n add(operation[\"at\"]);\n add(first(\"action_id\", \"id\"));\n add(operation[\"actor_id\"]);\n addState(operation[\"actor_id\"], operation[\"state_id\"]);\n addPlacement();\n break;\n case \"action.move\":\n add(operation[\"at\"]);\n add(operation[\"to\"]);\n addPlacement();\n break;\n case \"action.transition.set\":\n add(operation[\"at\"]);\n add(operation[\"target\"]);\n break;\n case \"scene.ref.set\":\n case \"scene.ref.remove\":\n add(operation[\"at\"]);\n add(operation[\"target\"]);\n addStates(operation[\"target\"], operation[\"state_ids\"]);\n break;\n case \"actor.add\":\n add(first(\"actor_id\", \"id\"));\n break;\n case \"location.add\":\n add(first(\"location_id\", \"id\"));\n break;\n case \"prop.add\":\n add(first(\"prop_id\", \"id\"));\n break;\n case \"state.add\": {\n const owner = operation[\"target\"];\n add(owner);\n addState(owner, first(\"state_id\", \"id\"));\n break;\n }\n case \"state.rename\":\n case \"state.describe\":\n add(operation[\"target\"]);\n break;\n case \"state.delete\": {\n const target = strOf(operation[\"target\"]).trim();\n add(target);\n const slash = target.indexOf(\"/\");\n if (slash > 0) addState(target.slice(0, slash), operation[\"replacement\"]);\n break;\n }\n case \"asset.rename\":\n case \"asset.describe\":\n case \"asset.role.set\":\n case \"asset.alias.set\":\n case \"asset.alias.add\":\n case \"asset.alias.remove\":\n case \"importance.set\":\n add(operation[\"target\"]);\n break;\n case \"asset.merge\":\n add(first(\"from\", \"source\"));\n add(first(\"into\", \"target\"));\n break;\n case \"asset.delete\":\n add(operation[\"target\"]);\n if (operation[\"strategy\"] === \"replace\") add(operation[\"replacement\"]);\n break;\n case \"episode.add\":\n add(first(\"episode_id\", \"id\"));\n break;\n case \"episode.synopsis.set\":\n add(first(\"episode_id\", \"target\", \"at\"));\n break;\n case \"meta.worldview.set\":\n case \"meta.synopsis.set\":\n add(\"global\");\n break;\n case \"scene.insert\": {\n const location = first(\"location\", \"location_id\");\n add(first(\"at\", \"episode_id\"));\n add(first(\"scene_id\", \"id\"));\n add(location);\n addStates(location, operation[\"location_state_ids\"]);\n addPlacement();\n break;\n }\n case \"scene.move\":\n add(operation[\"at\"]);\n add(operation[\"to\"]);\n addPlacement();\n break;\n case \"scene.delete\":\n add(operation[\"at\"]);\n break;\n case \"scene.split\":\n add(operation[\"at\"]);\n add(first(\"at_action\", \"action_id\"));\n add(first(\"new_scene_id\", \"scene_id\"));\n break;\n case \"scene.merge\":\n add(operation[\"from\"]);\n add(operation[\"into\"]);\n break;\n case \"extend.set\":\n case \"extend.clear\":\n add(operation[\"at\"]);\n break;\n default:\n throw new Error(`V4 plan target mapping is missing for operation ${kind}`);\n }\n return [...new Set(values)];\n}\n\nexport function buildV4MutationPlan(\n session: ScriptEditSession,\n operations: Dict[],\n options: { skipCodes?: ReadonlySet<string> } = {},\n): V4MutationPlanResult {\n if (session.version !== 4) {\n throw new CliError(\"A v4 mutation plan requires Script v4.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"V4_PLAN_VERSION_INVALID\",\n data: { actual: [`Script v${session.version}`] },\n });\n }\n const original = requireStructurallyReadableScriptV4(session.script);\n const proposed = structuredClone(original);\n const originalIds = v4CanonicalIds(original);\n const applied: string[] = [];\n const steps: V4MutationPlanStep[] = [];\n for (const [index, operation] of operations.entries()) {\n const beforeIds = v4CanonicalIds(proposed);\n const beforeSet = new Set(beforeIds);\n const before = v4Counts(proposed);\n let status: V4MutationPlanStep[\"status\"] = \"applied\";\n try {\n applied.push(...applyPatchOperationsV4(proposed, [operation]));\n } catch (error) {\n if (\n error instanceof CliError\n && error.errorCode\n && options.skipCodes?.has(error.errorCode)\n ) {\n status = \"skipped\";\n } else {\n throw error;\n }\n }\n const afterIds = v4CanonicalIds(proposed);\n const afterSet = new Set(afterIds);\n steps.push({\n index,\n operation,\n targets: v4OperationTargets(operation),\n status,\n before,\n after: v4Counts(proposed),\n created_ids: afterIds.filter((id) => !beforeSet.has(id)),\n removed_ids: beforeIds.filter((id) => !afterSet.has(id)),\n retained_ids: orderedIntersection(beforeIds, afterSet),\n });\n }\n const proposedIds = v4CanonicalIds(proposed);\n const originalSet = new Set(originalIds);\n const proposedSet = new Set(proposedIds);\n const targets = [...new Set(steps.flatMap((step) => step.targets))];\n const touched = new Set([\n ...targets,\n ...steps.flatMap((step) => step.created_ids),\n ...steps.flatMap((step) => step.removed_ids),\n ]);\n const plan: V4MutationPlan = {\n version: 1,\n script_version: 4,\n baseline: session.baselineHash,\n operations,\n targets,\n steps,\n before: v4Counts(original),\n after: v4Counts(proposed),\n created_ids: proposedIds.filter((id) => !originalSet.has(id)),\n removed_ids: originalIds.filter((id) => !proposedSet.has(id)),\n retained_ids: orderedIntersection(originalIds, proposedSet),\n untouched_ids: orderedIntersection(originalIds, proposedSet)\n .filter((id) => !touched.has(id)),\n validation: validateScriptV4(proposed),\n };\n return {\n plan,\n digest: `sha256:${sha256Text(JSON.stringify(sortDeep(plan)))}`,\n applied,\n };\n}\n\nconst V4_PLANNED_ID_FIELDS: Readonly<Record<string, string>> = {\n \"actor.add\": \"actor_id\",\n \"location.add\": \"location_id\",\n \"prop.add\": \"prop_id\",\n \"state.add\": \"state_id\",\n \"episode.add\": \"episode_id\",\n \"scene.insert\": \"scene_id\",\n \"scene.split\": \"new_scene_id\",\n \"action.insert\": \"action_id\",\n};\n\nexport function assertV4PlanHasExplicitNewIds(operations: Dict[]): void {\n for (const operation of operations) {\n const kind = strOf(operation[\"op\"]);\n const field = V4_PLANNED_ID_FIELDS[kind];\n if (!field || strOf(operation[field]).trim()) continue;\n const idKind = field === \"new_scene_id\" ? \"scene\" : field.replace(/_id$/, \"\");\n throw new CliError(\"Planned creation operations require an explicit candidate ID.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"V4_PLAN_ID_REQUIRED\",\n hint: `Generate a candidate with \\`scriptctl ids --kind ${idKind} --count 1\\`, then include it in the operation.`,\n data: { expected: [`${kind}.${field}`], actual: [`${kind}.${field}=<missing>`] },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Single-op helpers\n// ---------------------------------------------------------------------------\n\nexport async function applySingleScriptOpToSession(\n session: ScriptEditSession,\n opts: Dict,\n op: Dict,\n): Promise<[CommandOutput, number]> {\n const plan = strOf(opts[\"plan\"]).trim();\n if (plan) {\n throw new CliError(\"Single-point writes do not use plan digests.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MULTI_PLAN_USAGE_INVALID\",\n hint: \"Remove --plan from this single-point edit.\",\n data: { actual: [plan] },\n });\n }\n return applyScriptOpsToSession(session, opts, [op]);\n}\n\nexport async function applyScriptOpsToSession(\n session: ScriptEditSession,\n opts: Dict,\n operations: Dict[],\n): Promise<[CommandOutput, number]> {\n const workspace = strOf(opts[\"workspace_path\"] || \"workspace\");\n const applied = applyPatchOperationsForSession(session, scriptSourceText(workspace), operations);\n const opName = applied.length === 1 ? applied[0]! : \"script.ops\";\n const [newRevision, idempotent] = await saveScriptSession(session, opts, opName);\n const validation = validateSession(session);\n await syncValidationResult(session, validation, newRevision);\n const passed = Boolean(validation[\"passed\"]);\n const warnings = mutationValidationWarnings(session, validation);\n // One outcome line: what changed + revision (remote) + validation verdict.\n const rev = session.remote ? `; rev ${newRevision}` : \"\";\n const resultLine = `${applied.join(\", \")} applied${rev}; validation ${passed ? \"passed\" : \"needs repair\"}`;\n const issues = summarizeIssues(asList<Dict>(validation[\"issues\"]));\n const warningLines = summarizeIssues(warnings);\n const report: CommandOutput = {\n text: [resultLine, ...warningLines].join(\"\\n\"),\n data: {\n op: opName,\n changed: applied.length > 0,\n revision: session.remote ? newRevision : undefined,\n idempotent: session.remote ? idempotent : undefined,\n validation,\n issues,\n warnings,\n script_path: session.artifactLabel,\n },\n };\n return [report, EXIT_OK];\n}\n\nexport async function applySingleScriptOp(opts: Dict, op: Dict): Promise<[CommandOutput, number]> {\n const session = await loadScriptForEdit(opts);\n return applySingleScriptOpToSession(session, opts, op);\n}\n\nexport function summarizeScriptOp(_script: Dict, op: Dict): string {\n const kind = strOf(op[\"op\"]);\n if (kind === \"actor.add\") return `Added actor ${op[\"name\"] || op[\"actor_name\"]}${op[\"role_type\"] ? ` (${op[\"role_type\"]})` : \"\"}`;\n if (kind === \"location.add\") return `Added location ${op[\"name\"] || op[\"location_name\"]}`;\n if (kind === \"prop.add\") return `Added prop ${op[\"name\"] || op[\"prop_name\"]}`;\n if (kind === \"episode.add\") return `Added episode${op[\"episode_id\"] ? ` ${op[\"episode_id\"]}` : \" (generated ID)\"}${op[\"title\"] ? `: ${op[\"title\"]}` : \"\"}`;\n if (kind === \"meta.synopsis.set\") return \"Updated script synopsis\";\n if (kind === \"episode.synopsis.set\") return `Updated episode synopsis ${op[\"episode_id\"] ?? op[\"target\"] ?? op[\"at\"]}`;\n if (kind === \"state.add\") return `Added state ${op[\"state_id\"]}: ${op[\"name\"] || op[\"state_name\"]} to ${op[\"target\"]}`;\n if (kind === \"importance.set\") return `Set ${op[\"target\"]} importance to ${op[\"importance\"]}`;\n if (kind === \"scene.ref.set\") return `Set reference ${op[\"target\"]} on ${op[\"at\"]}${op[\"state\"] ? ` (state ${op[\"state\"]})` : \"\"}`;\n if (kind === \"extend.set\") return `Set extend.${op[\"key\"]} on ${op[\"at\"]}`;\n if (kind === \"extend.clear\") return op[\"key\"] ? `Removed extend.${op[\"key\"]} from ${op[\"at\"]}` : `Cleared extend on ${op[\"at\"]}`;\n if (kind === \"action.timestamp.set\") return `Set timestamp on ${op[\"at\"]}`;\n if (kind === \"action.timestamp.remove\") return `Removed timestamp from ${op[\"at\"]}`;\n if (kind.startsWith(\"state.\")) return `Applied ${kind}: ${op[\"target\"]}`;\n if (kind.startsWith(\"dialogue.\")) return `Applied ${kind}: ${op[\"at\"]}`;\n return `Applied ${kind}`;\n}\n\n// Accept `/re/flags` as-is; wrap a bare pattern as `/pattern/` so\n// `replace --regex --from '^\\s*\\[[^\\]]*\\]'` works without the user typing slashes.\n\nexport function regexPattern(raw: string): string {\n const s = raw.trim();\n if (s.length >= 2 && s.startsWith(\"/\") && s.lastIndexOf(\"/\") > 0) return s;\n return `/${s}/`;\n}\n\n// The selector-driven write runner. Resolves `opts` to its matched actions\n// (range/region + predicates) and applies one op template to each, as a single\n// in-memory pass committed once. Guardrail: with no --apply it's a DRY-RUN that\n// reports the blast radius and writes nothing; --apply commits. Per-action\n// \"no match here / overlap dialogue\" errors are skipped (a sweep); anything else\n// aborts the whole edit before any write. Shared by every selector-capable verb.\n\nexport async function applySelectorEditsToSession(\n session: ScriptEditSession,\n opts: Dict,\n template: Dict,\n verbLabel: string,\n): Promise<[CommandOutput, number]> {\n const workspace = strOf(opts[\"workspace_path\"] || \"workspace\");\n const apply = Boolean(opts[\"apply\"]);\n const opName = strOf(template[\"op\"]);\n const script = session.script;\n const refs = session.version === 3\n ? resolveActionTargets(script, opts).map((target) => `${target.epId}/${target.sceneId}#${target.idx}`)\n : resolveActionTargetsV4(requireStructurallyReadableScriptV4(script), opts, { allowOrdinals: false })\n .map((target) => target.action.action_id);\n const operations = refs.map((ref) => ({ ...template, at: ref }));\n const multiV4 = session.version === 4 && refs.length > 1;\n const planned = multiV4\n ? buildV4MutationPlan(session, operations, { skipCodes: SKIPPABLE_EDIT_CODES })\n : null;\n const planDigest = planned?.digest ?? null;\n const suppliedPlan = strOf(opts[\"plan\"]).trim();\n if (suppliedPlan && (!multiV4 || !apply)) {\n throw new CliError(\"A plan digest is only accepted for a v4 multi-target apply.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MULTI_PLAN_USAGE_INVALID\",\n hint: \"Remove --plan, or apply the same v4 multi-target selection that produced the digest.\",\n data: { actual: [suppliedPlan] },\n });\n }\n if (multiV4 && apply && !suppliedPlan) {\n throw new CliError(\"A v4 multi-target write requires its dry-run plan digest.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MULTI_PLAN_REQUIRED\",\n hint: \"Run the same command without --apply, review the full plan, then retry with `--apply --plan <digest>`.\",\n data: { expected: [planDigest ?? \"\"], actual: [\"<missing>\"] },\n });\n }\n if (multiV4 && apply && suppliedPlan !== planDigest) {\n throw new CliError(\"The supplied digest does not match the current targets and operations.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"MULTI_PLAN_MISMATCH\",\n hint: \"Review the newly computed dry-run plan, then apply its exact digest.\",\n data: { expected: [planDigest ?? \"\"], actual: [suppliedPlan] },\n });\n }\n const source = scriptSourceText(workspace);\n let applied = planned?.plan.steps.filter((step) => step.status === \"applied\").length ?? 0;\n let skipped = planned?.plan.steps.filter((step) => step.status === \"skipped\").length ?? 0;\n if (!planned) {\n for (const ref of refs) {\n try {\n applyPatchOperationsForSession(session, source, [{ ...template, at: ref }]);\n applied += 1;\n } catch (err) {\n if (err instanceof CliError && err.errorCode && SKIPPABLE_EDIT_CODES.has(err.errorCode)) {\n skipped += 1;\n continue;\n }\n throw err;\n }\n }\n } else if (apply) {\n for (const step of planned.plan.steps) {\n if (step.status === \"applied\") {\n applyPatchOperationsForSession(session, source, [step.operation]);\n }\n }\n }\n const displayedRefs = multiV4 ? refs : refs.slice(0, 12);\n const blast = [\n `verb: ${verbLabel} (${opName})`,\n `matched: ${refs.length} action(s)`,\n `${apply ? \"applied\" : \"would-apply\"}: ${applied}`,\n `${apply ? \"skipped\" : \"would-skip\"}: ${skipped}`,\n ...(displayedRefs.length ? [`targets: ${displayedRefs.join(\", \")}${refs.length > displayedRefs.length ? ` \u2026 (+${refs.length - displayedRefs.length} more)` : \"\"}`] : []),\n ...(planDigest ? [`plan_digest: ${planDigest}`] : []),\n ];\n\n if (!apply) {\n const legacyValidation = planned ? null : validateSession(session);\n const passed = planned\n ? planned.plan.validation.ok\n : Boolean(legacyValidation?.[\"passed\"]);\n const plannedIssueLines = planned\n ? [...planned.plan.validation.errors, ...planned.plan.validation.warnings]\n .map((issue) => `${issue.path}: ${issue.code} - ${issue.message}`)\n : null;\n const legacyIssueLines = legacyValidation === null\n ? []\n : summarizeIssues(asList<Dict>(legacyValidation[\"issues\"]));\n const issues = plannedIssueLines ?? legacyIssueLines;\n const hint = refs.length === 0\n ? \"Widen the selection with --in, --grep, or predicates.\"\n : planDigest\n ? `Run again with --apply --plan ${planDigest} to commit this exact plan${passed ? \".\" : \"; validation issues will remain available as follow-up diagnostics.\"}`\n : `Run again with --apply to commit${passed ? \".\" : \"; validation issues will remain available as follow-up diagnostics.\"}`;\n const lines = [...blast, `validation: ${passed ? \"would pass\" : \"would need repair\"}; no write`, ...issues, hint];\n const report: CommandOutput = {\n text: lines.join(\"\\n\"),\n data: {\n op: `${opName}.dry-run`,\n changed: false,\n matched: refs.length,\n applied,\n skipped,\n issues,\n script_path: session.artifactLabel,\n ...(planDigest ? {\n baseline: session.baselineHash,\n plan_digest: planDigest,\n operations,\n targets: refs,\n plan: planned?.plan,\n } : {}),\n },\n };\n return [report, EXIT_OK];\n }\n\n if (refs.length === 0) {\n return [{\n text: [...blast, \"Widen the selection with --in, --grep, or predicates.\"].join(\"\\n\"),\n data: {\n op: opName,\n changed: false,\n matched: 0,\n script_path: session.artifactLabel,\n },\n }, EXIT_OK];\n }\n\n const [newRevision, idempotent] = await saveScriptSession(session, opts, opName);\n const validation = validateSession(session);\n await syncValidationResult(session, validation, newRevision);\n const passed = Boolean(validation[\"passed\"]);\n const warnings = mutationValidationWarnings(session, validation);\n const rev = session.remote ? `; rev ${newRevision}` : \"\";\n const issues = summarizeIssues(asList<Dict>(validation[\"issues\"]));\n const warningLines = summarizeIssues(warnings);\n const report: CommandOutput = {\n text: [...blast, `validation: ${passed ? \"passed\" : \"needs repair\"}${rev}`, ...warningLines].join(\"\\n\"),\n data: {\n op: opName,\n changed: applied > 0,\n matched: refs.length,\n applied,\n skipped,\n revision: session.remote ? newRevision : undefined,\n idempotent: session.remote ? idempotent : undefined,\n validation,\n issues,\n warnings,\n script_path: session.artifactLabel,\n ...(planDigest ? {\n baseline: session.baselineHash,\n plan_digest: planDigest,\n operations,\n targets: refs,\n plan: planned?.plan,\n } : {}),\n },\n };\n return [report, EXIT_OK];\n}\n\nexport async function applySelectorEdits(opts: Dict, template: Dict, verbLabel: string): Promise<[CommandOutput, number]> {\n const session = await loadScriptForEdit(opts);\n return applySelectorEditsToSession(session, opts, template, verbLabel);\n}\n\nexport { sortDeep };\n\n// ===========================================================================\n// 0.6.0 plural-noun query commands (replace `commandScriptInspect --target X`)\n// ===========================================================================\n//\n// Each command is a thin read-only wrapper around the underlying script\n// document. They all return a CommandOutput shaped like inspect's existing output but\n// without the `--target` flag \u2014 the verb itself encodes the target. Filters\n// use `--in <addr>` (compose with the address parsers) plus per-target\n// predicates (--name / --kind / --has / --grep / --context / --type / --actor\n// / --speaker / --severity / --code / --has-{actor,location,prop}).\n\n// Resolve the speaker_id \u2192 source actor mapping once per call. Used by\n// commandActions's --actor filter when the action speaks via a speaker.\n\n// v3: a dialogue line carries a single inline speaker \u2014 an actor ({actor_id})\n// or a non-actor source ({kind, label?}). These read that shape.\n\n// The actor id behind an action's speaker, or \"\" for a non-actor / narrative line.\nexport function actionActorId(action: Dict): string {\n const s = action[\"speaker\"];\n if (isDict(s) && strOf(s[\"actor_id\"]).trim()) return strOf(s[\"actor_id\"]).trim();\n return \"\";\n}\n\n// A human label for the speaker: the actor's name (resolved via `names`), or a\n// non-actor kind's label / kind, or \"\" when the line has no speaker.\nexport function actionSpeakerLabel(action: Dict, actorNames?: Map<string, string>): string {\n const s = action[\"speaker\"];\n if (!isDict(s)) return \"\";\n const actorId = strOf(s[\"actor_id\"]).trim();\n if (actorId) return actorNames?.get(actorId) || actorId;\n const kind = strOf(s[\"kind\"]).trim();\n if (kind) return strOf(s[\"label\"]).trim() || kind;\n return \"\";\n}\n\nexport function actorIdsInAction(action: Dict): Set<string> {\n const ids = new Set<string>();\n const id = actionActorId(action);\n if (id) ids.add(id);\n return ids;\n}\n\n// Build a grep matcher. /pattern/flags \u2192 RegExp, otherwise literal substring.\n// Pre-flight checks block the common ReDoS shapes before they hit V8's regex\n// engine: nested quantifiers like (a+)+, (a*)+, (a*|b*)+ etc. compile fine\n// but hang the process on adversarial input. Since --grep accepts caller-\n// controlled patterns and runs over every action in scope, the safe move is\n// to reject patterns with quantifier-on-group-with-internal-quantifier and\n// cap the pattern length.\n\nexport function buildGrepMatcher(raw: string): ((hay: string) => boolean) | null {\n if (!raw) return null;\n const m = /^\\/(.+)\\/([gimsuy]*)$/.exec(raw);\n if (m) {\n const pattern = m[1]!;\n if (isDangerousRegex(pattern)) {\n throw new CliError(\"regex pattern has nested quantifiers (ReDoS risk) or exceeds the length limit.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"REGEX_UNSAFE\",\n hint: \"Rewrite the regex to avoid nested quantifiers, or use a literal substring (drop the /\u2026/ wrapper).\",\n data: { expected: [`pattern length <= ${MAX_GREP_PATTERN_LEN}; no quantifier-on-group-with-internal-quantifier (e.g. (a+)+)`], actual: [`length=${pattern.length}, sample=${pattern.slice(0, 80)}`] },\n });\n }\n try {\n const re = new RegExp(pattern, m[2]!);\n return (hay: string) => {\n re.lastIndex = 0;\n return re.test(hay);\n };\n } catch {\n // Malformed regex \u2014 treat as literal.\n }\n }\n return (hay: string) => hay.includes(raw);\n}\n\nexport interface TableQueryResult {\n lines: string[];\n rows: Array<Record<string, unknown>>;\n rowColumns: string[];\n}\n\nexport function buildReport(op: string, lines: string[]): CommandOutput {\n const outputLines = lines.length > 0 ? lines : [\"No matches.\"];\n return {\n text: outputLines.join(\"\\n\"),\n data: {\n op,\n changed: false,\n },\n };\n}\n\nexport function buildTableReport(\n op: string,\n lines: string[],\n rowColumns: string[],\n rows: Array<Record<string, unknown>>,\n): CommandOutput {\n const report = buildReport(op, lines);\n report.data[\"row_columns\"] = rowColumns;\n report.data[\"rows\"] = rows;\n return report;\n}\n\n// ----- summary --------------------------------------------------------------\n\nexport function synopsisPreview(text: string, limit: number): string {\n const oneLine = text.replace(/\\s+/g, \" \").trim();\n return oneLine.length > limit ? `${oneLine.slice(0, limit)}\u2026` : oneLine;\n}\n\nexport function episodeInSelector(selector: InSelector, epId: string, scenes: Dict[]): boolean {\n if (selector.isEmpty) return true;\n if (selector.matchesScene(epId, \"scn_000000\")) return true;\n for (const scene of scenes) {\n if (selector.matchesScene(epId, strOf(scene[\"scene_id\"]))) return true;\n }\n return false;\n}\n\nexport function nameMaps(script: Dict): { actor: Map<string, string>; location: Map<string, string>; prop: Map<string, string> } {\n const out = { actor: new Map<string, string>(), location: new Map<string, string>(), prop: new Map<string, string>() };\n for (const a of asList<Dict>(script[\"actors\"])) out.actor.set(strOf(a[\"actor_id\"]), strOf(a[\"actor_name\"]));\n for (const l of asList<Dict>(script[\"locations\"])) out.location.set(strOf(l[\"location_id\"]), strOf(l[\"location_name\"]));\n for (const p of asList<Dict>(script[\"props\"])) out.prop.set(strOf(p[\"prop_id\"]), strOf(p[\"prop_name\"]));\n return out;\n}\n\nexport function formatScene(epId: string, scene: Dict, names: ReturnType<typeof nameMaps>): string {\n const ctx = sceneRefs(scene);\n const env = isDict(scene[\"environment\"]) ? (scene[\"environment\"] as Dict) : {};\n const space = strOf(env[\"space\"]) || \"-\";\n const time = strOf(env[\"time\"]) || \"-\";\n const locations = asList<Dict>(ctx[\"locations\"]).map((r) => {\n const id = strOf(r[\"location_id\"]);\n return `${id}(${names.location.get(id) || \"?\"})`;\n });\n const actors = asList<Dict>(ctx[\"actors\"]).map((r) => {\n const id = strOf(r[\"actor_id\"]);\n return `${id}(${names.actor.get(id) || \"?\"})`;\n });\n const props = asList<Dict>(ctx[\"props\"]).map((r) => {\n const id = strOf(r[\"prop_id\"]);\n return `${id}(${names.prop.get(id) || \"?\"})`;\n });\n const actionCount = asList<Dict>(scene[\"actions\"]).length;\n const { t_start, t_end } = sceneTimeSpan(scene);\n const timePart = t_start || t_end ? ` t=${t_start || \"?\"}..${t_end || \"?\"}` : \"\";\n return `${epId}/${scene[\"scene_id\"]} [${space} ${time}] location=${locations.join(\",\") || \"-\"} actors=${actors.join(\",\") || \"-\"} props=${props.join(\",\") || \"-\"} actions=${actionCount}${timePart}`;\n}\n\nexport interface ActionTarget { epId: string; sceneId: string; idx: number; action: Dict; }\n\nexport const HAS_FILTERS = new Set([\"transition\", \"speaker\"]);\n\n// Resolve a selection (--in range/region selector + --type/--actor/--speaker/\n// --grep/--has predicates, AND-combined) to the matching actions, in document\n// order. The single matcher behind both `actions` queries and selector-driven\n// writes. Does NOT enforce \"at least one filter\" \u2014 that policy is caller-owned\n// (queries refuse a bare dump; writes gate on --all). Validates the --has value.\n\nexport function resolveActionTargets(script: Dict, opts: Dict): ActionTarget[] {\n const selector = parseInSelector(strOf(opts[\"in\"]));\n const timestampRange = actionTimestampFilter(opts);\n const typeFilter = strOf(opts[\"type\"]).trim();\n const actorFilter = strOf(opts[\"actor\"]).trim();\n const hasFilter = strOf(opts[\"has\"]).trim();\n // Whitelist --has: silently accepting unknown values means a typo like\n // \"state_changes\" (underscore) passed the filter-missing guard but bypassed\n // every concrete predicate, returning the whole script.\n if (hasFilter && !HAS_FILTERS.has(hasFilter)) {\n throw new CliError(\"--has value invalid.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"HAS_FILTER_INVALID\",\n hint: \"Use a supported --has value.\",\n data: { expected: [`--has: one of ${[...HAS_FILTERS].join(\", \")}`], actual: [hasFilter] },\n });\n }\n const grepMatcher = buildGrepMatcher(strOf(opts[\"grep\"]));\n const out: ActionTarget[] = [];\n for (const ep of asList<Dict>(script[\"episodes\"])) {\n const epId = strOf(ep[\"episode_id\"]);\n for (const scene of asList<Dict>(ep[\"scenes\"])) {\n const sceneId = strOf(scene[\"scene_id\"]);\n if (!selector.matchesScene(epId, sceneId)) continue;\n const actions = asList<Dict>(scene[\"actions\"]);\n for (let i = 0; i < actions.length; i++) {\n if (!selector.matchesAction(epId, sceneId, i)) continue;\n const a = actions[i]!;\n if (\n timestampRange\n && !actionTimestampMatches(\n isDict(a[\"extend\"]) ? (a[\"extend\"] as Dict)[\"timestamp\"] : undefined,\n timestampRange,\n actionAddress(epId, sceneId, i),\n )\n ) continue;\n if (typeFilter && strOf(a[\"type\"]).trim() !== typeFilter) continue;\n if (actorFilter && !actorIdsInAction(a).has(actorFilter)) continue;\n if (hasFilter === \"transition\" && !isDict(a[\"transition_prompt\"])) continue;\n if (hasFilter === \"speaker\" && !isDict(a[\"speaker\"])) continue;\n if (grepMatcher && !grepMatcher(strOf(a[\"content\"]))) continue;\n out.push({ epId, sceneId, idx: i, action: a });\n }\n }\n }\n return out;\n}\n\n// Whether a selection in `opts` has any filter at all (scope or predicate).\n\nexport function selectionHasAnyFilter(opts: Dict): boolean {\n return Boolean(\n strOf(opts[\"in\"]).trim() ||\n strOf(opts[\"grep\"]) || strOf(opts[\"type\"]).trim() || strOf(opts[\"actor\"]).trim() ||\n strOf(opts[\"has\"]).trim(),\n );\n}\n\n// Collapse a set of episode ids into sorted, comma-joined ranges:\n// {ep_001, ep_002, ep_003, ep_007} \u2192 \"ep_001..ep_003,ep_007\". Keeps the state\n// arc / appearance lines readable even when an item spans dozens of episodes.\nexport function compactEpisodeRanges(ids: Iterable<string>): string {\n const nums = [...new Set([...ids])]\n .map((id) => ({ id, n: idNum(id, \"ep\") }))\n .filter((x) => Number.isFinite(x.n))\n .sort((a, b) => a.n - b.n);\n if (nums.length === 0) return \"\";\n const parts: string[] = [];\n let start = nums[0]!;\n let prev = nums[0]!;\n const flush = () => parts.push(start.id === prev.id ? start.id : `${start.id}..${prev.id}`);\n for (let i = 1; i < nums.length; i++) {\n const cur = nums[i]!;\n if (cur.n === prev.n + 1) { prev = cur; continue; }\n flush();\n start = cur;\n prev = cur;\n }\n flush();\n return parts.join(\",\");\n}\n\n// One pass over scene context: for each asset id of `kind`, the set of episodes\n// and count of scenes it is referenced in. \"Appearance\" = presence in a scene's\n// context (the canonical who/what-is-in-this-scene list direct-init populates).\nexport function assetAppearanceCounts(\n script: Dict,\n kind: \"actor\" | \"location\" | \"prop\",\n): Map<string, { episodes: Set<string>; scenes: number }> {\n const idKey = kind === \"actor\" ? \"actor_id\" : kind === \"location\" ? \"location_id\" : \"prop_id\";\n const pluralKey = kind === \"actor\" ? \"actors\" : kind === \"location\" ? \"locations\" : \"props\";\n const out = new Map<string, { episodes: Set<string>; scenes: number }>();\n for (const ep of asList<Dict>(script[\"episodes\"])) {\n const epId = strOf(ep[\"episode_id\"]);\n for (const scene of asList<Dict>(ep[\"scenes\"])) {\n const ctx = sceneRefs(scene);\n const seen = new Set<string>();\n for (const ref of asList<Dict>(ctx[pluralKey])) {\n const id = strOf(ref[idKey]);\n if (!id || seen.has(id)) continue;\n seen.add(id);\n const entry = out.get(id) ?? { episodes: new Set<string>(), scenes: 0 };\n entry.episodes.add(epId);\n entry.scenes += 1;\n out.set(id, entry);\n }\n }\n }\n return out;\n}\n\nexport function listAssetsByKind(\n script: Dict,\n kind: \"actor\" | \"location\" | \"prop\",\n opts: { id: string; name: string; selector: InSelector; counts?: boolean },\n): TableQueryResult {\n const lines: string[] = [];\n const rows: Array<Record<string, unknown>> = [];\n const [key, idKey, nameKey] = (() => {\n switch (kind) {\n case \"actor\": return [\"actors\", \"actor_id\", \"actor_name\"] as const;\n case \"location\": return [\"locations\", \"location_id\", \"location_name\"] as const;\n case \"prop\": return [\"props\", \"prop_id\", \"prop_name\"] as const;\n }\n })();\n // Build the set of asset ids referenced inside the --in scope. A range or\n // multi-region selector takes the union of context refs over every matched\n // scene; a bare single action point (e.g. ep_001/scn_003#2) keeps the legacy\n // \"narrow to that one action's actor\" behavior.\n // WHOLE_SCRIPT ('--in *') means \"all assets\" \u2014 it must NOT narrow to the set\n // of assets referenced in scene context (that would drop registered-but-not-\n // yet-placed assets). Only a real address-region selector narrows.\n let scopeIds: Set<string> | null = null;\n if (!opts.selector.isEmpty && opts.selector !== WHOLE_SCRIPT) {\n scopeIds = new Set<string>();\n const single = selectorSingleActionPoint(opts.selector);\n const pluralKey = kind === \"actor\" ? \"actors\" : kind === \"location\" ? \"locations\" : \"props\";\n for (const ep of asList<Dict>(script[\"episodes\"])) {\n const epId = strOf(ep[\"episode_id\"]);\n for (const scene of asList<Dict>(ep[\"scenes\"])) {\n const sceneId = strOf(scene[\"scene_id\"]);\n if (!opts.selector.matchesScene(epId, sceneId)) continue;\n if (single) {\n // Single action point: matchesScene already isolates the target\n // scene. Legacy narrowing is implemented for actor only.\n if (kind === \"actor\") {\n const a = asList<Dict>(scene[\"actions\"])[single.idx];\n const aid = a ? actionActorId(a) : \"\";\n if (aid) scopeIds.add(aid);\n }\n continue;\n }\n const ctx = sceneRefs(scene);\n for (const ref of asList<Dict>(ctx[pluralKey])) {\n scopeIds.add(strOf(ref[idKey]));\n }\n }\n }\n }\n // Appearance counts (scenes / episodes) computed in one pass, only when asked\n // \u2014 keeps the default listing lean.\n const appearances = opts.counts ? assetAppearanceCounts(script, kind) : null;\n for (const asset of asList<Dict>(script[key])) {\n const id = strOf(asset[idKey]);\n const name = strOf(asset[nameKey]);\n if (opts.id && opts.id !== id) continue;\n if (opts.name && !name.includes(opts.name)) continue;\n if (scopeIds && !scopeIds.has(id)) continue;\n const aliases = asList<string>(asset[\"aliases\"]).map((s) => strOf(s));\n const role = strOf(asset[\"role_type\"]);\n const importance = strOf(asset[\"importance\"]);\n const descPresent = strOf(asset[\"description\"]).trim() ? \"yes\" : \"missing\";\n const states = asList(asset[\"states\"]).length;\n const extra: string[] = [];\n if (aliases.length > 0) extra.push(`aliases=(${aliases.join(\",\")})`);\n if (importance) extra.push(`importance=${importance}`);\n if (role) extra.push(`role=${role}`);\n extra.push(`states=${states}`, `description=${descPresent}`);\n if (appearances) {\n const seen = appearances.get(id);\n const eps = seen ? seen.episodes.size : 0;\n const scns = seen ? seen.scenes : 0;\n const arc = seen && eps > 0 ? ` episodes=${compactEpisodeRanges(seen.episodes)}` : \"\";\n extra.push(`scenes=${scns}`, `episodes_count=${eps}${arc}`);\n }\n lines.push(`${kind} ${id}: ${name || \"-\"} ${extra.join(\" \")}`);\n const seen = appearances?.get(id);\n rows.push({\n addr: `${kind}:${id}`,\n kind,\n id,\n name,\n aliases,\n importance,\n role,\n states,\n description_present: descPresent === \"yes\",\n ...(appearances\n ? {\n scenes: seen?.scenes ?? 0,\n episodes_count: seen?.episodes.size ?? 0,\n episodes: seen ? compactEpisodeRanges(seen.episodes) : \"\",\n }\n : {}),\n });\n }\n return {\n lines,\n rows,\n rowColumns: [\n \"addr\",\n \"kind\",\n \"id\",\n \"name\",\n \"aliases\",\n \"importance\",\n \"role\",\n \"states\",\n \"description_present\",\n ...(appearances ? [\"scenes\", \"episodes_count\", \"episodes\"] : []),\n ],\n };\n}\n\nexport function splitSpeakerList(raw: unknown): string[] {\n if (Array.isArray(raw)) return raw.map((v) => strOf(v)).filter((v) => v);\n return strOf(raw).split(\",\").map((s) => s.trim()).filter((s) => s);\n}\n\nexport function blankCreateReport(session: ScriptEditSession, validation: Dict, idempotent: boolean | null): CommandOutput {\n const passed = Boolean(validation[\"passed\"]);\n const resultLines = [`created: blank script (Script v${session.version})`, `validation: ${passed ? \"passed\" : \"needs repair\"}`];\n if (session.remote) {\n resultLines.push(`revision: ${session.revision}`);\n if (idempotent !== null) resultLines.push(`idempotent: ${String(idempotent).toLowerCase()}`);\n }\n return {\n text: resultLines.join(\"\\n\"),\n data: {\n op: \"script.create\",\n changed: true,\n validation,\n script_path: session.artifactLabel,\n ...(session.remote ? { revision: session.revision, idempotent } : {}),\n },\n };\n}\n\n// ----- add-* (register new entities) ----------------------------------------\n\n// Read the single positional <name> arg shared by add-actor/location/prop, or\n// throw the common ARGS_MISSING usage error with a verb-specific example.\n\nexport function requireNameArg(opts: Dict, verb: string, example: string): string {\n const args = asList<string>(opts[\"_args\"]);\n if (args.length < 1) {\n throw new CliError(\"Name missing.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"ARGS_MISSING\",\n hint: example,\n data: { expected: [\"<name>\"], actual: [\"<empty>\"] },\n });\n }\n return args[0]!;\n}\n", "import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nimport {\n CliError,\n EXIT_INPUT,\n EXIT_NEEDS_AGENT,\n EXIT_OK,\n EXIT_RUNTIME,\n type CommandOutput,\n directDir,\n exists,\n readJson,\n readText,\n scriptJsonPath,\n sha256Text,\n writeJson,\n} from \"../../common.js\";\nimport { atomicWriteJson } from \"../../infra/script-working-copy.js\";\nimport { applyPatchOperations } from \"../../domain/script/patch/apply.js\";\nimport { blankScriptV4 } from \"../../domain/script/v4/factory.js\";\nimport { collectAssetRefs, collectStateRefs } from \"../../domain/script/refs.js\";\nimport {\n expandSelectorToActionRefs,\n isDangerousRegex,\n MAX_GREP_PATTERN_LEN,\n parseInSelector,\n selectorSingleActionPoint,\n type InSelector,\n} from \"../../domain/script/selector.js\";\nimport {\n parseAnyAddress,\n parseActionRef,\n parseAssetTarget,\n parseSceneRef,\n parseStateTarget,\n} from \"../../domain/script/address.js\";\nimport { PATCH_OP_SCHEMA } from \"../../domain/script/schema.js\";\nimport { LocalScriptOutputStore } from \"../../infra/local-script-output-store.js\";\nimport {\n ScriptOutputApiError,\n resolveOutputMode,\n type ConfigMissingSlot,\n type ScriptOutputStore,\n} from \"../../infra/script-output-store.js\";\nimport { summarizeIssues } from \"../../domain/script/text-util.js\";\nimport { sortDeep } from \"../../domain/script/text-util.js\";\nimport {\n asList,\n type Dict,\n isDict,\n isList,\n strOf,\n} from \"../../domain/script/shared.js\";\nimport {\n ScriptEditSession, scriptOutputClient, apiErrorToCli, currentRevisionOrZero,\n loadScriptForEdit, validateSession, saveScriptSession, syncValidationResult, assertTargetCoherent,\n scriptSourceText, patchOperationsFromPayload, parseBound, episodeCharCounts, requestIdForScriptWrite,\n} from \"./session.js\";\nimport {\n tokenizeLine, DO_BOOL_FLAGS, DO_REPEAT_FLAGS, ParsedDoLine, parseDoLine, doErr, lineToOp, actionAddress, formatInspectAction, SKIPPABLE_EDIT_CODES, applySingleScriptOp, summarizeScriptOp, regexPattern, applySelectorEdits, actorIdsInAction, buildGrepMatcher, buildReport, synopsisPreview, episodeInSelector, nameMaps, formatScene, ActionTarget, HAS_FILTERS, resolveActionTargets, selectionHasAnyFilter, listAssetsByKind, splitSpeakerList, blankCreateReport, requireNameArg,\n} from \"./lib.js\";\n\nexport async function commandCreate(opts: Dict): Promise<[CommandOutput, number]> {\n const workspace = strOf(opts[\"workspace_path\"] || \"workspace\");\n const force = Boolean(opts[\"force\"]);\n const title = strOf(opts[\"title\"]).trim();\n const script = blankScriptV4(title);\n\n const localPath = scriptJsonPath(opts);\n if (exists(localPath) && !force) {\n throw new CliError(\"A script already exists at the target.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_EXISTS\",\n hint: \"Edit the existing script with the atomic verbs, or pass --force to overwrite with a blank scaffold.\",\n data: { expected: [\"a non-existent target, or --force to overwrite\"], actual: [localPath] },\n });\n }\n atomicWriteJson(localPath, script);\n const session = new ScriptEditSession({ workspace, scriptPath: localPath, script });\n const validation = validateSession(session);\n const passed = Boolean(validation[\"passed\"]);\n return [blankCreateReport(session, validation, null), passed ? EXIT_OK : EXIT_NEEDS_AGENT];\n}\n", "import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n CliError,\n EXIT_NEEDS_AGENT,\n EXIT_OK,\n EXIT_USAGE,\n sha256Text,\n type CommandOutput,\n} from \"../../common.js\";\nimport {\n migrateScriptToVersion,\n parseScriptMigrationStepArtifacts,\n} from \"../../domain/script/migrations/registry.js\";\nimport type { ScriptMigrationStepArtifact } from \"../../domain/script/migrations/types.js\";\nimport {\n isSupportedScriptVersion,\n scriptVersionOf,\n SUPPORTED_SCRIPT_VERSIONS,\n validateScriptDocument,\n type ScriptVersion,\n} from \"../../domain/script/dispatch.js\";\nimport { atomicWriteJson, withScriptFileLock } from \"../../infra/script-working-copy.js\";\nimport { isDict, type Dict } from \"../../domain/script/shared.js\";\n\ninterface MigrationManifest {\n readonly version: 1;\n readonly source_version: ScriptVersion;\n readonly target_version: ScriptVersion;\n readonly source_path: string;\n readonly source_sha256: string;\n readonly steps: readonly ScriptMigrationStepArtifact[];\n}\n\nfunction stringOption(opts: Dict, name: string): string {\n const value = opts[name];\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction numberOption(opts: Dict, name: string): number | null {\n const value = stringOption(opts, name);\n if (!/^\\d+$/.test(value)) return null;\n return Number(value);\n}\n\nfunction requireTargetVersion(opts: Dict): ScriptVersion {\n const value = numberOption(opts, \"to\");\n if (isSupportedScriptVersion(value)) return value;\n throw new CliError(\"A supported migration target version is required.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_TARGET_INVALID\",\n hint: \"Pass --to <version> with a supported Script version.\",\n data: {\n expected: SUPPORTED_SCRIPT_VERSIONS.map(String),\n actual: [stringOption(opts, \"to\") || \"<empty>\"],\n },\n });\n}\n\nfunction defaultManifestPath(outputPath: string): string {\n const extension = path.extname(outputPath);\n const stem = extension.length > 0\n ? outputPath.slice(0, -extension.length)\n : outputPath;\n return `${stem}.migration.json`;\n}\n\nfunction requireDistinctPaths(sourcePath: string, outputPath: string, manifestPath: string): void {\n const resolved = [sourcePath, outputPath, manifestPath].map((item) => path.resolve(item));\n if (resolved[0] === resolved[1]) {\n throw new CliError(\"The migration destination must differ from the source.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_SAME_PATH\",\n hint: \"Choose a separate --output path. The source file stays unchanged.\",\n data: { actual: [sourcePath] },\n });\n }\n if (resolved[0] === resolved[2] || resolved[1] === resolved[2]) {\n throw new CliError(\"The migration manifest needs its own file path.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_MANIFEST_PATH\",\n hint: \"Choose a --manifest path separate from the source and output files.\",\n data: { actual: [manifestPath] },\n });\n }\n}\n\nfunction assertWritableDestination(filePath: string, force: boolean): void {\n if (!force && fs.existsSync(filePath)) {\n throw new CliError(\"Migration destination already exists.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_OUTPUT_EXISTS\",\n hint: \"Choose a new path, or pass --force to replace the migration artifact.\",\n data: { actual: [filePath] },\n });\n }\n}\n\nfunction readSource(sourcePath: string): { raw: string; value: unknown } {\n let raw: string;\n try {\n raw = fs.readFileSync(sourcePath, \"utf8\");\n } catch (error) {\n throw new CliError(\"Cannot read the source script.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_SOURCE_READ_FAILED\",\n hint: \"Pass an existing JSON file with --script-path.\",\n data: { actual: [sourcePath, error instanceof Error ? error.message : String(error)] },\n });\n }\n try {\n return { raw, value: JSON.parse(raw) };\n } catch (error) {\n throw new CliError(\"The source script is not valid JSON.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_SOURCE_JSON_INVALID\",\n hint: \"Repair the JSON syntax, then rerun migrate.\",\n data: { actual: [error instanceof Error ? error.message : String(error)] },\n });\n }\n}\n\nfunction readPriorManifest(manifestPath: string, force: boolean): MigrationManifest | undefined {\n if (!force || !fs.existsSync(manifestPath)) return undefined;\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(manifestPath, \"utf8\"));\n } catch (error) {\n throw new CliError(\"Cannot reuse the existing migration manifest.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_MANIFEST_INVALID\",\n hint: \"Restore the migration manifest, or choose a new --manifest path.\",\n data: { actual: [manifestPath, error instanceof Error ? error.message : String(error)] },\n });\n }\n if (!isDict(value)\n || value[\"version\"] !== 1\n || !isSupportedScriptVersion(value[\"source_version\"])\n || !isSupportedScriptVersion(value[\"target_version\"])\n || typeof value[\"source_path\"] !== \"string\"\n || typeof value[\"source_sha256\"] !== \"string\") {\n throw new CliError(\"Cannot reuse the existing migration manifest.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_MANIFEST_INVALID\",\n hint: \"Restore the migration manifest, or choose a new --manifest path.\",\n data: { actual: [manifestPath] },\n });\n }\n return {\n version: 1,\n source_version: value[\"source_version\"],\n target_version: value[\"target_version\"],\n source_path: value[\"source_path\"],\n source_sha256: value[\"source_sha256\"],\n steps: parseScriptMigrationStepArtifacts(value[\"steps\"]),\n };\n}\n\nexport async function commandMigrate(opts: Dict): Promise<[CommandOutput, number]> {\n const sourceRawPath = stringOption(opts, \"script_path\");\n const outputRawPath = stringOption(opts, \"output\");\n if (!sourceRawPath || !outputRawPath) {\n throw new CliError(\"Migration paths are required.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_PATH_MISSING\",\n hint: \"Pass --script-path <source.json> and --output <target.json>.\",\n data: { expected: [\"--script-path <source.json>\", \"--output <target.json>\"] },\n });\n }\n\n const sourcePath = path.resolve(sourceRawPath);\n const outputPath = path.resolve(outputRawPath);\n const manifestPath = path.resolve(stringOption(opts, \"manifest\") || defaultManifestPath(outputPath));\n const targetVersion = requireTargetVersion(opts);\n const force = Boolean(opts[\"force\"]);\n requireDistinctPaths(sourcePath, outputPath, manifestPath);\n\n return withScriptFileLock(outputPath, async () => {\n assertWritableDestination(outputPath, force);\n assertWritableDestination(manifestPath, force);\n\n const sourceDocument = readSource(sourcePath);\n const sourceVersion = scriptVersionOf(sourceDocument.value);\n if (targetVersion <= sourceVersion) {\n throw new CliError(\"The migration target must be newer than the source script.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"MIGRATE_TARGET_NOT_NEWER\",\n data: { expected: [`>${sourceVersion}`], actual: [String(targetVersion)] },\n });\n }\n const sourceValidation = validateScriptDocument(sourceDocument.value);\n const priorManifest = readPriorManifest(manifestPath, force);\n const migrated = migrateScriptToVersion(\n sourceDocument.value,\n targetVersion,\n priorManifest?.steps,\n );\n const validation = validateScriptDocument(migrated.script);\n const manifest: MigrationManifest = {\n version: 1,\n source_version: migrated.sourceVersion,\n target_version: migrated.targetVersion,\n source_path: sourcePath,\n source_sha256: sha256Text(sourceDocument.raw),\n steps: migrated.steps,\n };\n\n atomicWriteJson(manifestPath, {\n ...manifest,\n steps: manifest.steps.map((step) => ({\n source_version: step.sourceVersion,\n target_version: step.targetVersion,\n identity_map: step.identityMap,\n })),\n });\n atomicWriteJson(outputPath, migrated.script);\n\n const data = {\n op: \"script.migrate\",\n changed: true,\n source_script_path: sourcePath,\n script_path: outputPath,\n manifest_path: manifestPath,\n source_version: migrated.sourceVersion,\n target_version: migrated.targetVersion,\n source_validation: {\n ok: sourceValidation.ok,\n errors: sourceValidation.errors.length,\n warnings: sourceValidation.warnings.length,\n },\n validation: {\n ok: validation.ok,\n errors: validation.errors.length,\n warnings: validation.warnings.length,\n issues: validation.errors.slice(0, 100),\n },\n };\n const text = validation.ok\n ? [`Script v${migrated.targetVersion}: ${outputPath}`, `Migration manifest: ${manifestPath}`, \"validation: ok\"].join(\"\\n\")\n : [\n `Script v${migrated.targetVersion}: ${outputPath}`,\n `Migration manifest: ${manifestPath}`,\n `validation: ${validation.errors.length} errors; repair before production use`,\n ].join(\"\\n\");\n return [{ text, data }, validation.ok ? EXIT_OK : EXIT_NEEDS_AGENT];\n });\n}\n", "import { CliError, EXIT_INPUT } from \"../../../common.js\";\nimport type { ScriptDocument } from \"../dispatch.js\";\nimport { isDict } from \"../shared.js\";\nimport { requireScriptV3 } from \"../v3/parse.js\";\nimport { newScriptV4FromV3WithIdentity, type V4IdentityMap } from \"../v4/from-v3.js\";\nimport type { ScriptMigrationStepArtifact, ScriptMigrationStepResult } from \"./types.js\";\n\nfunction v3ActionIdentityKeys(source: ReturnType<typeof requireScriptV3>): Record<string, string> {\n const action: Record<string, string> = {};\n for (const episode of source.episodes) {\n for (const scene of episode.scenes) {\n const sceneAddress = `${episode.episode_id}/${scene.scene_id}`;\n scene.actions.forEach((_item, index) => {\n const address = `${sceneAddress}#${index}`;\n action[address] = address;\n });\n }\n }\n return action;\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n return isDict(value) && Object.values(value).every((item) => typeof item === \"string\");\n}\n\nfunction isNestedStringRecord(value: unknown): value is Record<string, Record<string, string>> {\n return isDict(value) && Object.values(value).every(isStringRecord);\n}\n\nfunction isV4IdentityMap(value: unknown): value is V4IdentityMap {\n return isDict(value)\n && value[\"version\"] === 3\n && isStringRecord(value[\"actor\"])\n && isStringRecord(value[\"location\"])\n && isStringRecord(value[\"prop\"])\n && isNestedStringRecord(value[\"state\"])\n && isStringRecord(value[\"episode\"])\n && isStringRecord(value[\"scene\"])\n && isStringRecord(value[\"action\"]);\n}\n\nfunction priorIdentityMap(prior: ScriptMigrationStepArtifact | undefined): V4IdentityMap | undefined {\n if (prior === undefined) return undefined;\n if (isV4IdentityMap(prior.identityMap)) return prior.identityMap;\n throw new CliError(\"Migration manifest contains an invalid v3-to-v4 identity map.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"MIGRATE_MANIFEST_INVALID\",\n });\n}\n\nexport function migrate(\n source: ScriptDocument,\n prior: ScriptMigrationStepArtifact | undefined,\n): ScriptMigrationStepResult {\n const sourceV3 = requireScriptV3(source);\n const converted = newScriptV4FromV3WithIdentity(\n sourceV3,\n priorIdentityMap(prior),\n { action: v3ActionIdentityKeys(sourceV3) },\n );\n return {\n script: converted.script,\n artifact: {\n sourceVersion: 3,\n targetVersion: 4,\n identityMap: converted.identityMap,\n },\n };\n}\n", "import { CliError, EXIT_INPUT } from \"../../../common.js\";\nimport {\n isSupportedScriptVersion,\n requireScriptDocument,\n scriptVersionOf,\n type ScriptDocument,\n type ScriptVersion,\n} from \"../dispatch.js\";\nimport { isDict } from \"../shared.js\";\nimport { migrate as migrateV3ToV4 } from \"./v3-to-v4.js\";\nimport type {\n ScriptMigration,\n ScriptMigrationResult,\n ScriptMigrationStepArtifact,\n} from \"./types.js\";\n\ninterface RegisteredScriptMigration {\n readonly sourceVersion: ScriptVersion;\n readonly targetVersion: ScriptVersion;\n readonly migrate: ScriptMigration;\n}\n\nconst MIGRATIONS: readonly RegisteredScriptMigration[] = [\n {\n sourceVersion: 3,\n targetVersion: 4,\n migrate: migrateV3ToV4,\n },\n];\n\nfunction isMigrationArtifact(value: unknown): value is {\n readonly source_version: ScriptVersion;\n readonly target_version: ScriptVersion;\n readonly identity_map: unknown;\n} {\n return isDict(value)\n && isSupportedScriptVersion(value[\"source_version\"])\n && isSupportedScriptVersion(value[\"target_version\"])\n && value[\"source_version\"] < value[\"target_version\"]\n && \"identity_map\" in value;\n}\n\nexport function parseScriptMigrationStepArtifacts(\n value: unknown,\n): ScriptMigrationStepArtifact[] {\n if (!Array.isArray(value)) {\n throw new CliError(\"Migration manifest steps must be an array.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"MIGRATE_MANIFEST_INVALID\",\n });\n }\n return value.map((item) => {\n if (!isMigrationArtifact(item)) {\n throw new CliError(\"Migration manifest contains an invalid step artifact.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"MIGRATE_MANIFEST_INVALID\",\n });\n }\n return {\n sourceVersion: item.source_version,\n targetVersion: item.target_version,\n identityMap: item.identity_map,\n };\n });\n}\n\nfunction migrationFor(\n sourceVersion: ScriptVersion,\n targetVersion: ScriptVersion,\n): RegisteredScriptMigration | undefined {\n return MIGRATIONS.find((migration) => (\n migration.sourceVersion === sourceVersion\n && migration.targetVersion <= targetVersion\n ));\n}\n\nfunction priorArtifactFor(\n artifacts: readonly ScriptMigrationStepArtifact[],\n migration: RegisteredScriptMigration,\n): ScriptMigrationStepArtifact | undefined {\n return artifacts.find((artifact) => (\n artifact.sourceVersion === migration.sourceVersion\n && artifact.targetVersion === migration.targetVersion\n ));\n}\n\nexport function migrateScriptToVersion(\n value: unknown,\n targetVersion: ScriptVersion,\n priorArtifacts: readonly ScriptMigrationStepArtifact[] = [],\n): ScriptMigrationResult {\n const sourceVersion = scriptVersionOf(value);\n if (targetVersion < sourceVersion) {\n throw new CliError(\"A migration target must be newer than the source script.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"MIGRATE_TARGET_OLDER\",\n data: { expected: [String(sourceVersion)], actual: [String(targetVersion)] },\n });\n }\n\n let current: ScriptDocument = requireScriptDocument(value);\n let currentVersion = sourceVersion;\n const steps: ScriptMigrationStepArtifact[] = [];\n while (currentVersion < targetVersion) {\n const migration = migrationFor(currentVersion, targetVersion);\n if (migration === undefined) {\n throw new CliError(`No migration path exists from Script v${currentVersion} to Script v${targetVersion}.`, {\n exitCode: EXIT_INPUT,\n errorCode: \"MIGRATE_PATH_UNSUPPORTED\",\n data: { actual: [String(currentVersion), String(targetVersion)] },\n });\n }\n const migrated = migration.migrate(current, priorArtifactFor(priorArtifacts, migration));\n current = migrated.script;\n currentVersion = migration.targetVersion;\n steps.push(migrated.artifact);\n }\n\n return { sourceVersion, targetVersion, script: current, steps };\n}\n", "import * as path from \"node:path\";\n\nimport {\n CliError,\n DEFAULT_CONCURRENCY,\n EXIT_OK,\n EXIT_RUNTIME,\n EXIT_USAGE,\n directDir,\n sha256Text,\n type CommandOutput,\n} from \"../../common.js\";\nimport {\n fileCheckpointer,\n llm,\n loom,\n} from \"../../domain/loom/index.js\";\nimport type { LlmTaskExecutor } from \"../../llm/types.js\";\nimport {\n asList,\n type Dict,\n isDict,\n strOf,\n} from \"../../domain/script/shared.js\";\nimport { sceneRefs } from \"../../domain/script/scene-refs.js\";\nimport { PRODUCTION_LLM_COMPOSITION, type LlmComposition } from \"../../llm/composition.js\";\nimport {\n loadScriptForEdit,\n saveScriptSession,\n syncValidationResult,\n validateSession,\n} from \"./session.js\";\nimport { summarizeIssues } from \"../../domain/script/text-util.js\";\n\nexport interface SynopsisGenerateConfig {\n episodeInputMaxChars: number;\n episodeChunkTargetChars: number;\n arcEpisodeCount: number;\n finalMaxInputChars: number;\n}\n\nexport const DEFAULT_SYNOPSIS_GENERATE_CONFIG: SynopsisGenerateConfig = {\n episodeInputMaxChars: 6000,\n episodeChunkTargetChars: 4800,\n arcEpisodeCount: 10,\n finalMaxInputChars: 12000,\n};\n\nexport interface EpisodeSource {\n episodeIndex: number;\n episodeId: string;\n episodeNo: number;\n title: string;\n existingSynopsis: string;\n text: string;\n}\n\nexport interface EpisodeChunk {\n episodeIndex: number;\n episodeId: string;\n episodeNo: number;\n title: string;\n part: number;\n partCount: number;\n text: string;\n sourceHash: string;\n}\n\nexport interface ChunkBrief {\n episodeIndex: number;\n episodeId: string;\n episodeNo: number;\n title: string;\n part: number;\n partCount: number;\n synopsis: string;\n events: string[];\n characterChanges: CharacterChange[];\n hook: string;\n}\n\nexport interface EpisodeBrief {\n episodeIndex: number;\n episodeId: string;\n episodeNo: number;\n title: string;\n synopsis: string;\n oneLine: string;\n events: string[];\n}\n\nexport interface ArcParcel {\n index: number;\n startEpisodeNo: number;\n endEpisodeNo: number;\n text: string;\n}\n\nexport interface ArcBrief {\n index: number;\n startEpisodeNo: number;\n endEpisodeNo: number;\n synopsis: string;\n turns: string[];\n openQuestions: string[];\n}\n\nexport interface ScriptOverview {\n synopsis: string;\n theme: string;\n logline: string;\n style: string;\n mainCharacters: Array<{ name: string; role: string }>;\n}\n\ninterface CharacterChange {\n name: string;\n change: string;\n}\n\ninterface SynopsisGenerateResult {\n episodeBriefs: EpisodeBrief[];\n overview: ScriptOverview;\n overviewGenerated: boolean;\n report: {\n reused: number;\n ran: number;\n };\n}\n\nconst CHUNK_INSTRUCTION = \"\u4ECE\u5F53\u524D\u5267\u672C\u7247\u6BB5\u4E2D\u63D0\u53D6\u5267\u60C5\u6897\u6982\u548C\u5173\u952E\u4E8B\u4EF6\u3002\u53EA\u57FA\u4E8E\u5F53\u524D\u7247\u6BB5\uFF0C\u4E0D\u8981\u63A8\u6D4B\u540E\u7EED\u3002\";\n\nexport const CHUNK_FORMAT = [\n \"\u8F93\u51FA\u683C\u5F0F\uFF1A\u4E00\u4E2A\u7EAF\u6587\u672C\u7ED3\u6784\u5316\u6587\u6863\u3002\u4E0D\u8981\u5305\u88F9\u4EE3\u7801\u5757\uFF0C\u4E0D\u8981\u5728\u6587\u6863\u524D\u540E\u6DFB\u52A0\u89E3\u91CA\u3002\",\n \"\",\n \"## \u7247\u6BB5\u6897\u6982\",\n \"<\u5982\u679C\u5F53\u524D\u96C6\u53EA\u6709\u4E00\u4E2A\u7247\u6BB5\uFF0C\u5199 200-300 \u5B57\uFF1B\u5982\u679C\u5F53\u524D\u96C6\u88AB\u5207\u6210\u591A\u4E2A\u7247\u6BB5\uFF0C\u5199 80-150 \u5B57\u3002\u6309\u53D1\u751F\u987A\u5E8F\u6982\u62EC\uFF0C\u53EA\u5199\u5F53\u524D\u7247\u6BB5\u3002>\",\n \"\",\n \"## \u5173\u952E\u4E8B\u4EF6\",\n \"- <\u4E8B\u4EF61>\",\n \"- <\u4E8B\u4EF62>\",\n \"\",\n \"## \u4EBA\u7269\u53D8\u5316\",\n \"- <\u4EBA\u7269\u540D> | <\u53D8\u5316>\",\n \"\",\n \"## \u7ED3\u5C3E\u94A9\u5B50\",\n \"<\u6709\u5219\u5199\u4E00\u53E5\uFF1B\u6CA1\u6709\u5219\u7559\u7A7A>\",\n].join(\"\\n\");\n\nconst EPISODE_INSTRUCTION = \"\u628A\u540C\u4E00\u96C6\u7684\u591A\u4E2A\u7247\u6BB5\u6897\u6982\u5408\u5E76\u4E3A\u4E00\u96C6\u6897\u6982\u3002\u53EA\u4F7F\u7528\u8F93\u5165\u7247\u6BB5\uFF0C\u4E0D\u8981\u65B0\u589E\u5267\u60C5\u3002\";\n\nexport const EPISODE_FORMAT = [\n \"\u8F93\u51FA\u683C\u5F0F\uFF1A\u4E00\u4E2A\u7EAF\u6587\u672C\u7ED3\u6784\u5316\u6587\u6863\u3002\u4E0D\u8981\u5305\u88F9\u4EE3\u7801\u5757\uFF0C\u4E0D\u8981\u5728\u6587\u6863\u524D\u540E\u6DFB\u52A0\u89E3\u91CA\u3002\",\n \"\",\n \"## \u5206\u96C6\u6897\u6982\",\n \"<200-300 \u5B57\uFF0C\u6309\u5267\u60C5\u53D1\u751F\u987A\u5E8F\u5199\u6210\u8FDE\u8D2F\u6BB5\u843D\u3002>\",\n \"\",\n \"## \u5355\u53E5\u6897\u6982\",\n \"<30-50 \u5B57\uFF0C\u6982\u62EC\u672C\u96C6\u4E3B\u7EBF\u3002>\",\n \"\",\n \"## \u5173\u952E\u4E8B\u4EF6\",\n \"- <\u4E8B\u4EF61>\",\n \"- <\u4E8B\u4EF62>\",\n].join(\"\\n\");\n\nconst ARC_INSTRUCTION = \"\u628A\u4E00\u7EC4\u8FDE\u7EED\u5206\u96C6\u6897\u6982\u538B\u7F29\u4E3A\u9636\u6BB5\u6897\u6982\u3002\u53EA\u4F7F\u7528\u8F93\u5165\u5206\u96C6\uFF0C\u4E0D\u8981\u65B0\u589E\u5267\u60C5\u3002\";\n\nexport const ARC_FORMAT = [\n \"\u8F93\u51FA\u683C\u5F0F\uFF1A\u4E00\u4E2A\u7EAF\u6587\u672C\u7ED3\u6784\u5316\u6587\u6863\u3002\u4E0D\u8981\u5305\u88F9\u4EE3\u7801\u5757\uFF0C\u4E0D\u8981\u5728\u6587\u6863\u524D\u540E\u6DFB\u52A0\u89E3\u91CA\u3002\",\n \"\",\n \"## \u9636\u6BB5\u6897\u6982\",\n \"<400-600 \u5B57\uFF0C\u6982\u62EC\u8FD9\u4E00\u9636\u6BB5\u7684\u4E3B\u7EBF\u63A8\u8FDB\u3002>\",\n \"\",\n \"## \u5173\u952E\u8F6C\u6298\",\n \"- <\u8F6C\u62981>\",\n \"- <\u8F6C\u62982>\",\n \"\",\n \"## \u672A\u89E3\u51B3\u60AC\u5FF5\",\n \"- <\u60AC\u5FF51>\",\n].join(\"\\n\");\n\nconst FINAL_INSTRUCTION = \"\u6839\u636E\u5206\u96C6\u7D22\u5F15\u548C\u9636\u6BB5\u6897\u6982\u751F\u6210\u5168\u5267\u603B\u89C8\u3002\u53EA\u4F7F\u7528\u8F93\u5165\u5185\u5BB9\uFF0C\u4E0D\u8981\u65B0\u589E\u5267\u60C5\u3001\u4EBA\u7269\u6216\u5173\u7CFB\u3002\";\n\nexport const FINAL_FORMAT = [\n \"\u8F93\u51FA\u683C\u5F0F\uFF1A\u4E00\u4E2A\u7EAF\u6587\u672C\u7ED3\u6784\u5316\u6587\u6863\u3002\u4E0D\u8981\u5305\u88F9\u4EE3\u7801\u5757\uFF0C\u4E0D\u8981\u5728\u6587\u6863\u524D\u540E\u6DFB\u52A0\u89E3\u91CA\u3002\",\n \"\",\n \"## \u5168\u6587\u6897\u6982\",\n \"<800-1200 \u5B57\uFF0C\u8986\u76D6\u5168\u5267\u4E3B\u7EBF\u3001\u5173\u952E\u5173\u7CFB\u3001\u4E3B\u8981\u51B2\u7A81\u548C\u7ED3\u5C40\u8D70\u5411\u3002>\",\n \"\",\n \"## \u4E3B\u9898\",\n \"<\u4E00\u53E5\u8BDD\u6216\u4E00\u4E2A\u77ED\u8BED>\",\n \"\",\n \"## \u4E00\u53E5\u8BDD\",\n \"<\u4E00\u53E5\u5B8C\u6574 logline>\",\n \"\",\n \"## \u98CE\u683C\",\n \"<\u7C7B\u578B / \u6C14\u8D28 / \u53D9\u4E8B\u98CE\u683C>\",\n \"\",\n \"## \u4E3B\u8981\u4EBA\u7269\",\n \"- <\u540D\u5B57> | <\u89D2\u8272\u5B9A\u4F4D>\",\n].join(\"\\n\");\n\nexport function renderEpisodeSource(script: Dict, episode: Dict, index: number): EpisodeSource {\n const episodeId = strOf(episode[\"episode_id\"]).trim() || `ep_${String(index + 1).padStart(3, \"0\")}`;\n const episodeNo = episodeNumber(episodeId, index);\n const title = strOf(episode[\"title\"]).trim();\n const lines: string[] = [];\n const scriptTitle = strOf(script[\"title\"]).trim();\n if (scriptTitle) lines.push(`\u5267\u540D\uFF1A${scriptTitle}`);\n lines.push(`\u96C6\u6570\uFF1A\u7B2C${episodeNo}\u96C6`);\n if (title) lines.push(`\u6807\u9898\uFF1A${title}`);\n lines.push(\"\");\n\n for (const scene of asList<Dict>(episode[\"scenes\"])) {\n lines.push(renderSceneHeader(script, scene));\n for (const action of asList<Dict>(scene[\"actions\"])) {\n const rendered = renderAction(script, action);\n if (rendered) lines.push(rendered);\n }\n lines.push(\"\");\n }\n\n return {\n episodeIndex: index,\n episodeId,\n episodeNo,\n title,\n existingSynopsis: strOf(episode[\"synopsis\"]).trim(),\n text: lines.join(\"\\n\").trim(),\n };\n}\n\nexport function splitEpisodeSource(source: EpisodeSource, config: SynopsisGenerateConfig = DEFAULT_SYNOPSIS_GENERATE_CONFIG): EpisodeChunk[] {\n const rawLines = source.text.split(/\\r?\\n/);\n const lines = rawLines.flatMap((line) => splitLongLine(line, config.episodeChunkTargetChars));\n if (source.text.length <= config.episodeInputMaxChars && lines.length === rawLines.length) {\n return [{\n episodeIndex: source.episodeIndex,\n episodeId: source.episodeId,\n episodeNo: source.episodeNo,\n title: source.title,\n part: 1,\n partCount: 1,\n text: source.text,\n sourceHash: sha256Text(source.text),\n }];\n }\n\n const chunks: string[] = [];\n let current: string[] = [];\n let currentChars = 0;\n for (const line of lines) {\n const lineChars = line.length + (current.length > 0 ? 1 : 0);\n if (current.length > 0 && currentChars + lineChars > config.episodeChunkTargetChars) {\n chunks.push(current.join(\"\\n\").trim());\n current = [];\n currentChars = 0;\n }\n const nextLineChars = line.length + (current.length > 0 ? 1 : 0);\n current.push(line);\n currentChars += nextLineChars;\n }\n if (current.length > 0) chunks.push(current.join(\"\\n\").trim());\n\n return chunks.map((text, idx) => ({\n episodeIndex: source.episodeIndex,\n episodeId: source.episodeId,\n episodeNo: source.episodeNo,\n title: source.title,\n part: idx + 1,\n partCount: chunks.length,\n text,\n sourceHash: sha256Text(text),\n }));\n}\n\nexport function parseChunkBrief(text: string, chunk: EpisodeChunk): ChunkBrief {\n const sections = sectionMap(text);\n return {\n episodeIndex: chunk.episodeIndex,\n episodeId: chunk.episodeId,\n episodeNo: chunk.episodeNo,\n title: chunk.title,\n part: chunk.part,\n partCount: chunk.partCount,\n synopsis: requiredSection(sections, \"\u7247\u6BB5\u6897\u6982\"),\n events: parseBullets(sections.get(\"\u5173\u952E\u4E8B\u4EF6\") ?? \"\"),\n characterChanges: parseCharacterChanges(sections.get(\"\u4EBA\u7269\u53D8\u5316\") ?? \"\"),\n hook: (sections.get(\"\u7ED3\u5C3E\u94A9\u5B50\") ?? \"\").trim(),\n };\n}\n\nexport function reduceChunkBriefs(items: ChunkBrief[], ctx: { scope: EpisodeSource | null }): EpisodeBrief {\n const source = requireScope(ctx.scope, \"episode\");\n const ordered = [...items].sort((a, b) => a.part - b.part);\n return {\n episodeIndex: source.episodeIndex,\n episodeId: source.episodeId,\n episodeNo: source.episodeNo,\n title: source.title,\n synopsis: ordered.map((item) => item.synopsis).filter((s) => s.trim()).join(\"\\n\"),\n oneLine: firstNonEmpty(ordered.map((item) => item.synopsis)),\n events: uniqueStrings(ordered.flatMap((item) => item.events)),\n };\n}\n\nexport function parseEpisodeBrief(text: string, source: EpisodeBrief): EpisodeBrief {\n const sections = sectionMap(text);\n return {\n episodeIndex: source.episodeIndex,\n episodeId: source.episodeId,\n episodeNo: source.episodeNo,\n title: source.title,\n synopsis: requiredSection(sections, \"\u5206\u96C6\u6897\u6982\"),\n oneLine: requiredSection(sections, \"\u5355\u53E5\u6897\u6982\"),\n events: parseBullets(sections.get(\"\u5173\u952E\u4E8B\u4EF6\") ?? \"\"),\n };\n}\n\nexport function buildArcParcels(episodes: EpisodeBrief[], arcEpisodeCount: number): ArcParcel[] {\n const parcels: ArcParcel[] = [];\n for (let i = 0; i < episodes.length; i += arcEpisodeCount) {\n const group = episodes.slice(i, i + arcEpisodeCount);\n const first = group[0]!;\n const last = group[group.length - 1]!;\n parcels.push({\n index: parcels.length + 1,\n startEpisodeNo: first.episodeNo,\n endEpisodeNo: last.episodeNo,\n text: renderEpisodeBriefs(group),\n });\n }\n return parcels;\n}\n\nexport function buildArcParcelsFromArcs(arcs: ArcBrief[], fanout: number): ArcParcel[] {\n const parcels: ArcParcel[] = [];\n for (let i = 0; i < arcs.length; i += fanout) {\n const group = arcs.slice(i, i + fanout);\n const first = group[0]!;\n const last = group[group.length - 1]!;\n parcels.push({\n index: parcels.length + 1,\n startEpisodeNo: first.startEpisodeNo,\n endEpisodeNo: last.endEpisodeNo,\n text: renderArcBriefs(group),\n });\n }\n return parcels;\n}\n\nexport function parseArcBrief(text: string, parcel: ArcParcel): ArcBrief {\n const sections = sectionMap(text);\n return {\n index: parcel.index,\n startEpisodeNo: parcel.startEpisodeNo,\n endEpisodeNo: parcel.endEpisodeNo,\n synopsis: requiredSection(sections, \"\u9636\u6BB5\u6897\u6982\"),\n turns: parseBullets(sections.get(\"\u5173\u952E\u8F6C\u6298\") ?? \"\"),\n openQuestions: parseBullets(sections.get(\"\u672A\u89E3\u51B3\u60AC\u5FF5\") ?? \"\"),\n };\n}\n\nexport function reduceArcBriefs(items: ArcBrief[]): ArcBrief {\n const ordered = [...items].sort((a, b) => a.startEpisodeNo - b.startEpisodeNo);\n const first = ordered[0];\n const last = ordered[ordered.length - 1];\n if (!first || !last) throw new Error(\"arc reduce requires at least one item\");\n return {\n index: first.index,\n startEpisodeNo: first.startEpisodeNo,\n endEpisodeNo: last.endEpisodeNo,\n synopsis: ordered.map((item) => `\u7B2C${item.startEpisodeNo}-${item.endEpisodeNo}\u96C6\uFF1A${item.synopsis}`).join(\"\\n\"),\n turns: uniqueStrings(ordered.flatMap((item) => item.turns)),\n openQuestions: uniqueStrings(ordered.flatMap((item) => item.openQuestions)),\n };\n}\n\nexport function renderFinalInput(episodes: EpisodeBrief[], arcs: ArcBrief[]): string {\n const lines: string[] = [\"\u5206\u96C6\u7D22\u5F15\uFF1A\"];\n for (const ep of [...episodes].sort((a, b) => a.episodeNo - b.episodeNo)) {\n lines.push(`\u7B2C${ep.episodeNo}\u96C6\uFF1A${ep.oneLine || ep.synopsis}`);\n }\n lines.push(\"\", \"\u9636\u6BB5\u6897\u6982\uFF1A\");\n for (const arc of [...arcs].sort((a, b) => a.startEpisodeNo - b.startEpisodeNo)) {\n lines.push(`\u7B2C${arc.startEpisodeNo}-${arc.endEpisodeNo}\u96C6\uFF1A${arc.synopsis}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function parseScriptOverview(text: string): ScriptOverview {\n const sections = sectionMap(text);\n return {\n synopsis: requiredSection(sections, \"\u5168\u6587\u6897\u6982\"),\n theme: requiredSection(sections, \"\u4E3B\u9898\"),\n logline: requiredSection(sections, \"\u4E00\u53E5\u8BDD\"),\n style: requiredSection(sections, \"\u98CE\u683C\"),\n mainCharacters: parseMainCharacters(requiredSection(sections, \"\u4E3B\u8981\u4EBA\u7269\")),\n };\n}\n\nexport async function generateSynopsisFromScript(opts: {\n script: Dict;\n executor: LlmTaskExecutor;\n checkpointDir: string;\n checkpointSalt?: unknown;\n concurrency: number;\n overwrite: boolean;\n config?: SynopsisGenerateConfig;\n}): Promise<SynopsisGenerateResult> {\n const config = opts.config ?? DEFAULT_SYNOPSIS_GENERATE_CONFIG;\n const episodes = asList<Dict>(opts.script[\"episodes\"]);\n if (episodes.length === 0) {\n throw new CliError(\"No episodes found in script.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SCRIPT_EPISODES_MISSING\",\n hint: \"Create or parse episodes before generating synopsis.\",\n data: { expected: [\"script.episodes[] with at least one episode\"], actual: [\"episodes: 0\"] },\n });\n }\n\n const allSources = episodes.map((episode, index) => renderEpisodeSource(opts.script, episode, index));\n const sources = opts.overwrite ? allSources : allSources.filter((source) => !source.existingSynopsis);\n const episodeRun = sources.length === 0\n ? []\n : await loom(opts.script)\n .split({\n scope: \"episode\",\n partition: () => sources,\n chunk: (source) => splitEpisodeSource(source, config),\n })\n .extract(llm<EpisodeChunk, ChunkBrief>({\n taskId: \"synopsis.chunk\",\n instruction: CHUNK_INSTRUCTION,\n format: CHUNK_FORMAT,\n input: ({ parcel }) => renderChunkInput(parcel),\n parse: ({ text, parcel }) => parseChunkBrief(text, parcel),\n }))\n .reduce(\"episode\", reduceChunkBriefs)\n .extract(llm<EpisodeBrief, EpisodeBrief>({\n taskId: \"synopsis.episode\",\n instruction: EPISODE_INSTRUCTION,\n format: EPISODE_FORMAT,\n input: ({ parcel }) => renderEpisodeReduceInput(parcel),\n parse: ({ text, parcel }) => parseEpisodeBrief(text, parcel),\n }))\n .reduce(\"root\", (items: EpisodeBrief[]) => [...items].sort((a, b) => a.episodeNo - b.episodeNo))\n .run({\n concurrency: opts.concurrency,\n checkpoint: fileCheckpointer(path.join(opts.checkpointDir, \"episode\")),\n checkpointSalt: opts.checkpointSalt,\n executor: opts.executor,\n });\n const generatedEpisodeBriefs = Array.isArray(episodeRun) ? episodeRun : episodeRun.value;\n\n const byIndex = new Map(generatedEpisodeBriefs.map((brief) => [brief.episodeIndex, brief]));\n const episodeBriefs = allSources.map((source) => byIndex.get(source.episodeIndex) ?? {\n episodeIndex: source.episodeIndex,\n episodeId: source.episodeId,\n episodeNo: source.episodeNo,\n title: source.title,\n synopsis: source.existingSynopsis,\n oneLine: synopsisPreviewLine(source.existingSynopsis),\n events: [],\n });\n\n const missing = episodeBriefs.filter((brief) => !brief.synopsis.trim()).map((brief) => brief.episodeId);\n if (missing.length > 0) {\n throw new CliError(\"Some episode synopses are still missing.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"EPISODE_SYNOPSIS_MISSING\",\n hint: \"Use --overwrite to regenerate, or manually set missing episode synopses.\",\n data: { expected: [\"every episode has synopsis\"], actual: missing },\n });\n }\n\n const overviewNeeded = opts.overwrite || scriptOverviewMissing(opts.script);\n const arcRun = overviewNeeded\n ? await generateArcBriefs({\n episodes: episodeBriefs,\n executor: opts.executor,\n checkpointDir: path.join(opts.checkpointDir, \"arc\"),\n checkpointSalt: opts.checkpointSalt,\n concurrency: opts.concurrency,\n config,\n })\n : { value: [], report: { reused: 0, ran: 0 } };\n const overviewRun = overviewNeeded\n ? await generateScriptOverview({\n episodes: episodeBriefs,\n arcs: arcRun.value,\n executor: opts.executor,\n checkpointDir: path.join(opts.checkpointDir, \"final\"),\n checkpointSalt: opts.checkpointSalt,\n config,\n })\n : { value: existingScriptOverview(opts.script), report: { reused: 0, ran: 0 } };\n\n return {\n episodeBriefs,\n overview: overviewRun.value,\n overviewGenerated: overviewNeeded,\n report: {\n reused: (Array.isArray(episodeRun) ? 0 : episodeRun.report.reused) + arcRun.report.reused + overviewRun.report.reused,\n ran: (Array.isArray(episodeRun) ? 0 : episodeRun.report.ran) + arcRun.report.ran + overviewRun.report.ran,\n },\n };\n}\n\nexport async function commandSynopsisGenerate(opts: Dict, composition: LlmComposition = PRODUCTION_LLM_COMPOSITION): Promise<[CommandOutput, number]> {\n const concurrency = parsePositiveInt(opts[\"concurrency\"], DEFAULT_CONCURRENCY, \"--concurrency\");\n const overwrite = Boolean(opts[\"overwrite\"]);\n const apply = Boolean(opts[\"apply\"]);\n const dryRun = Boolean(opts[\"dry_run\"]);\n if (apply && dryRun) {\n throw new CliError(\"--apply and --dry-run are mutually exclusive.\", {\n exitCode: EXIT_USAGE,\n errorCode: \"SYNOPSIS_GENERATE_FLAG_CONFLICT\",\n hint: \"Pick one mode and retry.\",\n data: { expected: [\"at most one of --apply / --dry-run\"], actual: [\"--apply\", \"--dry-run\"] },\n });\n }\n const workspace = strOf(opts[\"workspace_path\"] || \"workspace\");\n const session = await loadScriptForEdit(opts);\n const executor = composition.createExecutor(strOf(opts[\"llm_config\"]).trim() || undefined);\n\n const checkpoint = strOf(opts[\"checkpoint\"]).trim() || path.join(directDir(workspace), \"loom\", \"synopsis-generate\");\n const result = await generateSynopsisFromScript({\n script: session.script,\n executor,\n checkpointDir: checkpoint,\n concurrency,\n overwrite,\n });\n\n const changedEpisodeIds = new Set<string>();\n const scriptEpisodes = asList<Dict>(session.script[\"episodes\"]);\n for (const brief of result.episodeBriefs) {\n const episode = scriptEpisodes[brief.episodeIndex];\n if (episode && (overwrite || !strOf(episode[\"synopsis\"]).trim())) {\n if (strOf(episode[\"synopsis\"]) !== brief.synopsis) {\n episode[\"synopsis\"] = brief.synopsis;\n changedEpisodeIds.add(brief.episodeId);\n }\n }\n }\n let overviewChanged = false;\n overviewChanged = setTextField(session.script, \"synopsis\", result.overview.synopsis, overwrite) || overviewChanged;\n overviewChanged = setTextField(session.script, \"theme\", result.overview.theme, overwrite) || overviewChanged;\n overviewChanged = setTextField(session.script, \"logline\", result.overview.logline, overwrite) || overviewChanged;\n overviewChanged = setTextField(session.script, \"style\", result.overview.style, overwrite) || overviewChanged;\n if (overwrite || asList(session.script[\"main_characters\"]).length === 0) {\n const nextMainCharacters = result.overview.mainCharacters.map((item) => ({ name: item.name, role: item.role }));\n if (JSON.stringify(session.script[\"main_characters\"] ?? []) !== JSON.stringify(nextMainCharacters)) {\n session.script[\"main_characters\"] = nextMainCharacters;\n overviewChanged = true;\n }\n }\n const hasChanges = changedEpisodeIds.size > 0 || overviewChanged;\n\n const validation = validateSession(session);\n const passed = Boolean(validation[\"passed\"]);\n const resultLines = [\n `${result.episodeBriefs.length} episodes; ${changedEpisodeIds.size} synopses ${apply ? \"written\" : \"would change\"}; overview ${result.overviewGenerated ? \"generated\" : \"reused\"}; validation ${passed ? (apply ? \"passed\" : \"would pass\") : apply ? \"needs repair\" : \"would need repair\"}${apply ? \"\" : \"; dry-run, no write\"}`,\n `loom: ran=${result.report.ran}, reused=${result.report.reused}`,\n `llm config: ${executor.configSource}; routes: ${executor.usage().length}`,\n ];\n\n let revision: number | null | undefined;\n let idempotent: boolean | undefined;\n if (apply && hasChanges) {\n [revision, idempotent] = await saveScriptSession(session, opts, \"synopsis.generate\");\n await syncValidationResult(session, validation, revision);\n if (session.remote) resultLines.push(`revision ${revision}; idempotent ${String(idempotent).toLowerCase()}`);\n }\n\n const issues = summarizeIssues(asList<Dict>(validation[\"issues\"]));\n if (!apply) resultLines.push(\"Run again with --apply to write the generated synopsis fields.\");\n const report: CommandOutput = {\n text: [...resultLines, ...issues].join(\"\\n\"),\n data: {\n op: apply ? \"synopsis.generate\" : \"synopsis.generate.dry-run\",\n changed: apply && hasChanges,\n revision,\n idempotent,\n validation,\n issues,\n script_path: session.artifactLabel,\n episode_synopses: result.episodeBriefs.map((brief) => ({\n episode_id: brief.episodeId,\n title: brief.title,\n synopsis: brief.synopsis,\n one_line: brief.oneLine,\n })),\n config_source: executor.configSource,\n llm_routes: executor.usage(),\n },\n };\n return [report, EXIT_OK];\n}\n\nfunction splitLongLine(line: string, maxChars: number): string[] {\n if (line.length <= maxChars) return [line];\n const parts: string[] = [];\n for (let i = 0; i < line.length; i += maxChars) {\n parts.push(line.slice(i, i + maxChars));\n }\n return parts;\n}\n\nasync function generateArcBriefs(opts: {\n episodes: EpisodeBrief[];\n executor: LlmTaskExecutor;\n checkpointDir: string;\n checkpointSalt?: unknown;\n concurrency: number;\n config: SynopsisGenerateConfig;\n}): Promise<{ value: ArcBrief[]; report: { reused: number; ran: number } }> {\n let current = buildArcParcels(opts.episodes, opts.config.arcEpisodeCount);\n let level = 1;\n const report = { reused: 0, ran: 0 };\n while (true) {\n const run = await loom(current)\n .split({\n scope: \"arc\",\n partition: (parcels) => parcels,\n chunk: (parcel) => [parcel],\n })\n .extract(llm<ArcParcel, ArcBrief>({\n taskId: \"synopsis.arc\",\n instruction: ARC_INSTRUCTION,\n format: ARC_FORMAT,\n input: ({ parcel }) => renderArcInput(parcel),\n parse: ({ text, parcel }) => parseArcBrief(text, parcel),\n }))\n .reduce(\"arc\", (items: ArcBrief[]) => requireSingle(items, \"arc\"))\n .reduce(\"root\", (items: ArcBrief[]) => [...items].sort((a, b) => a.startEpisodeNo - b.startEpisodeNo))\n .run({\n concurrency: opts.concurrency,\n checkpoint: fileCheckpointer(path.join(opts.checkpointDir, `level-${level}`)),\n checkpointSalt: opts.checkpointSalt,\n executor: opts.executor,\n });\n report.reused += run.report.reused;\n report.ran += run.report.ran;\n const briefs = run.value;\n\n const finalInput = renderFinalInput(opts.episodes, briefs);\n if (finalInput.length <= opts.config.finalMaxInputChars || briefs.length <= 1) return { value: briefs, report };\n current = buildArcParcelsFromArcs(briefs, opts.config.arcEpisodeCount);\n level += 1;\n }\n}\n\nasync function generateScriptOverview(opts: {\n episodes: EpisodeBrief[];\n arcs: ArcBrief[];\n executor: LlmTaskExecutor;\n checkpointDir: string;\n checkpointSalt?: unknown;\n config: SynopsisGenerateConfig;\n}): Promise<{ value: ScriptOverview; report: { reused: number; ran: number } }> {\n let arcs = opts.arcs;\n while (renderFinalInput(opts.episodes, arcs).length > opts.config.finalMaxInputChars && arcs.length > 1) {\n arcs = [reduceArcBriefs(arcs)];\n }\n const run = await loom({ episodes: opts.episodes, arcs })\n .extract(llm<{ episodes: EpisodeBrief[]; arcs: ArcBrief[] }, ScriptOverview>({\n taskId: \"synopsis.script-overview\",\n instruction: FINAL_INSTRUCTION,\n format: FINAL_FORMAT,\n input: ({ parcel }) => renderFinalInput(parcel.episodes, parcel.arcs),\n parse: ({ text }) => parseScriptOverview(text),\n }))\n .run({\n concurrency: 1,\n checkpoint: fileCheckpointer(opts.checkpointDir),\n checkpointSalt: opts.checkpointSalt,\n executor: opts.executor,\n });\n return { value: run.value, report: run.report };\n}\n\nfunction renderSceneHeader(script: Dict, scene: Dict): string {\n const env = isDict(scene[\"environment\"]) ? scene[\"environment\"] : {};\n const space = strOf(env[\"space\"]).trim();\n const time = strOf(env[\"time\"]).trim();\n const refs = sceneRefs(scene);\n const locations = asList<Dict>(refs[\"locations\"]).map((ref) => assetName(script, \"locations\", \"location_id\", \"location_name\", strOf(ref[\"location_id\"]))).filter((s) => s);\n const actors = asList<Dict>(refs[\"actors\"]).map((ref) => assetName(script, \"actors\", \"actor_id\", \"actor_name\", strOf(ref[\"actor_id\"]))).filter((s) => s);\n const location = locations.join(\"\u3001\") || \"-\";\n const envText = [space, time].filter((s) => s).join(\" \");\n return `[\u573A\u666F] ${envText || \"-\"}\uFF5C${location}\uFF5C\u51FA\u573A\uFF1A${actors.join(\"\u3001\") || \"-\"}`;\n}\n\nfunction renderAction(script: Dict, action: Dict): string {\n const type = strOf(action[\"type\"]).trim();\n if (type === \"dialogue\") {\n const speaker = actionSpeakerName(script, action);\n const content = strOf(action[\"content\"]).trim();\n return content ? `[\u5BF9\u767D] ${speaker ? `${speaker}\uFF1A` : \"\"}${content}` : \"\";\n }\n if (type === \"inner_thought\") {\n const speaker = actionSpeakerName(script, action);\n const content = strOf(action[\"content\"]).trim();\n return content ? `[\u5FC3\u58F0] ${speaker ? `${speaker}\uFF1A` : \"\"}${content}` : \"\";\n }\n const content = strOf(action[\"content\"]).trim();\n return content ? `[\u52A8\u4F5C] ${content}` : \"\";\n}\n\nfunction actionSpeakerName(script: Dict, action: Dict): string {\n // v3: a single inline speaker \u2014 an actor ref, or a non-actor kind with a label.\n const s = action[\"speaker\"];\n if (!isDict(s)) return \"\";\n const actorId = strOf(s[\"actor_id\"]).trim();\n if (actorId) return assetName(script, \"actors\", \"actor_id\", \"actor_name\", actorId) || actorId;\n const kind = strOf(s[\"kind\"]).trim();\n if (kind) return strOf(s[\"label\"]).trim() || kind;\n return \"\";\n}\n\nfunction assetName(script: Dict, collection: string, idKey: string, nameKey: string, id: string): string {\n const item = asList<Dict>(script[collection]).find((entry) => strOf(entry[idKey]) === id);\n return item ? strOf(item[nameKey]).trim() : \"\";\n}\n\nfunction episodeNumber(episodeId: string, index: number): number {\n const m = /^ep_(\\d+)$/.exec(episodeId);\n return m ? Number(m[1]) : index + 1;\n}\n\nfunction sectionMap(text: string): Map<string, string> {\n const sections = new Map<string, string>();\n let current: string | null = null;\n let lines: string[] = [];\n const flush = () => {\n if (current) sections.set(current, lines.join(\"\\n\").trim());\n lines = [];\n };\n for (const rawLine of text.split(/\\r?\\n/)) {\n const heading = parseSectionHeading(rawLine);\n if (heading) {\n if (current === heading.name && heading.inline) {\n lines.push(rawLine);\n continue;\n }\n flush();\n current = heading.name;\n if (heading.inline) lines.push(heading.inline);\n continue;\n }\n if (current) lines.push(rawLine);\n }\n flush();\n return sections;\n}\n\nconst SYNOPSIS_SECTION_NAMES = new Set([\n \"\u7247\u6BB5\u6897\u6982\",\n \"\u5173\u952E\u4E8B\u4EF6\",\n \"\u4EBA\u7269\u53D8\u5316\",\n \"\u7ED3\u5C3E\u94A9\u5B50\",\n \"\u5206\u96C6\u6897\u6982\",\n \"\u5355\u53E5\u6897\u6982\",\n \"\u9636\u6BB5\u6897\u6982\",\n \"\u5173\u952E\u8F6C\u6298\",\n \"\u672A\u89E3\u51B3\u60AC\u5FF5\",\n \"\u5168\u6587\u6897\u6982\",\n \"\u4E3B\u9898\",\n \"\u4E00\u53E5\u8BDD\",\n \"\u98CE\u683C\",\n \"\u4E3B\u8981\u4EBA\u7269\",\n]);\n\nfunction parseSectionHeading(rawLine: string): { name: string; inline: string } | null {\n const line = rawLine.trim();\n const md = /^#{1,6}\\s+(.+?)\\s*$/.exec(line);\n if (md) {\n const name = md[1]!.trim();\n return SYNOPSIS_SECTION_NAMES.has(name) ? { name, inline: \"\" } : null;\n }\n const colon = line.search(/[:\uFF1A]/);\n const name = (colon >= 0 ? line.slice(0, colon) : line).trim();\n if (!SYNOPSIS_SECTION_NAMES.has(name)) return null;\n return { name, inline: colon >= 0 ? line.slice(colon + 1).trim() : \"\" };\n}\n\nfunction requiredSection(sections: Map<string, string>, name: string): string {\n const value = (sections.get(name) ?? \"\").trim();\n if (!value) throw new Error(`synopsis output missing section: ${name}`);\n return value;\n}\n\nfunction parseBullets(text: string): string[] {\n return text.split(/\\r?\\n/)\n .map((line) => line.trim())\n .map((line) => line.replace(/^[-*]\\s*/, \"\").trim())\n .filter((line) => line.length > 0);\n}\n\nfunction parseCharacterChanges(text: string): CharacterChange[] {\n return parseBullets(text).map((line) => {\n const [name, ...rest] = line.split(\"|\");\n return { name: strOf(name).trim(), change: rest.join(\"|\").trim() };\n }).filter((item) => item.name && item.change);\n}\n\nfunction parseMainCharacters(text: string): Array<{ name: string; role: string }> {\n return parseBullets(text).map((line) => {\n const [name, ...rest] = line.split(\"|\");\n return { name: strOf(name).trim(), role: rest.join(\"|\").trim() };\n }).filter((item) => item.name && item.role);\n}\n\nfunction renderChunkInput(chunk: EpisodeChunk): string {\n return [\n `\u5F53\u524D\u5206\u96C6\uFF1A\u7B2C${chunk.episodeNo}\u96C6 ${chunk.title || \"\"}`.trim(),\n `\u5F53\u524D\u7247\u6BB5\uFF1A${chunk.part}/${chunk.partCount}`,\n \"\",\n \"\u8FD9\u662F\u5F53\u524D\u4EFB\u52A1\u7684\u539F\u6587\uFF1A\",\n chunk.text,\n ].join(\"\\n\");\n}\n\nfunction renderEpisodeReduceInput(episode: EpisodeBrief): string {\n return [\n `\u5F53\u524D\u5206\u96C6\uFF1A\u7B2C${episode.episodeNo}\u96C6 ${episode.title || \"\"}`.trim(),\n \"\",\n \"\u7247\u6BB5\u6897\u6982\uFF1A\",\n episode.synopsis,\n \"\",\n \"\u7247\u6BB5\u5173\u952E\u4E8B\u4EF6\uFF1A\",\n ...episode.events.map((event) => `- ${event}`),\n ].join(\"\\n\");\n}\n\nfunction renderEpisodeBriefs(episodes: EpisodeBrief[]): string {\n const lines: string[] = [];\n for (const ep of episodes) {\n lines.push(`\u7B2C${ep.episodeNo}\u96C6 ${ep.title || \"\"}`.trim());\n lines.push(`\u5355\u53E5\uFF1A${ep.oneLine}`);\n lines.push(`\u6897\u6982\uFF1A${ep.synopsis}`);\n if (ep.events.length > 0) {\n lines.push(\"\u5173\u952E\u4E8B\u4EF6\uFF1A\");\n for (const event of ep.events) lines.push(`- ${event}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\").trim();\n}\n\nfunction renderArcBriefs(arcs: ArcBrief[]): string {\n const lines: string[] = [];\n for (const arc of arcs) {\n lines.push(`\u7B2C${arc.startEpisodeNo}-${arc.endEpisodeNo}\u96C6`);\n lines.push(`\u9636\u6BB5\u6897\u6982\uFF1A${arc.synopsis}`);\n if (arc.turns.length > 0) {\n lines.push(\"\u5173\u952E\u8F6C\u6298\uFF1A\");\n for (const turn of arc.turns) lines.push(`- ${turn}`);\n }\n if (arc.openQuestions.length > 0) {\n lines.push(\"\u672A\u89E3\u51B3\u60AC\u5FF5\uFF1A\");\n for (const q of arc.openQuestions) lines.push(`- ${q}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\").trim();\n}\n\nfunction renderArcInput(parcel: ArcParcel): string {\n return [\n `\u5F53\u524D\u9636\u6BB5\uFF1A\u7B2C${parcel.startEpisodeNo}-${parcel.endEpisodeNo}\u96C6`,\n \"\",\n \"\u5206\u96C6\u6897\u6982\uFF1A\",\n parcel.text,\n ].join(\"\\n\");\n}\n\nfunction requireScope<T>(scope: T | null, name: string): T {\n if (scope === null) throw new Error(`${name} scope missing`);\n return scope;\n}\n\nfunction requireSingle<T>(items: T[], name: string): T {\n const item = items[0];\n if (!item || items.length !== 1) throw new Error(`${name} reduce requires exactly one item`);\n return item;\n}\n\nfunction firstNonEmpty(values: string[]): string {\n return values.map((value) => value.trim()).find((value) => value.length > 0) ?? \"\";\n}\n\nfunction uniqueStrings(values: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const value of values.map((v) => v.trim()).filter((v) => v.length > 0)) {\n if (seen.has(value)) continue;\n seen.add(value);\n out.push(value);\n }\n return out;\n}\n\nfunction synopsisPreviewLine(text: string): string {\n const clean = text.replace(/\\s+/g, \" \").trim();\n return clean.length > 50 ? clean.slice(0, 50) : clean;\n}\n\nfunction parsePositiveInt(value: unknown, fallback: number, label: string): number {\n if (value === undefined || value === null || value === \"\") return fallback;\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) {\n throw new CliError(`${label} must be a positive integer.`, {\n exitCode: EXIT_USAGE,\n errorCode: \"NUMERIC_OPTION_INVALID\",\n hint: `Pass ${label} ${fallback}.`,\n data: { expected: [`${label}: positive integer`], actual: [strOf(value)] },\n });\n }\n return Math.floor(n);\n}\n\nfunction setTextField(script: Dict, key: string, value: string, overwrite: boolean): boolean {\n if (!overwrite && strOf(script[key]).trim()) return false;\n if (strOf(script[key]) === value) return false;\n script[key] = value;\n return true;\n}\n\nfunction scriptOverviewMissing(script: Dict): boolean {\n return !strOf(script[\"synopsis\"]).trim()\n || !strOf(script[\"theme\"]).trim()\n || !strOf(script[\"logline\"]).trim()\n || !strOf(script[\"style\"]).trim()\n || asList(script[\"main_characters\"]).length === 0;\n}\n\nfunction existingScriptOverview(script: Dict): ScriptOverview {\n return {\n synopsis: strOf(script[\"synopsis\"]).trim(),\n theme: strOf(script[\"theme\"]).trim(),\n logline: strOf(script[\"logline\"]).trim(),\n style: strOf(script[\"style\"]).trim(),\n mainCharacters: asList<Dict>(script[\"main_characters\"]).map((item) => ({\n name: strOf(item[\"name\"]).trim(),\n role: strOf(item[\"role\"]).trim(),\n })).filter((item) => item.name && item.role),\n };\n}\n", "import * as path from \"node:path\";\n\nimport {\n exists,\n readJson,\n sha256Text,\n writeJson,\n} from \"../../common.js\";\nimport type {\n Checkpointer,\n CheckpointRecord,\n} from \"./types.js\";\n\nfunction keyPath(dir: string, key: string): string {\n const digest = sha256Text(key);\n return path.join(dir, `${digest}.json`);\n}\n\nexport function fileCheckpointer(dir: string): Checkpointer {\n return {\n read<T = unknown>(key: string): CheckpointRecord<T> | null {\n const p = keyPath(dir, key);\n if (!exists(p)) return null;\n return readJson<CheckpointRecord<T>>(p);\n },\n write<T = unknown>(record: CheckpointRecord<T>): void {\n writeJson(keyPath(dir, record.key), record);\n },\n };\n}\n\nexport function noopCheckpointer(): Checkpointer {\n return {\n read(): null {\n return null;\n },\n write(): void {\n // intentionally empty\n },\n };\n}\n", "import { sha256Text } from \"../../common.js\";\nimport {\n noopCheckpointer,\n} from \"./checkpointer.js\";\nimport type {\n Checkpointer,\n CheckpointRecord,\n ExtractTask,\n FnTask,\n LlmTask,\n LoomReport,\n LoomResult,\n LoomStep,\n LoomTree,\n ModelRequest,\n ModelResponse,\n ParcelNode,\n ReduceTask,\n RootNode,\n RunOptions,\n ScopeName,\n ScopeNode,\n SplitSpec,\n} from \"./types.js\";\n\nexport {\n fileCheckpointer,\n noopCheckpointer,\n} from \"./checkpointer.js\";\nexport type {\n Checkpointer,\n CheckpointRecord,\n ExtractTask,\n FnTask,\n LlmTask,\n LoomReport,\n LoomResult,\n LoomTree,\n ModelRequest,\n ModelResponse,\n ParcelNode,\n ReduceTask,\n RootNode,\n RunOptions,\n ScopeName,\n ScopeNode,\n SplitSpec,\n} from \"./types.js\";\n\ntype TreeNode = ScopeNode<unknown, unknown> | ParcelNode<unknown>;\ntype WorkNode = ScopeNode<unknown, unknown> | ParcelNode<unknown>;\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map((v) => stableStringify(v)).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n return `{${Object.keys(obj).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(\",\")}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction signature(value: unknown): string {\n return sha256Text(stableStringify(value));\n}\n\nfunction checkpointRecord<T>(key: string, sig: string, value: T): CheckpointRecord<T> {\n return {\n key,\n signature: sig,\n value,\n createdAt: new Date().toISOString(),\n };\n}\n\nfunction joinPrompt(instruction: string, format: string): string {\n return [instruction.trim(), format.trim()].filter(Boolean).join(\"\\n\\n\");\n}\n\nfunction renderLlmRequest(task: LlmTask<unknown, unknown>, parcelValue: unknown): { system: string; user: string } {\n return {\n system: joinPrompt(task.instruction, task.format),\n user: task.input ? task.input({ parcel: parcelValue }) : String(parcelValue),\n };\n}\n\nfunction extractCheckpointPayload(\n task: ExtractTask<unknown, unknown>,\n parcelValue: unknown,\n runtime: RequiredRuntime,\n): { payload: unknown; request?: { system: string; user: string } } {\n if (task.kind === \"llm\") {\n if (!runtime.executor) throw new Error(\"loom llm task requires run({ executor })\");\n const request = renderLlmRequest(task, parcelValue);\n const route = runtime.executor.route(task.taskId);\n return {\n request,\n payload: {\n step: \"extract\",\n kind: \"llm\",\n taskId: task.taskId,\n version: task.version ?? \"\",\n routeFingerprint: route.fingerprint,\n system: request.system,\n user: request.user,\n salt: runtime.checkpointSalt,\n },\n };\n }\n return {\n payload: {\n step: \"extract\",\n kind: \"fn\",\n version: task.version ?? \"\",\n parcel: parcelValue,\n salt: runtime.checkpointSalt,\n },\n };\n}\n\nexport function root<TParcel>(\n children: Array<ScopeNode<unknown, TParcel> | ParcelNode<TParcel>>,\n): RootNode<TParcel> {\n return { kind: \"root\", children };\n}\n\nexport function group<TScope, TParcel>(\n scope: ScopeName,\n children: Array<ScopeNode<unknown, TParcel> | ParcelNode<TParcel>>,\n data: TScope,\n): ScopeNode<TScope, TParcel> {\n return { kind: \"scope\", scope, data, children };\n}\n\nexport function parcel<TParcel>(data: TParcel): ParcelNode<TParcel> {\n return { kind: \"parcel\", data };\n}\n\nexport function llm<TInput, TOutput>(opts: {\n taskId: LlmTask<unknown, unknown>[\"taskId\"];\n version?: string;\n instruction: string;\n format: string;\n input?: (ctx: { parcel: TInput }) => string;\n parse: (ctx: { text: string; parcel: TInput; raw?: unknown }) => TOutput;\n validate?: (output: TOutput) => void;\n}): LlmTask<TInput, TOutput> {\n return { kind: \"llm\", ...opts };\n}\n\nexport function fn<TInput, TOutput>(opts: {\n version?: string;\n run: (ctx: { parcel: TInput }) => Promise<TOutput> | TOutput;\n validate?: (output: TOutput) => void;\n}): FnTask<TInput, TOutput> {\n return { kind: \"fn\", ...opts };\n}\n\nexport class LoomJob<TInput, TCurrent> {\n constructor(\n private readonly input: TInput,\n private readonly steps: LoomStep[] = [],\n ) {}\n\n split<TScope, TParcel>(spec: SplitSpec<TInput, TScope, TParcel>): LoomJob<TInput, TParcel> {\n return new LoomJob<TInput, TParcel>(this.input, [...this.steps, { kind: \"split\", spec: spec as SplitSpec<unknown, unknown, unknown> }]);\n }\n\n extract<TOutput>(task: ExtractTask<TCurrent, TOutput>): LoomJob<TInput, TOutput> {\n return new LoomJob<TInput, TOutput>(this.input, [...this.steps, { kind: \"extract\", task: task as ExtractTask<unknown, unknown> }]);\n }\n\n reduce<TOutput, TScope = unknown>(\n scope: ScopeName,\n task: ReduceTask<TCurrent, TOutput, TScope> | ((items: TCurrent[], ctx: { scope: TScope | null; scopeName: ScopeName }) => Promise<TOutput> | TOutput),\n ): LoomJob<TInput, TOutput> {\n const normalized: ReduceTask<TCurrent, TOutput, TScope> = typeof task === \"function\" ? { run: task } : task;\n return new LoomJob<TInput, TOutput>(this.input, [\n ...this.steps,\n { kind: \"reduce\", scope, task: normalized as ReduceTask<unknown, unknown, unknown> },\n ]);\n }\n\n plan(): { input: TInput; steps: LoomStep[] } {\n return { input: this.input, steps: [...this.steps] };\n }\n\n async run(opts: RunOptions = {}): Promise<LoomResult<TCurrent>> {\n const result = await executePlan<TCurrent>(this.input, this.steps, opts);\n return result;\n }\n}\n\nexport function loom<TInput>(input: TInput): LoomJob<TInput, TInput> {\n return new LoomJob<TInput, TInput>(input);\n}\n\nasync function mapWithConcurrency<T, R>(\n items: T[],\n concurrency: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n if (items.length === 0) return [];\n const out = new Array<R>(items.length);\n let cursor = 0;\n const limit = Math.max(1, Math.min(concurrency, items.length));\n await Promise.all(Array.from({ length: limit }, async () => {\n while (true) {\n const idx = cursor++;\n if (idx >= items.length) break;\n out[idx] = await worker(items[idx]!, idx);\n }\n }));\n return out;\n}\n\nfunction splitTree<TInput>(input: TInput, spec: SplitSpec<unknown, unknown, unknown>): RootNode<unknown> {\n const scopes = spec.partition(input);\n return root(scopes.map((scopeData) => {\n const chunks = spec.chunk(scopeData).map((chunk) => parcel(chunk));\n return group(spec.scope, chunks, scopeData);\n }));\n}\n\nfunction flattenParcels(node: RootNode<unknown> | WorkNode, path: string[] = []): Array<{ parcel: unknown; path: string[] }> {\n if (node.kind === \"parcel\") return [{ parcel: node.data, path }];\n const children = node.kind === \"root\" ? node.children : node.children;\n const out: Array<{ parcel: unknown; path: string[] }> = [];\n for (let i = 0; i < children.length; i++) {\n const child = children[i]!;\n const childPath = child.kind === \"scope\"\n ? [...path, `${child.scope}:${i}`]\n : [...path, `parcel:${i}`];\n out.push(...flattenParcels(child, childPath));\n }\n return out;\n}\n\nfunction validateOutput<T>(validate: ((output: T) => void) | undefined, output: T): T {\n validate?.(output);\n return output;\n}\n\nasync function runFnExtractTask(\n task: FnTask<unknown, unknown>,\n parcelValue: unknown,\n): Promise<unknown> {\n return validateOutput(task.validate, await task.run({ parcel: parcelValue }));\n}\n\nasync function runLlmModel(\n task: LlmTask<unknown, unknown>,\n request: { system: string; user: string },\n runtime: RequiredRuntime,\n): Promise<ModelResponse> {\n if (!runtime.executor) throw new Error(\"loom llm task requires run({ executor })\");\n return runtime.executor.generateText(task.taskId, { system: request.system, user: request.user, signal: runtime.signal });\n}\n\nfunction parseLlmResponse(\n task: LlmTask<unknown, unknown>,\n parcelValue: unknown,\n response: ModelResponse,\n): unknown {\n return validateOutput(\n task.validate,\n task.parse({ text: response.text, parcel: parcelValue, raw: response.raw }),\n );\n}\n\nfunction replaceParcels(\n node: RootNode<unknown> | WorkNode,\n values: unknown[],\n cursor: { index: number },\n): RootNode<unknown> | WorkNode {\n if (node.kind === \"parcel\") {\n const value = values[cursor.index];\n cursor.index += 1;\n return parcel(value);\n }\n const children = node.children.map((child) => replaceParcels(child, values, cursor) as WorkNode);\n if (node.kind === \"root\") return root(children);\n return group(node.scope, children, node.data);\n}\n\nfunction allChildrenParcels(node: ScopeNode<unknown, unknown> | RootNode<unknown>): boolean {\n return node.children.every((child) => child.kind === \"parcel\");\n}\n\nasync function reduceScopeNode(\n node: RootNode<unknown> | WorkNode,\n scope: ScopeName,\n task: ReduceTask<unknown, unknown, unknown>,\n runtime: RequiredRuntime,\n path: string[],\n): Promise<RootNode<unknown> | WorkNode> {\n if (node.kind === \"parcel\") return node;\n const reducedChildren: WorkNode[] = [];\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i]!;\n reducedChildren.push(await reduceScopeNode(child, scope, task, runtime, [...path, `${child.kind}:${i}`]) as WorkNode);\n }\n\n const rebuilt = node.kind === \"root\" ? root(reducedChildren) : group(node.scope, reducedChildren, node.data);\n const isTargetRoot = scope === \"root\" && rebuilt.kind === \"root\";\n const isTargetScope = rebuilt.kind === \"scope\" && rebuilt.scope === scope;\n if (!isTargetRoot && !isTargetScope) return rebuilt;\n if (!allChildrenParcels(rebuilt)) return rebuilt;\n\n const items = rebuilt.children.map((child) => (child as ParcelNode<unknown>).data);\n const scopeData = rebuilt.kind === \"scope\" ? rebuilt.data : null;\n const scopeName = rebuilt.kind === \"scope\" ? rebuilt.scope : \"root\";\n const version = task.version ?? \"\";\n const key = `reduce:${scope}:${path.join(\"/\")}:${signature({ items, scopeData, version, salt: runtime.checkpointSalt })}`;\n const sig = signature({ step: \"reduce\", scope, version, items, scopeData, salt: runtime.checkpointSalt });\n const cached = await readCheckpoint(runtime.checkpoint, key, sig);\n if (cached.hit) {\n runtime.report.reused += 1;\n return parcel(validateOutput(task.validate, cached.value));\n }\n const out = validateOutput(task.validate, await task.run(items, { scope: scopeData, scopeName }));\n runtime.report.ran += 1;\n await runtime.checkpoint.write(checkpointRecord(key, sig, out));\n return parcel(out);\n}\n\nasync function readCheckpoint(\n checkpoint: Checkpointer,\n key: string,\n sig: string,\n): Promise<{ hit: true; value: unknown } | { hit: false }>;\nasync function readCheckpoint<T>(\n checkpoint: Checkpointer,\n key: string,\n sig: string,\n): Promise<{ hit: true; value: T } | { hit: false }>;\nasync function readCheckpoint<T = unknown>(\n checkpoint: Checkpointer,\n key: string,\n sig: string,\n): Promise<{ hit: true; value: T } | { hit: false }> {\n const record = await checkpoint.read<T>(key);\n if (record && record.signature === sig) return { hit: true, value: record.value };\n return { hit: false };\n}\n\ninterface RequiredRuntime {\n executor?: RunOptions[\"executor\"];\n signal?: AbortSignal;\n checkpointSalt?: unknown;\n checkpoint: Checkpointer;\n concurrency: number;\n report: LoomReport;\n}\n\nasync function executePlan<T>(input: unknown, steps: LoomStep[], opts: RunOptions): Promise<LoomResult<T>> {\n const runtime: RequiredRuntime = {\n executor: opts.executor,\n signal: opts.signal,\n checkpointSalt: opts.checkpointSalt,\n checkpoint: opts.checkpoint ?? noopCheckpointer(),\n concurrency: opts.concurrency ?? 4,\n report: { reused: 0, ran: 0 },\n };\n let tree: RootNode<unknown> | null = null;\n let currentInput: unknown = input;\n for (const step of steps) {\n if (step.kind === \"split\") {\n tree = splitTree(currentInput, step.spec);\n currentInput = tree;\n continue;\n }\n if (!tree) {\n tree = root([parcel(currentInput)]);\n }\n if (step.kind === \"extract\") {\n const leaves = flattenParcels(tree);\n const values = await mapWithConcurrency(leaves, runtime.concurrency, async (leaf) => {\n const checkpoint = extractCheckpointPayload(step.task, leaf.parcel, runtime);\n const sig = signature(checkpoint.payload);\n const key = `extract:${leaf.path.join(\"/\")}:${sig}`;\n\n if (step.task.kind === \"llm\") {\n const cached = await readCheckpoint<ModelResponse>(runtime.checkpoint, key, sig);\n if (cached.hit) {\n runtime.report.reused += 1;\n runtime.executor?.recordReuse(step.task.taskId);\n return parseLlmResponse(step.task, leaf.parcel, cached.value);\n }\n const request = checkpoint.request ?? renderLlmRequest(step.task, leaf.parcel);\n const response = await runLlmModel(step.task, request, runtime);\n const value = parseLlmResponse(step.task, leaf.parcel, response);\n runtime.report.ran += 1;\n await runtime.checkpoint.write(checkpointRecord(key, sig, response));\n return value;\n }\n\n const cached = await readCheckpoint(runtime.checkpoint, key, sig);\n if (cached.hit) {\n runtime.report.reused += 1;\n return validateOutput(step.task.validate, cached.value);\n }\n const value = await runFnExtractTask(step.task, leaf.parcel);\n runtime.report.ran += 1;\n await runtime.checkpoint.write(checkpointRecord(key, sig, value));\n return value;\n });\n tree = replaceParcels(tree, values, { index: 0 }) as RootNode<unknown>;\n currentInput = tree;\n continue;\n }\n tree = await reduceScopeNode(tree, step.scope, step.task, runtime, []) as RootNode<unknown>;\n currentInput = tree;\n }\n if (!tree) return { value: currentInput as T, report: runtime.report };\n const leaves = flattenParcels(tree);\n if (leaves.length !== 1) {\n throw new Error(`loom plan ended with ${leaves.length} result(s); reduce to root before run completes`);\n }\n return { value: leaves[0]!.parcel as T, report: runtime.report };\n}\n", "import * as fs from \"node:fs\";\n\nimport {\n CliError,\n EXIT_INPUT,\n EXIT_OK,\n EXIT_RUNTIME,\n type CommandOutput,\n scriptJsonPath,\n} from \"../../common.js\";\nimport { requireScriptDocument } from \"../../domain/script/dispatch.js\";\nimport { isDict, type Dict, strOf } from \"../../domain/script/shared.js\";\nimport {\n remoteScriptOutputStoreFromEnv,\n ScriptOutputApiError,\n type ScriptSnapshot,\n type ScriptV2OutputStore,\n} from \"../../infra/script-output-api.js\";\nimport { syncEpisodeCount } from \"../../infra/script-output-store.js\";\nimport {\n assertLocalFileFingerprint,\n assertScriptUnchanged,\n atomicWriteJson,\n localFileFingerprint,\n readWorkingCopyMetadata,\n semanticScriptHash,\n workingCopyPaths,\n writeWorkingCopyMetadata,\n type WorkingCopyMetadata,\n} from \"../../infra/script-working-copy.js\";\nimport { apiErrorToCli, validateScriptReport } from \"./session.js\";\n\nconst MAX_PUBLISH_ATTEMPTS = 3;\n\ntype ValidationPayload = {\n status: \"valid\";\n summary: Dict;\n};\n\ntype ManagedPublishResult = {\n revision: number;\n patchedFromRevision: number;\n attempts: number;\n recovered: boolean;\n};\n\nfunction configuredProjectGroupNo(opts: Dict): string {\n return strOf(opts[\"project_group_no\"] || process.env.SANDBOX_PROJECT_GROUP_NO).trim();\n}\n\nfunction remoteClient(projectGroupNo: string | null): ScriptV2OutputStore {\n try {\n return remoteScriptOutputStoreFromEnv(projectGroupNo);\n } catch (error) {\n if (error instanceof ScriptOutputApiError) {\n throw apiErrorToCli(\"SCRIPT API BLOCKED: gateway not configured\", error);\n }\n throw error;\n }\n}\n\nfunction clientForMetadata(opts: Dict, metadata: WorkingCopyMetadata): ScriptV2OutputStore {\n const configuredProject = configuredProjectGroupNo(opts);\n if (configuredProject && configuredProject !== metadata.projectGroupNo) {\n throw remoteMismatch(metadata, `configured projectGroupNo=${configuredProject}`);\n }\n const client = remoteClient(metadata.projectGroupNo);\n if (client.gatewayBase !== metadata.apiBaseUrl) {\n throw remoteMismatch(metadata, `configured apiBaseUrl=${client.gatewayBase}`);\n }\n return client;\n}\n\nfunction remoteMismatch(metadata: WorkingCopyMetadata, received: string): CliError {\n return new CliError(\"The configured remote does not match this working copy.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"WORKING_COPY_REMOTE_MISMATCH\",\n hint: \"Restore the checkout environment for this working copy, or checkout another file.\",\n data: { expected: [`projectGroupNo=${metadata.projectGroupNo}`, `apiBaseUrl=${metadata.apiBaseUrl}`], actual: [received] },\n });\n}\n\nfunction readLocalScript(scriptPath: string): Dict {\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(scriptPath, \"utf-8\"));\n } catch (error) {\n throw new CliError(\"The local script is missing or invalid JSON.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_JSON_INVALID\",\n hint: \"Fix the local script JSON before continuing.\",\n data: { actual: [scriptPath, error instanceof Error ? error.message : String(error)] },\n });\n }\n if (!isDict(value)) {\n throw new CliError(\"The script root must be a JSON object.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"SCRIPT_ROOT_INVALID\",\n hint: \"Replace the file with a valid Script v3 JSON object.\",\n data: { actual: [scriptPath, Array.isArray(value) ? \"array\" : typeof value] },\n });\n }\n return value;\n}\n\nfunction isRevisionConflict(error: ScriptOutputApiError): boolean {\n return String(error.code) === \"9002\" || error.message.includes(\"\u7248\u672C\u51B2\u7A81\");\n}\n\nfunction isAmbiguousResponse(error: ScriptOutputApiError): boolean {\n const malformedSuccess = error.status !== null\n && error.status >= 200\n && error.status < 300\n && error.code === null;\n return error.status === null || error.status >= 500 || malformedSuccess;\n}\n\nfunction snapshotRevision(snapshot: ScriptSnapshot): number {\n const revision = Number(snapshot.revision);\n if (!Number.isInteger(revision) || revision < 0) {\n throw new CliError(\"The gateway returned an invalid snapshot revision.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"PUBLISH_OUTCOME_UNKNOWN\",\n hint: \"Inspect the remote script before retrying.\",\n data: { actual: [JSON.stringify(snapshot)] },\n });\n }\n return revision;\n}\n\nfunction outcomeUnknown(baseRevision: number, received: string[]): CliError {\n return new CliError(\"The publish outcome could not be confirmed after retrying.\", {\n exitCode: EXIT_RUNTIME,\n errorCode: \"PUBLISH_OUTCOME_UNKNOWN\",\n hint: \"Run publish again; it will inspect the latest snapshot before sending another patch.\",\n data: { actual: [...received, `baseRevision=${baseRevision}`] },\n });\n}\n\nasync function publishManagedLocalWins(\n client: ScriptV2OutputStore,\n scriptPath: string,\n script: Dict,\n scriptHash: string,\n metadata: WorkingCopyMetadata,\n validation: ValidationPayload,\n): Promise<ManagedPublishResult> {\n const failures: string[] = [];\n for (let attempt = 1; attempt <= MAX_PUBLISH_ATTEMPTS; attempt += 1) {\n let snapshot: ScriptSnapshot | null;\n try {\n snapshot = await client.getSnapshot();\n } catch (error) {\n if (error instanceof ScriptOutputApiError && isAmbiguousResponse(error)) {\n failures.push(`snapshot attempt ${attempt}: ${error.message}`);\n continue;\n }\n if (error instanceof ScriptOutputApiError) throw apiErrorToCli(\"PUBLISH BLOCKED: snapshot query failed\", error);\n throw error;\n }\n if (snapshot === null || !isDict(snapshot.script)) {\n throw new CliError(\"The managed working copy no longer has a remote script.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"REMOTE_SCRIPT_NOT_FOUND\",\n hint: \"Publish a new unmanaged file to create the remote script, or restore the remote project.\",\n data: { actual: [`projectGroupNo=${client.projectGroupNo}`] },\n });\n }\n const baseRevision = snapshotRevision(snapshot);\n if (semanticScriptHash(snapshot.script) === scriptHash && snapshot.validationStatus === \"valid\") {\n return {\n revision: baseRevision,\n patchedFromRevision: baseRevision,\n attempts: attempt,\n recovered: baseRevision !== metadata.baseRevision,\n };\n }\n\n assertScriptUnchanged(scriptPath, scriptHash);\n try {\n const response = await client.publishPatch({\n baseRevision,\n old: snapshot.script,\n edited: script,\n validation,\n });\n const revision = isDict(response) ? Number(response[\"revision\"]) : Number.NaN;\n if (Number.isInteger(revision) && revision > baseRevision) {\n return { revision, patchedFromRevision: baseRevision, attempts: attempt, recovered: attempt > 1 };\n }\n failures.push(`patch attempt ${attempt}: invalid response ${JSON.stringify(response)}`);\n } catch (error) {\n if (error instanceof ScriptOutputApiError && (isRevisionConflict(error) || isAmbiguousResponse(error))) {\n failures.push(`patch attempt ${attempt}: ${error.message}`);\n continue;\n }\n if (error instanceof ScriptOutputApiError) throw apiErrorToCli(\"PUBLISH BLOCKED: patch failed\", error);\n throw error;\n }\n }\n throw outcomeUnknown(metadata.baseRevision, failures);\n}\n\nasync function publishInitial(\n client: ScriptV2OutputStore,\n scriptPath: string,\n script: Dict,\n scriptHash: string,\n validation: ValidationPayload,\n): Promise<ManagedPublishResult> {\n const failures: string[] = [];\n for (let attempt = 1; attempt <= MAX_PUBLISH_ATTEMPTS; attempt += 1) {\n let snapshot: ScriptSnapshot | null;\n try {\n snapshot = await client.getSnapshot();\n } catch (error) {\n if (error instanceof ScriptOutputApiError && isAmbiguousResponse(error)) {\n failures.push(`snapshot attempt ${attempt}: ${error.message}`);\n continue;\n }\n if (error instanceof ScriptOutputApiError) throw apiErrorToCli(\"PUBLISH BLOCKED: snapshot query failed\", error);\n throw error;\n }\n\n if (snapshot !== null) {\n const revision = snapshotRevision(snapshot);\n if (isDict(snapshot.script)\n && semanticScriptHash(snapshot.script) === scriptHash\n && snapshot.validationStatus === \"valid\") {\n return { revision, patchedFromRevision: 0, attempts: attempt, recovered: true };\n }\n throw new CliError(\"An unmanaged local script cannot replace an existing remote script.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"REMOTE_SCRIPT_EXISTS\",\n hint: \"Checkout the remote script, apply the local changes to that managed working copy, then publish.\",\n data: { actual: [`projectGroupNo=${client.projectGroupNo}`, `revision=${revision}`] },\n });\n }\n\n assertScriptUnchanged(scriptPath, scriptHash);\n try {\n const response = await client.publishPatch({\n baseRevision: 0,\n old: {},\n edited: script,\n validation,\n });\n const revision = isDict(response) ? Number(response[\"revision\"]) : Number.NaN;\n if (Number.isInteger(revision) && revision > 0) {\n return { revision, patchedFromRevision: 0, attempts: attempt, recovered: attempt > 1 };\n }\n failures.push(`patch attempt ${attempt}: invalid response ${JSON.stringify(response)}`);\n } catch (error) {\n if (error instanceof ScriptOutputApiError && (isRevisionConflict(error) || isAmbiguousResponse(error))) {\n failures.push(`patch attempt ${attempt}: ${error.message}`);\n continue;\n }\n if (error instanceof ScriptOutputApiError) throw apiErrorToCli(\"PUBLISH BLOCKED: patch failed\", error);\n throw error;\n }\n }\n throw outcomeUnknown(0, failures);\n}\n\nexport async function commandCheckout(opts: Dict): Promise<[CommandOutput, number]> {\n const scriptPath = scriptJsonPath(opts);\n const discardLocal = Boolean(opts[\"discard_local\"]);\n const paths = workingCopyPaths(scriptPath);\n const metadata = readWorkingCopyMetadata(scriptPath);\n const existed = fs.existsSync(scriptPath);\n const beforeFingerprint = localFileFingerprint(scriptPath);\n\n if (existed && metadata === null && !discardLocal) {\n throw new CliError(\"The target is an unmanaged local script.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"LOCAL_TARGET_EXISTS\",\n hint: `Run \\`scriptctl checkout --script-path ${scriptPath} --discard-local\\` only if the local file may be discarded.`,\n data: { actual: [scriptPath] },\n });\n }\n if (existed && metadata !== null && !discardLocal) {\n const currentHash = semanticScriptHash(readLocalScript(scriptPath));\n if (currentHash !== metadata.baseContentHash) {\n throw new CliError(\"The working copy has unpublished local changes.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"WORKING_COPY_DIRTY\",\n hint: \"Publish the local changes, or pass --discard-local to replace them with the remote snapshot.\",\n data: { actual: [scriptPath, `baseRevision=${metadata.baseRevision}`] },\n });\n }\n }\n\n const client = metadata !== null && !discardLocal\n ? clientForMetadata(opts, metadata)\n : remoteClient(configuredProjectGroupNo(opts) || null);\n let snapshot;\n try {\n snapshot = await client.getSnapshot();\n } catch (error) {\n if (error instanceof ScriptOutputApiError) {\n throw apiErrorToCli(\"CHECKOUT BLOCKED: snapshot query failed\", error);\n }\n throw error;\n }\n if (snapshot === null || !isDict(snapshot.script)) {\n throw new CliError(\"No remote script_v2 snapshot exists for this project.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"REMOTE_SCRIPT_NOT_FOUND\",\n hint: \"Use the ingest/create workflow and publish the first script instead of checkout.\",\n data: { actual: [`projectGroupNo=${client.projectGroupNo}`] },\n });\n }\n assertLocalFileFingerprint(scriptPath, beforeFingerprint);\n const baseContentHash = semanticScriptHash(snapshot.script);\n atomicWriteJson(scriptPath, snapshot.script);\n writeWorkingCopyMetadata(scriptPath, {\n schemaVersion: 1,\n projectGroupNo: client.projectGroupNo,\n apiBaseUrl: client.gatewayBase,\n baseRevision: Number(snapshot.revision),\n baseContentHash,\n });\n const text = discardLocal && existed\n ? `Discarded the local file and checked out revision ${snapshot.revision} to ${scriptPath}`\n : `Checked out revision ${snapshot.revision} to ${scriptPath}`;\n return [{\n text,\n data: {\n changed: true,\n script_path: scriptPath,\n metadata_path: paths.metadataPath,\n managed: true,\n dirty: false,\n discarded_local: discardLocal && existed,\n project_group_no: client.projectGroupNo,\n base_revision: Number(snapshot.revision),\n },\n }, EXIT_OK];\n}\n\nexport function commandWorkingCopyStatus(opts: Dict): [CommandOutput, number] {\n const scriptPath = scriptJsonPath(opts);\n const exists = fs.existsSync(scriptPath);\n const metadata = readWorkingCopyMetadata(scriptPath);\n const dirty = exists && metadata !== null\n ? semanticScriptHash(readLocalScript(scriptPath)) !== metadata.baseContentHash\n : null;\n const text = metadata === null\n ? `${scriptPath}: unmanaged local script`\n : `${scriptPath}: ${dirty ? \"dirty\" : \"clean\"} at revision ${metadata.baseRevision}`;\n return [{\n text,\n data: {\n script_path: scriptPath,\n exists,\n managed: metadata !== null,\n dirty,\n ...(metadata === null ? {} : {\n project_group_no: metadata.projectGroupNo,\n api_base_url: metadata.apiBaseUrl,\n base_revision: metadata.baseRevision,\n }),\n },\n }, EXIT_OK];\n}\n\nexport async function commandWorkingCopyPublish(opts: Dict): Promise<[CommandOutput, number]> {\n const scriptPath = scriptJsonPath(opts);\n const script = readLocalScript(scriptPath);\n const scriptHash = semanticScriptHash(script);\n const metadata = readWorkingCopyMetadata(scriptPath);\n if (metadata !== null && metadata.baseContentHash === scriptHash) {\n return [{\n text: `No local changes; revision remains ${metadata.baseRevision}`,\n data: {\n changed: false,\n published: false,\n reason: \"NO_CHANGES\",\n revision: metadata.baseRevision,\n script_path: scriptPath,\n },\n }, EXIT_OK];\n }\n\n const validation = validateScriptReport(script);\n if (!Boolean(validation[\"passed\"])) {\n throw new CliError(\"The local script does not pass its declared Script version validation.\", {\n exitCode: EXIT_INPUT,\n errorCode: \"PUBLISH_VALIDATION_FAILED\",\n hint: `Run \\`scriptctl validate --script-path ${scriptPath}\\`, repair the issues, then publish again.`,\n data: { actual: (validation[\"issues\"] as Dict[]).slice(0, 5).map((issue) => `${issue[\"path\"] ?? \"<root>\"}: ${issue[\"summary\"]}`) },\n });\n }\n const episodeCount = requireScriptDocument(script).episodes.length;\n\n const validationPayload: ValidationPayload = {\n status: \"valid\",\n summary: {\n passed: true,\n hasBlocking: false,\n stats: validation[\"stats\"] ?? {},\n issueCount: 0,\n },\n };\n\n if (metadata !== null) {\n const client = clientForMetadata(opts, metadata);\n const result = await publishManagedLocalWins(\n client,\n scriptPath,\n script,\n scriptHash,\n metadata,\n validationPayload,\n );\n writeWorkingCopyMetadata(scriptPath, {\n schemaVersion: 1,\n projectGroupNo: client.projectGroupNo,\n apiBaseUrl: client.gatewayBase,\n baseRevision: result.revision,\n baseContentHash: scriptHash,\n });\n await syncEpisodeCount(client, episodeCount);\n return [{\n text: `Published local content over revision ${result.patchedFromRevision} \u2192 ${result.revision}`,\n data: {\n changed: true,\n published: true,\n created: false,\n transport: \"patch\",\n script_path: scriptPath,\n project_group_no: client.projectGroupNo,\n base_revision: result.patchedFromRevision,\n revision: result.revision,\n attempts: result.attempts,\n recovered: result.recovered,\n },\n }, EXIT_OK];\n }\n\n const client = remoteClient(configuredProjectGroupNo(opts) || null);\n const result = await publishInitial(client, scriptPath, script, scriptHash, validationPayload);\n writeWorkingCopyMetadata(scriptPath, {\n schemaVersion: 1,\n projectGroupNo: client.projectGroupNo,\n apiBaseUrl: client.gatewayBase,\n baseRevision: result.revision,\n baseContentHash: scriptHash,\n });\n await syncEpisodeCount(client, episodeCount);\n return [{\n text: `Published revision ${result.patchedFromRevision} \u2192 ${result.revision}`,\n data: {\n changed: true,\n published: true,\n created: true,\n transport: \"patch\",\n script_path: scriptPath,\n project_group_no: client.projectGroupNo,\n base_revision: result.patchedFromRevision,\n revision: result.revision,\n attempts: result.attempts,\n recovered: result.recovered,\n },\n }, EXIT_OK];\n}\n", "import { Command } from \"commander\";\n\nimport { type LlmComposition } from \"../llm/composition.js\";\nimport { commandIngest } from \"../usecases/ingest/command.js\";\nimport { commandIngestStatus } from \"../usecases/ingest/status.js\";\nimport { commandSkipVideoEpisode } from \"../usecases/ingest/skip-video-episode.js\";\nimport { commandGenerateVideoStateEvidence } from \"../usecases/ingest/generate-video-state-evidence.js\";\nimport { commandView } from \"../usecases/ingest/view-command.js\";\nimport { commandAuditAssets } from \"../usecases/script/audit-assets.js\";\nimport { commandCreate } from \"../usecases/script/create.js\";\nimport { commandMigrate } from \"../usecases/script/migrate.js\";\nimport { commandSynopsisGenerate } from \"../usecases/script/synopsis-generate.js\";\nimport {\n commandCheckout,\n commandWorkingCopyPublish,\n commandWorkingCopyStatus,\n} from \"../usecases/script/working-copy.js\";\nimport {\n describeArguments,\n dispatch,\n type RunState,\n withScriptOpts,\n withWorkingCopyOpts,\n} from \"./registry.js\";\n\nexport function registerWorkflowCommands(program: Command, state: RunState, llm: LlmComposition): void {\n program.command(\"migrate\")\n .description(\"Create a newer Script schema copy through the registered migration chain\")\n .requiredOption(\"-p, --script-path <path>\", \"Source Script JSON file\")\n .requiredOption(\"-o, --output <file>\", \"Destination Script JSON file\")\n .requiredOption(\"--to <version>\", \"Target Script version\")\n .option(\"--manifest <file>\", \"Migration manifest output\")\n .option(\"--force\", \"Replace existing migration artifacts\")\n .addHelpText(\n \"after\",\n \"\\nExample:\\n scriptctl migrate -p ./old-script.json -o ./script-v4.json --to 4\\n\",\n )\n .action(dispatch(commandMigrate, state));\n\n const ingest = program.command(\"ingest\")\n .description(\"Convert source files into a Script v4 workspace\")\n .option(\"-s, --source-path <path>\", \"Source file or directory\")\n .option(\"-w, --workspace-path <path>\", \"Workspace directory\", \"workspace\")\n .option(\"--llm-config <path>\", \"LLM configuration file\")\n .option(\"--concurrency <n>\", \"Maximum concurrent model calls\")\n .option(\"--fps <n>\", \"Video sampling rate\")\n .option(\"--upload-mode <mode>\", \"Video transport: file-api (default) or base64\")\n .option(\"--provider-base-url <url>\", \"Gemini-compatible provider service root\")\n .option(\"--provider-api-key <key>\", \"Provider API key (visible in process arguments; prefer --provider-api-key-env)\")\n .option(\"--provider-api-key-env <name>\", \"Environment variable containing the provider API key\")\n .option(\"--provider-model <model>\", \"Gemini-compatible provider model\")\n .option(\"--step\", \"Process only the next unfinished video episode\")\n .option(\"--force\", \"Rebuild completed stages\")\n .addHelpText(\"after\", \"\\nExample:\\n scriptctl ingest --source-path ./draft.md --workspace-path ./workspace\\n\")\n .action(dispatch((options) => commandIngest(options, llm), state));\n\n ingest.command(\"status\")\n .description(\"Show ingest workspace progress\")\n .option(\"-w, --workspace-path <path>\", \"Workspace directory\")\n .action(dispatch(commandIngestStatus, state));\n\n ingest.command(\"skip\")\n .description(\"Manually accept the next failed video episode as empty\")\n .option(\"-w, --workspace-path <path>\", \"Workspace directory\")\n .requiredOption(\"--episode <n>\", \"Failed episode number\")\n .requiredOption(\"--reason <text>\", \"Why this episode is being skipped\")\n .addHelpText(\"after\", \"\\nExample:\\n scriptctl ingest skip -w ./workspace --episode 7 --reason \\\"provider policy block\\\"\\n\")\n .action(dispatch(commandSkipVideoEpisode, state));\n\n program.command(\"evidence\")\n .description(\"Generate local original-video reference frames from final Script v4 timestamps\")\n .option(\"-p, --script-path <path>\", \"Final Script v4 JSON file\")\n .requiredOption(\"-s, --source-path <path>\", \"Linked source-video file or episode directory\")\n .requiredOption(\"-w, --workspace-path <path>\", \"Project workspace directory\")\n .option(\"--force\", \"Re-extract frames even when deterministic output files already exist\")\n .addHelpText(\"after\", \"\\nExample:\\n scriptctl evidence -p ./script.json -s /Volumes/NAS/videos -w ./workspace --force\\n\")\n .action(dispatch(commandGenerateVideoStateEvidence, state));\n\n program.command(\"view\")\n .description(\"Render or serve the workspace review page\")\n .option(\"-w, --workspace-path <path>\", \"Workspace directory\", \"workspace\")\n .option(\"--watch\", \"Serve and refresh the review page\")\n .option(\"--port <n>\", \"HTTP server port\")\n .action(dispatch(commandView, state));\n\n withWorkingCopyOpts(program.command(\"checkout\"))\n .description(\"Download a remote script into a managed local copy\")\n .option(\"--discard-local\", \"Replace an existing dirty local copy\")\n .action(dispatch(commandCheckout, state));\n\n withScriptOpts(program.command(\"status\"), \"read\")\n .description(\"Show local working-copy state\")\n .action(dispatch(commandWorkingCopyStatus, state));\n\n withWorkingCopyOpts(program.command(\"publish\"))\n .description(\"Validate and publish the local working copy\")\n .action(dispatch(commandWorkingCopyPublish, state));\n\n // The .scriptctl authoring surface (write / compose / export) is gone with\n // the rest of the old agent-facing CLI: `read` emits the prose that the new\n // `write` accepts back, so an agent needs neither a bracket grammar nor a\n // plan digest. Ingest, checkout, publish and view stay \u2014 they are pipeline\n // steps, not tools an agent reaches for.\n\n // These three used to sit among the agent commands, but they are pipeline\n // steps too: `create` and `synopsis generate` are called by redraw's source\n // preparation workflow, and `audit-assets` is a whole-script LLM pass, not\n // something an agent reaches for mid-review.\n withScriptOpts(program.command(\"create\"))\n .description(\"Create an empty script\")\n .option(\"--title <title>\", \"Script title\")\n .option(\"--force\", \"Replace an existing script file\")\n .action(dispatch(commandCreate, state));\n\n withScriptOpts(program.command(\"audit-assets\"), \"read\")\n .description(\"Audit asset consistency with an LLM\")\n .option(\"--llm-config <path>\", \"LLM configuration file\")\n .option(\"-o, --output <path>\", \"Audit JSON output file\")\n .action(dispatch((options) => commandAuditAssets(options, llm), state));\n\n // Setting synopsis text is `edit --synopsis`; this parent only carries the\n // LLM generator, which redraw invokes as `synopsis generate`.\n const synopsis = program.command(\"synopsis\")\n .description(\"Generate synopsis fields with an LLM\")\n .action(() => synopsis.outputHelp());\n\n withScriptOpts(synopsis.command(\"generate\"))\n .description(\"Generate synopsis fields with an LLM\")\n .option(\"--llm-config <path>\", \"LLM configuration file\")\n .option(\"--concurrency <n>\", \"Maximum concurrent model calls\", \"30\")\n .option(\"--checkpoint <dir>\", \"Checkpoint directory\")\n .option(\"--overwrite\", \"Regenerate existing synopsis fields\")\n .option(\"--apply\", \"Write generated fields\")\n .option(\"-n, --dry-run\", \"Generate a preview without writing\")\n .action(dispatch((options) => commandSynopsisGenerate(options, llm), state));\n}\n", "#!/usr/bin/env node\nimport { main } from \"./cli.js\";\n\nmain(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((err) => {\n // eslint-disable-next-line no-console\n console.error(err);\n process.exitCode = 70;\n });\n"],
|
|
5
|
+
"mappings": "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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAuEd,SAAS,gCAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAsBP,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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",
|
|
6
|
+
"names": ["fs", "path", "text", "message", "text", "message", "fs", "path", "fs", "path", "body", "fs", "path", "createRequire", "fs", "path", "fileURLToPath", "message", "fs", "os", "path", "message", "record", "root", "crypto", "message", "resolve", "cached", "message", "request", "text", "fs", "path", "fetch", "isRecord", "message", "delay", "resolve", "message", "num", "request", "text", "root", "readError", "fetch", "fs", "fs", "root", "resolve", "num", "POLL_INTERVAL_MS", "delay", "resolve", "message", "request", "text", "finishReason", "require", "usageOf", "isRecord", "num", "cached", "message", "request", "text", "spec", "message", "cached", "request", "require", "createRequire", "report", "text", "resolve", "issues", "line", "crypto", "fs", "path", "record", "text", "message", "state", "state", "fs", "path", "fileURLToPath", "llm", "fileURLToPath", "write", "state", "fs", "fs", "issues", "baseline", "message", "minutes", "seconds", "fraction", "milliseconds", "doc", "path", "message", "collect", "list", "nameKey", "ref", "isObj", "isStr", "isArr", "path", "doc", "message", "list", "nameKey", "assetName", "state", "episode", "ref", "path", "doc", "asset", "resolve", "doc", "pad", "text", "message", "doc", "doc", "resolve", "list", "ref", "text", "oneOf", "process", "sep", "assetName", "path", "str", "state", "read", "find", "span", "edit", "insert", "move", "write", "fs", "replace", "ref", "asset", "del", "merge", "ext", "path", "fs", "path", "ext", "fs", "path", "ref", "nextStateId", "state", "nameKey", "text", "message", "isObj", "str", "ref", "state", "episode", "text", "norm", "text", "norm", "list", "path", "message", "asset", "episode", "isObj", "isArr", "pad", "KINDS", "doc", "list", "newId", "isRecord", "record", "isJsonValue", "ref", "createHash", "issues", "generateV4Id", "generateV4Id", "converted", "state", "stateId", "ref", "episode", "actionAddress", "signature", "createHash", "record", "asset", "fs", "fs", "strOf", "isDict", "isList", "isDict", "strOf", "isList", "strings", "ref", "text", "isList", "isDict", "tableText", "collect", "text", "ext", "fs", "path", "writeJson", "readJson", "root", "writeJson", "readJson", "message", "record", "text", "text", "step", "isObj", "isArr", "list", "doc", "ref", "asset", "state", "isObj", "str", "message", "merge", "isObj", "isArr", "norm", "merge", "t0", "cached", "group", "startEp", "endEp", "SPACE", "doc", "asset", "nameKey", "assetName", "stateName", "isObj", "list", "doc", "root", "stateName", "state", "asset", "ref", "asset", "state", "isObj", "asArr", "asStr", "issues", "report", "issues", "cached", "cached", "crypto", "record", "group", "report", "episode", "episodeNumber", "pad", "text", "records", "message", "pad3", "fs", "path", "pad", "state", "emptyContext", "norm", "clip", "arr", "state", "episode", "has", "applyDelta", "find", "text", "ref", "render", "stamp", "list", "nameKey", "norm", "episode", "stateName", "ref", "state", "path", "ext", "message", "fs", "path", "episode", "spawn", "fs", "path", "resolve", "spawn", "fs", "path", "resolve", "spawn", "fs", "path", "lockfile", "root", "lockfile", "message", "isObj", "asStr", "asArr", "state", "text", "ref", "isRecord", "episode", "oneOf", "optionalString", "record", "value", "episode", "pad", "episode", "header", "checkLifecycle", "state", "asset", "path", "record", "step", "emptyContext", "doc", "applyDelta", "strOf", "message", "executor", "report", "result", "fs", "path", "strOf", "root", "message", "normalize", "record", "state", "path", "message", "episode", "header", "emptyContext", "record", "currentManifest", "identityMap", "fs", "path", "isRecord", "optionalString", "record", "isJsonValue", "hasValidExtension", "isState", "isActor", "isLocation", "isProp", "isAction", "isScene", "isEpisode", "inputError", "message", "episode", "emptyContext", "fs", "path", "isObj", "isArr", "list", "speakerLabel", "doc", "http", "fs", "path", "spawn", "strOf", "root", "only", "arr", "text", "resolve", "spawn", "strOf", "pad", "path", "text", "path", "message", "report", "issues", "issues", "report", "fs", "path", "episode", "step", "text", "path", "path", "record", "request", "spec", "path", "validate", "request", "cached", "record", "step", "leaves", "value", "episode", "episodeNumber", "text", "group", "parcel", "issues", "report", "ref", "assetName", "content", "nameKey", "name", "fs", "text", "exists", "client", "result", "state", "llm", "state", "llm", "text", "message"]
|
|
7
|
+
}
|