@lingjingai/scriptctl 0.62.3 → 0.62.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.
@@ -0,0 +1,5 @@
1
+ # 0.62.4
2
+
3
+ - `review --converge-only` 只运行全剧收敛,支持客户端保留已完成集后的续跑。
4
+ - 审核 NDJSON 增加 `unit-started` 事件,提供真实的分集与全剧阶段开始状态。
5
+ - 流式命令在 JSON 模式下直接结束,保持每行一个完整事件。
package/dist/bin.js CHANGED
@@ -3005,6 +3005,7 @@ function tableText(data) {
3005
3005
  ].join("\n");
3006
3006
  }
3007
3007
  function emit(output, exitCode, jsonMode, format) {
3008
+ if (output.text === "" && Object.keys(output.data).length === 0) return;
3008
3009
  if (format === "addr" && hasRows(output.data)) {
3009
3010
  if (output.data.rows.length === 0) {
3010
3011
  process.stdout.write("");
@@ -3026,7 +3027,6 @@ function emit(output, exitCode, jsonMode, format) {
3026
3027
  payload["exit_code"] = exitCode;
3027
3028
  process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
3028
3029
  } else {
3029
- if (output.text === "" && Object.keys(output.data).length === 0) return;
3030
3030
  process.stdout.write(withNewline(tableText(output.data) ?? output.text));
3031
3031
  }
3032
3032
  }
@@ -3265,6 +3265,7 @@ async function commandReview(opts) {
3265
3265
  ...episodeList(strOf(opts["episodes"])) ? { episodes: episodeList(strOf(opts["episodes"])) } : {},
3266
3266
  concurrency: positive(opts, "concurrency", 5),
3267
3267
  converge: opts["converge"] !== false,
3268
+ convergeOnly: opts["converge_only"] === true,
3268
3269
  apiKey: profile.apiKey,
3269
3270
  model: profile.model,
3270
3271
  mediaModel: profile.model,
@@ -3293,7 +3294,7 @@ function registerReviewCommand(program, state2) {
3293
3294
  "\u7B2C N \u96C6\u7684\u89C6\u9891\uFF1B\u6309\u96C6\u987A\u5E8F\u91CD\u590D\u4F20\uFF0C\u8986\u76D6 -s \u7684\u76EE\u5F55\u6392\u5E8F",
3294
3295
  (value, previous) => [...previous, value],
3295
3296
  []
3296
- ).option("--episodes <list>", "\u53EA\u5BA1\u8FD9\u4E9B\u96C6\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u9ED8\u8BA4\u5168\u5267\uFF09").option("--concurrency <n>", "\u540C\u65F6\u5728\u98DE\u7684\u96C6\u6570", Number).option("--episode-timeout-ms <ms>", "\u5355\u96C6\u8D85\u65F6\uFF1B\u5230\u70B9\u6536\u5C3E\u5E76\u4FDD\u7559\u5DF2\u8BB0\u5F55\u7684\u7ED3\u8BBA", Number).option("--max-steps <n>", "\u5355\u96C6\u6700\u591A\u51E0\u6B65\u5DE5\u5177\u8C03\u7528", Number).option("--media-budget <n>", "\u5355\u96C6\u6700\u591A\u51E0\u6B21\u89C6\u9891\u6838\u5BF9", Number).option("--no-converge", "\u8DF3\u8FC7\u5168\u5267\u6536\u655B\u9636\u6BB5").option("--model <profile>", "\u8986\u76D6 LLM profile\uFF08\u9ED8\u8BA4 review-agent\uFF09").option("--llm-config <path>", "LLM configuration file").option("--check", "\u53EA\u68C0\u67E5\u6A21\u578B\u4E0E agent \u662F\u5426\u5C31\u7EEA\uFF0C\u4E0D\u5BA1\u6838").action(dispatch(commandReview, state2));
3297
+ ).option("--episodes <list>", "\u53EA\u5BA1\u8FD9\u4E9B\u96C6\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u9ED8\u8BA4\u5168\u5267\uFF09").option("--concurrency <n>", "\u540C\u65F6\u5728\u98DE\u7684\u96C6\u6570", Number).option("--episode-timeout-ms <ms>", "\u5355\u96C6\u8D85\u65F6\uFF1B\u5230\u70B9\u6536\u5C3E\u5E76\u4FDD\u7559\u5DF2\u8BB0\u5F55\u7684\u7ED3\u8BBA", Number).option("--max-steps <n>", "\u5355\u96C6\u6700\u591A\u51E0\u6B65\u5DE5\u5177\u8C03\u7528", Number).option("--media-budget <n>", "\u5355\u96C6\u6700\u591A\u51E0\u6B21\u89C6\u9891\u6838\u5BF9", Number).option("--converge-only", "\u53EA\u6267\u884C\u5168\u5267\u6536\u655B\uFF0C\u4E0D\u91CD\u65B0\u5BA1\u6838\u5404\u96C6").option("--no-converge", "\u8DF3\u8FC7\u5168\u5267\u6536\u655B\u9636\u6BB5").option("--model <profile>", "\u8986\u76D6 LLM profile\uFF08\u9ED8\u8BA4 review-agent\uFF09").option("--llm-config <path>", "LLM configuration file").option("--check", "\u53EA\u68C0\u67E5\u6A21\u578B\u4E0E agent \u662F\u5426\u5C31\u7EEA\uFF0C\u4E0D\u5BA1\u6838").action(dispatch(commandReview, state2));
3297
3298
  }
3298
3299
 
3299
3300
  // src/cli/register-script.ts
@@ -4601,67 +4602,6 @@ function spanAddresses(doc2, actions) {
4601
4602
  });
