@lingjingai/scriptctl 0.10.3 → 0.10.4

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.
@@ -15,7 +15,6 @@ export declare function findScene(script: Dict, epId: string, sceneId: string):
15
15
  export declare function validateScript(workspace: string, scriptPath?: string | null, opts?: {
16
16
  requireSource?: boolean;
17
17
  scriptData?: Dict;
18
- persist?: boolean;
19
18
  }): Dict;
20
19
  export declare function assetKeys(assetType: string): [string, string, string];
21
20
  export declare function ensureRefId(script: Dict, assetType: string, rawId: unknown, opts?: {
@@ -84,7 +84,7 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
84
84
  exitCode: EXIT_INPUT,
85
85
  required: ["workspace/source.txt"],
86
86
  received: [sourcePath],
87
- nextSteps: ["Run scriptctl import init first."],
87
+ nextSteps: ["Run scriptctl direct init first."],
88
88
  });
89
89
  }
90
90
  if (exists(sourcePath))
@@ -98,9 +98,9 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
98
98
  if (!exists(finalScriptPath)) {
99
99
  throw new CliError("VALIDATE BLOCKED: script not found", "Script JSON not found.", {
100
100
  exitCode: EXIT_INPUT,
101
- required: ["script.initial.json"],
101
+ required: ["script.initial.json or --script-path"],
102
102
  received: [finalScriptPath],
103
- nextSteps: ["Run scriptctl import init first."],
103
+ nextSteps: ["Run scriptctl direct init first."],
104
104
  });
105
105
  }
106
106
  try {
@@ -116,13 +116,8 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
116
116
  }
117
117
  }
118
118
  const issues = [];
119
- // LOW_CONFIDENCE_METADATA reflects the local parse artifact (asset_metadata.json
120
- // describes script.initial.json). It is only meaningful when validating that
121
- // local script. When validating an in-memory script (scriptData) — i.e. the
122
- // DB-backed final script after `import push` — the local metadata file is
123
- // unrelated, so skip the check to avoid a permanent spurious error on the DB.
124
119
  const metadataPath = path.join(dd, "asset_metadata.json");
125
- if (opts.scriptData === undefined && exists(metadataPath)) {
120
+ if (exists(metadataPath)) {
126
121
  let metadata = {};
127
122
  try {
128
123
  metadata = readJson(metadataPath);
@@ -131,15 +126,11 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
131
126
  metadata = {};
132
127
  }
133
128
  if (isDict(metadata) && metadata["confidence"] === "low") {
134
- // Advisory (warning, not error): this is a parse-time confidence signal on
135
- // the initial extraction, surfaced once in push's validation.json for the
136
- // review subagent to double-check. It is not a clearable gate — DB edits
137
- // don't touch this local artifact — so it must not fail `passed`.
138
129
  issues.push({
139
130
  code: "LOW_CONFIDENCE_METADATA",
140
- severity: "warning",
131
+ severity: "error",
141
132
  summary: "AI metadata confidence is low.",
142
- repair_hint: "Double-check worldview / role_type / descriptions during review.",
133
+ repair_hint: "Inspect assets and patch worldview, role_type, or descriptions explicitly.",
143
134
  });
144
135
  }
145
136
  }
@@ -437,11 +428,8 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
437
428
  });
438
429
  }
439
430
  }
440
- // Same as LOW_CONFIDENCE_METADATA above: episode_plan.json is a local parse
441
- // artifact that only describes the local script.initial.json, so skip it when
442
- // validating an in-memory/DB script (scriptData).
443
431
  const planPath = path.join(dd, "episode_plan.json");
444
- if (opts.scriptData === undefined && exists(planPath)) {
432
+ if (exists(planPath)) {
445
433
  const plan = readJson(planPath);
446
434
  if (plan["boundary_confidence"] === "low") {
447
435
  issues.push({
@@ -459,24 +447,7 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
459
447
  let totalScenes = 0;
460
448
  let totalActions = 0;
461
449
  let lastSceneNum = 0;
462
- const episodeIds = new Set();
463
450
  for (const ep of episodes) {
464
- const epId = strOf(ep["episode_id"]);
465
- if (epId) {
466
- if (episodeIds.has(epId)) {
467
- // Duplicate episode_id is a hard structural error: the script-output DB
468
- // enforces a unique (project_group_no, episode_uid) constraint, so a push
469
- // would crash with a duplicate-key error. Surface it here instead.
470
- issues.push({
471
- code: "DUPLICATE_EPISODE_ID",
472
- severity: "error",
473
- episode: epId,
474
- summary: `Duplicate episode_id: ${epId}`,
475
- repair_hint: "Renumber/rename so every episode_id is unique (rerun import init, or patch the episode).",
476
- });
477
- }
478
- episodeIds.add(epId);
479
- }
480
451
  const epTitle = strOf(ep["title"]).trim();
481
452
  if (!epTitle || isTechnicalEpisodeTitle(epTitle)) {
482
453
  issues.push({
@@ -484,7 +455,7 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
484
455
  severity: "warning",
485
456
  episode: ep["episode_id"],
486
457
  summary: `Episode title is missing or technical: ${epTitle || "<empty>"}`,
487
- repair_hint: 'Rerun `import init` to regenerate, or `script patch episode <episode_id> --field title --value "第N集:短标题"`.',
458
+ repair_hint: 'Rerun `direct init` to regenerate, or `script patch episode <episode_id> --field title --value "第N集:短标题"`.',
488
459
  });
489
460
  }
490
461
  const scenes = asList(ep["scenes"]);
@@ -933,10 +904,7 @@ export function validateScript(workspace, scriptPath = null, opts = {}) {
933
904
  script_path: opts.scriptData !== undefined ? "<in-memory>" : (scriptPath ?? path.join(dd, "script.initial.json")),
934
905
  validated_at: new Date().toISOString().replace(/\.\d+Z$/, "Z"),
935
906
  };
936
- // persist defaults true. Callers that own the write (validateSession sets a
937
- // nicer script_path label) or want no side effect (patch --dry-run) pass false.
938
- if (opts.persist !== false)
939
- writeJson(path.join(dd, "validation.json"), validation);
907
+ writeJson(path.join(dd, "validation.json"), validation);
940
908
  return validation;
941
909
  }
942
910
  // ---------------------------------------------------------------------------