@lingjingai/scriptctl 0.62.2 → 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.
- package/changes/0.62.3.md +4 -0
- package/changes/0.62.4.md +5 -0
- package/dist/bin.js +66 -86
- package/dist/bin.js.map +4 -4
- package/dist/cli/register-review.js +1 -0
- package/dist/cli/register-review.js.map +1 -1
- package/dist/cli/register-script.js +0 -12
- package/dist/cli/register-script.js.map +1 -1
- package/dist/infra/llm/doubao-model.d.ts +60 -0
- package/dist/infra/llm/doubao-model.js +250 -0
- package/dist/infra/llm/doubao-model.js.map +1 -0
- package/dist/infra/llm/doubao-video-model.js +2 -2
- package/dist/infra/llm/doubao-video-model.js.map +1 -1
- package/dist/llm/router.d.ts +5 -2
- package/dist/llm/router.js +26 -8
- package/dist/llm/router.js.map +1 -1
- package/dist/output.js +3 -5
- package/dist/output.js.map +1 -1
- package/dist/review-agent.js +4 -85
- package/dist/review-agent.js.map +4 -4
- package/dist/usecases/script/review.js +1 -0
- package/dist/usecases/script/review.js.map +1 -1
- package/package.json +15 -15
- package/skills/scriptctl/SKILL.md +1 -9
- package/skills/scriptctl/references/ingest-workflow.md +2 -2
- package/changes/0.62.1.md +0 -15
- package/changes/0.62.2.md +0 -3
package/dist/bin.js
CHANGED
|
@@ -1043,7 +1043,7 @@ var AnthropicModel = class {
|
|
|
1043
1043
|
}
|
|
1044
1044
|
};
|
|
1045
1045
|
|
|
1046
|
-
// src/infra/llm/doubao-
|
|
1046
|
+
// src/infra/llm/doubao-model.ts
|
|
1047
1047
|
import * as fs7 from "node:fs";
|
|
1048
1048
|
import * as path7 from "node:path";
|
|
1049
1049
|
import { File } from "node:buffer";
|
|
@@ -1173,7 +1173,7 @@ function httpError(status, message2, detail, context = {}) {
|
|
|
1173
1173
|
});
|
|
1174
1174
|
}
|
|
1175
1175
|
|
|
1176
|
-
// src/infra/llm/doubao-
|
|
1176
|
+
// src/infra/llm/doubao-model.ts
|
|
1177
1177
|
var POLL_INTERVAL_MS = 2e3;
|
|
1178
1178
|
function delay2(ms) {
|
|
1179
1179
|
return new Promise((resolve19) => setTimeout(resolve19, ms));
|
|
@@ -1203,7 +1203,7 @@ function extractText(res) {
|
|
|
1203
1203
|
}
|
|
1204
1204
|
return parts.join("").trim();
|
|
1205
1205
|
}
|
|
1206
|
-
var
|
|
1206
|
+
var DoubaoModel = class {
|
|
1207
1207
|
constructor(model, timeoutMs, maxAttempts, apiKey, baseUrl, client) {
|
|
1208
1208
|
this.model = model;
|
|
1209
1209
|
this.timeoutMs = timeoutMs;
|
|
@@ -1278,12 +1278,45 @@ var DoubaoVideoModel = class {
|
|
|
1278
1278
|
if (request2.responseJsonSchema) {
|
|
1279
1279
|
params["text"] = { format: { type: "json_schema", name: "video_serial", schema: request2.responseJsonSchema } };
|
|
1280
1280
|
}
|
|
1281
|
+
return this.generateResponse(params, request2.signal, Boolean(request2.responseJsonSchema));
|
|
1282
|
+
}
|
|
1283
|
+
async generateText(request2) {
|
|
1284
|
+
const params = this.textParams(request2);
|
|
1285
|
+
if (request2.responseFormat) params["text"] = { format: { type: request2.responseFormat } };
|
|
1286
|
+
return this.generateResponse(params, request2.signal, Boolean(request2.responseFormat));
|
|
1287
|
+
}
|
|
1288
|
+
async generateTool(request2) {
|
|
1289
|
+
const params = this.textParams(request2);
|
|
1290
|
+
params["text"] = { format: {
|
|
1291
|
+
type: "json_schema",
|
|
1292
|
+
name: request2.tool.name,
|
|
1293
|
+
description: request2.tool.description,
|
|
1294
|
+
schema: request2.tool.inputSchema
|
|
1295
|
+
} };
|
|
1296
|
+
const response = await this.generateResponse(params, request2.signal, true);
|
|
1297
|
+
return {
|
|
1298
|
+
input: JSON.parse(response.text),
|
|
1299
|
+
finishReason: response.finishReason,
|
|
1300
|
+
attempts: response.attempts,
|
|
1301
|
+
usage: response.usage,
|
|
1302
|
+
raw: response.raw
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
textParams(request2) {
|
|
1306
|
+
return {
|
|
1307
|
+
model: this.model,
|
|
1308
|
+
max_output_tokens: request2.maxOutputTokens,
|
|
1309
|
+
instructions: request2.system,
|
|
1310
|
+
input: [{ role: "user", content: [{ type: "input_text", text: request2.user }] }]
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
async generateResponse(params, signal, structured) {
|
|
1281
1314
|
const { value, attempts, failedUsage } = await withTransientRetry(this.maxAttempts, async () => {
|
|
1282
1315
|
let res;
|
|
1283
1316
|
try {
|
|
1284
|
-
res = await this.client.createResponse(params,
|
|
1317
|
+
res = await this.client.createResponse(params, signal);
|
|
1285
1318
|
} catch (error) {
|
|
1286
|
-
throw toArkError(error,
|
|
1319
|
+
throw toArkError(error, signal, "generate", this.model);
|
|
1287
1320
|
}
|
|
1288
1321
|
const status = (res.status ?? "").toLowerCase();
|
|
1289
1322
|
const usage = arkUsage(res.usage);
|
|
@@ -1294,11 +1327,11 @@ var DoubaoVideoModel = class {
|
|
|
1294
1327
|
}
|
|
1295
1328
|
const text2 = extractText(res);
|
|
1296
1329
|
if (!text2) throw new LlmTransportError("empty_response", "Doubao returned an empty response.", { retryable: true, usage });
|
|
1297
|
-
if (
|
|
1330
|
+
if (structured) {
|
|
1298
1331
|
try {
|
|
1299
1332
|
JSON.parse(text2);
|
|
1300
1333
|
} catch {
|
|
1301
|
-
throw new LlmTransportError("invalid_response", "Doubao returned malformed JSON for a structured
|
|
1334
|
+
throw new LlmTransportError("invalid_response", "Doubao returned malformed JSON for a structured response.", {
|
|
1302
1335
|
retryable: true,
|
|
1303
1336
|
usage,
|
|
1304
1337
|
context: { provider: "doubao", model: this.model, operation: "generate" }
|
|
@@ -2457,6 +2490,12 @@ var ModelRouter = class {
|
|
|
2457
2490
|
// Resolve an explicit Doubao route or the default fallback; absent fallback credentials skip it.
|
|
2458
2491
|
// Overridable in tests to inject a fake Ark client.
|
|
2459
2492
|
doubaoAdapter(route) {
|
|
2493
|
+
return this.arkAdapter(route);
|
|
2494
|
+
}
|
|
2495
|
+
doubaoTextAdapter() {
|
|
2496
|
+
return this.arkAdapter();
|
|
2497
|
+
}
|
|
2498
|
+
arkAdapter(route) {
|
|
2460
2499
|
const apiKey = route ? this.videoCredential(route) : (process.env[DOUBAO_FALLBACK.apiKeyEnv] ?? "").trim();
|
|
2461
2500
|
if (!apiKey) return null;
|
|
2462
2501
|
const model = route?.info.model ?? this.doubaoModel();
|
|
@@ -2464,7 +2503,7 @@ var ModelRouter = class {
|
|
|
2464
2503
|
const key = `doubao ${baseUrl} ${model}`;
|
|
2465
2504
|
const cached2 = this.doubaoAdapters.get(key);
|
|
2466
2505
|
if (cached2) return cached2;
|
|
2467
|
-
const adapter = new
|
|
2506
|
+
const adapter = new DoubaoModel(model, DOUBAO_FALLBACK.timeoutMs, DOUBAO_FALLBACK.maxAttempts, apiKey, baseUrl);
|
|
2468
2507
|
this.doubaoAdapters.set(key, adapter);
|
|
2469
2508
|
return adapter;
|
|
2470
2509
|
}
|
|
@@ -2472,19 +2511,29 @@ var ModelRouter = class {
|
|
|
2472
2511
|
doubaoModel() {
|
|
2473
2512
|
return (process.env[DOUBAO_FALLBACK.modelEnv] ?? "").trim() || DOUBAO_FALLBACK.model;
|
|
2474
2513
|
}
|
|
2514
|
+
async withModerationFallback(task, signal, generate) {
|
|
2515
|
+
const route = this.resolve(task);
|
|
2516
|
+
const adapter = this.adapter(route);
|
|
2517
|
+
try {
|
|
2518
|
+
return await this.tracked(route.info, () => generate(adapter));
|
|
2519
|
+
} catch (error) {
|
|
2520
|
+
if (signal?.aborted || !(error instanceof LlmTransportError) || error.code !== "content_filtered") throw error;
|
|
2521
|
+
const doubao = this.doubaoTextAdapter();
|
|
2522
|
+
if (!doubao) throw error;
|
|
2523
|
+
process.stderr.write(`\u21AA\uFE0F \u6587\u672C\u5185\u5BB9\u5BA1\u6838\u62D2\u7EDD\uFF0C\u56DE\u9000\u5230\u8C46\u5305 ${this.doubaoModel()}
|
|
2524
|
+
`);
|
|
2525
|
+
return this.tracked(this.doubaoRoute(task), () => generate(doubao));
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2475
2528
|
async generateText(task, request2) {
|
|
2476
2529
|
const spec2 = LLM_TASK_REGISTRY[task];
|
|
2477
2530
|
if (spec2.mode !== "text") throw configRuntimeError("The task does not support text generation.", ["text task"], [`task: ${task}`]);
|
|
2478
|
-
|
|
2479
|
-
const adapter = this.adapter(route);
|
|
2480
|
-
return this.tracked(route.info, () => adapter.generateText({ ...request2, maxOutputTokens: spec2.maxOutputTokens }));
|
|
2531
|
+
return this.withModerationFallback(task, request2.signal, (adapter) => adapter.generateText({ ...request2, maxOutputTokens: spec2.maxOutputTokens }));
|
|
2481
2532
|
}
|
|
2482
2533
|
async generateTool(task, request2) {
|
|
2483
2534
|
const spec2 = LLM_TASK_REGISTRY[task];
|
|
2484
2535
|
if (spec2.mode !== "tool") throw configRuntimeError("The task does not support tool generation.", ["tool task"], [`task: ${task}`]);
|
|
2485
|
-
|
|
2486
|
-
const adapter = this.adapter(route);
|
|
2487
|
-
return this.tracked(route.info, () => adapter.generateTool({ ...request2, maxOutputTokens: spec2.maxOutputTokens }));
|
|
2536
|
+
return this.withModerationFallback(task, request2.signal, (adapter) => adapter.generateTool({ ...request2, maxOutputTokens: spec2.maxOutputTokens }));
|
|
2488
2537
|
}
|
|
2489
2538
|
};
|
|
2490
2539
|
function createLlmExecutor(explicitConfigPath, options) {
|
|
@@ -2956,6 +3005,7 @@ function tableText(data) {
|
|
|
2956
3005
|
].join("\n");
|
|
2957
3006
|
}
|
|
2958
3007
|
function emit(output, exitCode, jsonMode, format) {
|
|
3008
|
+
if (output.text === "" && Object.keys(output.data).length === 0) return;
|
|
2959
3009
|
if (format === "addr" && hasRows(output.data)) {
|
|
2960
3010
|
if (output.data.rows.length === 0) {
|
|
2961
3011
|
process.stdout.write("");
|
|
@@ -2977,7 +3027,6 @@ function emit(output, exitCode, jsonMode, format) {
|
|
|
2977
3027
|
payload["exit_code"] = exitCode;
|
|
2978
3028
|
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
2979
3029
|
} else {
|
|
2980
|
-
if (output.text === "" && Object.keys(output.data).length === 0) return;
|
|
2981
3030
|
process.stdout.write(withNewline(tableText(output.data) ?? output.text));
|
|
2982
3031
|
}
|
|
2983
3032
|
}
|
|
@@ -3216,6 +3265,7 @@ async function commandReview(opts) {
|
|
|
3216
3265
|
...episodeList(strOf(opts["episodes"])) ? { episodes: episodeList(strOf(opts["episodes"])) } : {},
|
|
3217
3266
|
concurrency: positive(opts, "concurrency", 5),
|
|
3218
3267
|
converge: opts["converge"] !== false,
|
|
3268
|
+
convergeOnly: opts["converge_only"] === true,
|
|
3219
3269
|
apiKey: profile.apiKey,
|
|
3220
3270
|
model: profile.model,
|
|
3221
3271
|
mediaModel: profile.model,
|
|
@@ -3244,7 +3294,7 @@ function registerReviewCommand(program, state2) {
|
|
|
3244
3294
|
"\u7B2C N \u96C6\u7684\u89C6\u9891\uFF1B\u6309\u96C6\u987A\u5E8F\u91CD\u590D\u4F20\uFF0C\u8986\u76D6 -s \u7684\u76EE\u5F55\u6392\u5E8F",
|
|
3245
3295
|
(value, previous) => [...previous, value],
|
|
3246
3296
|
[]
|
|
3247
|
-
).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));
|
|
3248
3298
|
}
|
|
3249
3299
|
|
|
3250
3300
|
// src/cli/register-script.ts
|
|
@@ -4552,67 +4602,6 @@ function spanAddresses(doc2, actions) {
|
|
|
4552
4602
|
});
|
|
4553
4603
|
}
|
|
4554
4604
|
|
|
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
|
-
|
|
4616
4605
|
// packages/screenplay/dist/tools.js
|
|
4617
4606
|
var NON_ACTOR_NAMES = ["\u65C1\u767D", "\u5E7F\u64AD", "\u753B\u5916", "\u7FA4\u58F0"];
|
|
4618
4607
|
var NON_ACTOR_KIND = {
|
|
@@ -5740,15 +5729,6 @@ ${issues(d, {})}`
|
|
|
5740
5729
|
...opts["full"] ? { full: true } : {}
|
|
5741
5730
|
}), "find"), state2));
|
|
5742
5731
|
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"]);
|
|
5752
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));
|
|
5753
5733
|
describeArguments(span2, [`${ADDR}\uFF0C\u6216 \`\u8D77ID..\u6B62ID\``]);
|
|
5754
5734
|
withScriptOpts(program.command("validate"), "read").description("\u8DD1\u6574\u672C\u6821\u9A8C").action(dispatch((opts) => text(() => validate(doc(opts)), "validate"), state2));
|