4602
4603
  }
4603
4604
 
4604
- // packages/screenplay/dist/references.js
4605
- function references(doc2, address, opts = {}) {
4606
- const offset = opts.offset ?? 0, limit = opts.limit ?? 20, context = opts.context ?? 3;
4607
- for (const [name, value, minimum] of [["offset", offset, 0], ["limit", limit, 1], ["context", context, 0]]) {
4608
- if (!Number.isSafeInteger(value) || value < minimum)
4609
- throw new Error(`${name} must be an integer >= ${minimum}`);
4610
- }
4611
- const node = resolve6(doc2, address);
4612
- if (node.t !== "asset" && node.t !== "state")
4613
- throw new Error("references requires an asset or asset/state address; use read for episodes/scenes/actions");
4614
- const asset2 = node.asset;
4615
- const state2 = node.t === "state" ? node.state.id : null;
4616
- const names = [.../* @__PURE__ */ new Set([asset2.id, asset2.name, ...asset2.aliases])].filter(Boolean);
4617
- const hits = [];
4618
- for (const ep of doc2.episodes)
4619
- for (const scene of ep.scenes) {
4620
- const bindings = [...scene.location ? [scene.location] : [], ...scene.actors, ...scene.props].filter((ref2) => ref2.id === asset2.id && (state2 === null || ref2.states.includes(state2)));
4621
- if (bindings.length)
4622
- hits.push({ kind: "scene_binding", scene, matched: bindings.flatMap((ref2) => ref2.states) });
4623
- for (const action of scene.actions) {
4624
- if (action.speaker?.id === asset2.id && (state2 === null || action.speaker.state === state2)) {
4625
- hits.push({ kind: "speaker", scene, action, matched: [asset2.id] });
4626
- }
4627
- if (state2 === null) {
4628
- const matched = names.filter((name) => action.content.includes(name));
4629
- if (matched.length)
4630
- hits.push({ kind: "text_mention", scene, action, matched });
4631
- }
4632
- }
4633
- }
4634
- const end = offset + limit;
4635
- return {
4636
- asset_id: asset2.id,
4637
- state_id: state2,
4638
- total: hits.length,
4639
- next_offset: end < hits.length ? end : null,
4640
- items: hits.slice(offset, end).map(({ kind, scene, action, matched }) => {
4641
- const index = action ? scene.actions.indexOf(action) : -1;
4642
- const nearby = action ? scene.actions.slice(Math.max(0, index - context), index + context + 1) : [];
4643
- const gutter = Math.max(0, ...nearby.map((row) => row.anchor.length));
4644
- return {
4645
- kind,
4646
- address: action?.anchor ?? scene.anchor,
4647
- scene_address: scene.anchor,
4648
- episode: scene.ep.no,
4649
- matched,
4650
- text: [formatSceneHead(doc2, scene), ...nearby.map((row) => (row === action ? "> " : " ") + formatAction(doc2, row, gutter))].join("\n")
4651
- };
4652
- })
4653
- };
4654
- }
4655
- function formatReferences(result) {
4656
- return [
4657
- `${result.asset_id}${result.state_id === null ? "" : "/" + result.state_id} ${result.total} references \xB7 showing ${result.items.length}`,
4658
- "scene_binding=explicit scene presence; speaker=explicit speaker; text_mention=name/alias mention only (not proof of presence).",
4659
- ...result.items.map((hit) => `${hit.address} ${hit.kind} ep=${hit.episode}
4660
- ${hit.text}`),
4661
- result.next_offset === null ? "end" : `Continue: --offset ${result.next_offset}`
4662
- ].join("\n\n");
4663
- }
4664
-
4665
4605
  // packages/screenplay/dist/tools.js
