@lingjingai/scriptctl 0.62.0 → 0.62.1
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.62.1.md +15 -0
- package/dist/bin.js +70 -0
- package/dist/bin.js.map +4 -4
- package/dist/cli/register-script.js +12 -0
- package/dist/cli/register-script.js.map +1 -1
- package/dist/review-agent.js +83 -0
- package/dist/review-agent.js.map +4 -4
- package/package.json +1 -1
- package/skills/scriptctl/SKILL.md +9 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 0.62.1
|
|
2
|
+
|
|
3
|
+
## Added
|
|
4
|
+
- `scriptctl refs` and `sc refs` locate asset and appearance references with scene/action addresses, surrounding text, and pagination. Explicit scene bindings, speakers, and textual mentions are reported separately; mentions do not imply presence or a particular appearance.
|
|
5
|
+
- The screenplay SDK exports read-only `references` and `formatReferences`, shared by the CLI and review agents.
|
|
6
|
+
- The Mastra screenplay review agent exposes `refs` during both episode review and whole-series convergence, querying the current in-memory document after edits.
|
|
7
|
+
|
|
8
|
+
## Changed
|
|
9
|
+
- Review instructions and the packaged scriptctl skill document reference lookup and distinguish read-only `refs` from the binding mutation `ref`.
|
|
10
|
+
|
|
11
|
+
## Fixed
|
|
12
|
+
- None.
|
|
13
|
+
|
|
14
|
+
## Breaking
|
|
15
|
+
- None.
|
package/dist/bin.js
CHANGED
|
@@ -4552,6 +4552,67 @@ function spanAddresses(doc2, actions) {
|
|
|
4552
4552
|
});
|
|
4553
4553
|
}
|
|
4554
4554
|
|
|
4555
|
+
// packages/screenplay/dist/references.js
|
|
4556
|
+
function references(doc2, address, opts = {}) {
|
|
4557
|
+
const offset = opts.offset ?? 0, limit = opts.limit ?? 20, context = opts.context ?? 3;
|
|
4558
|
+
for (const [name, value, minimum] of [["offset", offset, 0], ["limit", limit, 1], ["context", context, 0]]) {
|
|
4559
|
+
if (!Number.isSafeInteger(value) || value < minimum)
|
|
4560
|
+
throw new Error(`${name} must be an integer >= ${minimum}`);
|
|
4561
|
+
}
|
|
4562
|
+
const node = resolve6(doc2, address);
|
|
4563
|
+
if (node.t !== "asset" && node.t !== "state")
|
|
4564
|
+
throw new Error("references requires an asset or asset/state address; use read for episodes/scenes/actions");
|
|
4565
|
+
const asset2 = node.asset;
|
|
4566
|
+
const state2 = node.t === "state" ? node.state.id : null;
|
|
4567
|
+
const names = [.../* @__PURE__ */ new Set([asset2.id, asset2.name, ...asset2.aliases])].filter(Boolean);
|
|
4568
|
+
const hits = [];
|
|
4569
|
+
for (const ep of doc2.episodes)
|
|
4570
|
+
for (const scene of ep.scenes) {
|
|
4571
|
+
const bindings = [...scene.location ? [scene.location] : [], ...scene.actors, ...scene.props].filter((ref2) => ref2.id === asset2.id && (state2 === null || ref2.states.includes(state2)));
|
|
4572
|
+
if (bindings.length)
|
|
4573
|
+
hits.push({ kind: "scene_binding", scene, matched: bindings.flatMap((ref2) => ref2.states) });
|
|
4574
|
+
for (const action of scene.actions) {
|
|
4575
|
+
if (action.speaker?.id === asset2.id && (state2 === null || action.speaker.state === state2)) {
|
|
4576
|
+
hits.push({ kind: "speaker", scene, action, matched: [asset2.id] });
|
|
4577
|
+
}
|
|
4578
|
+
if (state2 === null) {
|
|
4579
|
+
const matched = names.filter((name) => action.content.includes(name));
|
|
4580
|
+
if (matched.length)
|
|
4581
|
+
hits.push({ kind: "text_mention", scene, action, matched });
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
}
|
|
4585
|
+
const end = offset + limit;
|
|
4586
|
+
return {
|
|
4587
|
+
asset_id: asset2.id,
|
|
4588
|
+
state_id: state2,
|
|
4589
|
+
total: hits.length,
|
|
4590
|
+
next_offset: end < hits.length ? end : null,
|
|
4591
|
+
items: hits.slice(offset, end).map(({ kind, scene, action, matched }) => {
|
|
4592
|
+
const index = action ? scene.actions.indexOf(action) : -1;
|
|
4593
|
+
const nearby = action ? scene.actions.slice(Math.max(0, index - context), index + context + 1) : [];
|
|
4594
|
+
const gutter = Math.max(0, ...nearby.map((row) => row.anchor.length));
|
|
4595
|
+
return {
|
|
4596
|
+
kind,
|
|
4597
|
+
address: action?.anchor ?? scene.anchor,
|
|
4598
|
+
scene_address: scene.anchor,
|
|
4599
|
+
episode: scene.ep.no,
|
|
4600
|
+
matched,
|
|
4601
|
+
text: [formatSceneHead(doc2, scene), ...nearby.map((row) => (row === action ? "> " : " ") + formatAction(doc2, row, gutter))].join("\n")
|
|
4602
|
+
};
|
|
4603
|
+
})
|
|
4604
|
+
};
|
|
4605
|
+
}
|
|
4606
|
+
function formatReferences(result) {
|
|
4607
|
+
return [
|
|
4608
|
+
`${result.asset_id}${result.state_id === null ? "" : "/" + result.state_id} ${result.total} references \xB7 showing ${result.items.length}`,
|
|
4609
|
+
"scene_binding=explicit scene presence; speaker=explicit speaker; text_mention=name/alias mention only (not proof of presence).",
|
|
4610
|
+
...result.items.map((hit) => `${hit.address} ${hit.kind} ep=${hit.episode}
|
|
4611
|
+
${hit.text}`),
|
|
4612
|
+
result.next_offset === null ? "end" : `Continue: --offset ${result.next_offset}`
|
|
4613
|
+
].join("\n\n");
|
|
4614
|
+
}
|
|
4615
|
+
|
|
4555
4616
|
// packages/screenplay/dist/tools.js
|
|
4556
4617
|
var NON_ACTOR_NAMES = ["\u65C1\u767D", "\u5E7F\u64AD", "\u753B\u5916", "\u7FA4\u58F0"];
|
|
4557
4618
|
var NON_ACTOR_KIND = {
|
|
@@ -5679,6 +5740,15 @@ ${issues(d, {})}`
|
|
|
5679
5740
|
...opts["full"] ? { full: true } : {}
|
|
5680
5741
|
}), "find"), state2));
|
|
5681
5742
|
describeArguments(find2, ["\u6B63\u5219\uFF1B\u53EA\u6309 speaker/type \u8FC7\u6EE4\u65F6\u53EF\u7701\u7565"]);
|
|
5743
|
+
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) => {
|
|
5744
|
+
const result = references(doc(opts), arg(opts), {
|
|
5745
|
+
offset: num(opts, "offset"),
|
|
5746
|
+
limit: num(opts, "limit"),
|
|
5747
|
+
context: num(opts, "context")
|
|
5748
|
+
});
|
|
5749
|
+
return [{ text: formatReferences(result), data: { op: "refs", changed: false, ...result } }, EXIT_OK];
|
|
5750
|
+
}, state2));
|
|
5751
|
+
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"]);
|
|
5682
5752
|
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));
|
|
5683
5753
|
describeArguments(span2, [`${ADDR}\uFF0C\u6216 \`\u8D77ID..\u6B62ID\``]);
|
|
5684
5754
|
withScriptOpts(program.command("validate"), "read").description("\u8DD1\u6574\u672C\u6821\u9A8C").action(dispatch((opts) => text(() => validate(doc(opts)), "validate"), state2));
|