4666
4606
  var NON_ACTOR_NAMES = ["\u65C1\u767D", "\u5E7F\u64AD", "\u753B\u5916", "\u7FA4\u58F0"];
4667
4607
  var NON_ACTOR_KIND = {
@@ -5789,15 +5729,6 @@ ${issues(d, {})}`
5789
5729
  ...opts["full"] ? { full: true } : {}
5790
5730
  }), "find"), state2));
5791
5731
  describeArguments(find2, ["\u6B63\u5219\uFF1B\u53EA\u6309 speaker/type \u8FC7\u6EE4\u65F6\u53EF\u7701\u7565"]);
5792
- const refs = withScriptOpts(program.command("refs <addr>"), "read").description("\u53EA\u8BFB\u5B9A\u4F4D\u8D44\u4EA7/\u9020\u578B\u7684\u573A\u666F\u7ED1\u5B9A\u3001\u8BF4\u8BDD\u5F15\u7528\u548C\u6B63\u6587\u63D0\u53CA\uFF0C\u8FD4\u56DE\u53EF read \u7684\u5730\u5740\u53CA\u4E0A\u4E0B\u6587").option("--offset <n>", "\u4ECE\u7B2C\u51E0\u6761\u5F15\u7528\u7EE7\u7EED\uFF08\u4ECE 0 \u5F00\u59CB\uFF09").option("--limit <n>", "\u672C\u6279\u5F15\u7528\u6570\uFF08\u9ED8\u8BA4 20\uFF09").option("--context <n>", "\u6B63\u6587\u547D\u4E2D\u524D\u540E\u5404\u51E0\u6761 action\uFF08\u9ED8\u8BA4 3\uFF09").action(dispatch((opts) => {
5793
- const result = references(doc(opts), arg(opts), {
5794
- offset: num(opts, "offset"),
5795
- limit: num(opts, "limit"),
5796
- context: num(opts, "context")
5797
- });
5798
- return [{ text: formatReferences(result), data: { op: "refs", changed: false, ...result } }, EXIT_OK];
5799
- }, state2));
5800
- describeArguments(refs, ["\u4EBA\u7269/\u573A\u666F/\u9053\u5177 ID \u6216\u540D\u79F0\uFF0C\u6216 <\u8D44\u4EA7>/<\u9020\u578B>\uFF1B\u6B63\u6587\u63D0\u53CA\u4E0D\u7B49\u4E8E\u5B9E\u9645\u51FA\u573A"]);
5801
5732
  const span2 = withScriptOpts(program.command("span <range>"), "read").description("\u628A\u4E00\u6BB5 action \u6362\u7B97\u6210\u96C6\u5185\u89C6\u9891\u65F6\u95F4\u7A97\u53E3\uFF08\u534A\u5F00\u533A\u95F4\uFF09").action(dispatch((opts) => text(() => span(doc(opts), arg(opts)), "span"), state2));
5802
5733
  describeArguments(span2, [`${ADDR}\uFF0C\u6216 \`\u8D77ID..\u6B62ID\``]);
5803
5734
  withScriptOpts(program.command("validate"), "read").description("\u8DD1\u6574\u672C\u6821\u9A8C").action(dispatch((opts) => text(() => validate(doc(opts)), "validate"), state2));