@lingjingai/scriptctl 0.13.0 → 0.15.0
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/dist/cli.js +26 -49
- package/dist/cli.js.map +1 -1
- package/dist/common.d.ts +1 -1
- package/dist/common.js +1 -1
- package/dist/domain/script-core.d.ts +15 -0
- package/dist/domain/script-core.js +207 -63
- package/dist/domain/script-core.js.map +1 -1
- package/dist/help-text.js +31 -315
- package/dist/help-text.js.map +1 -1
- package/dist/infra/providers.d.ts +0 -36
- package/dist/infra/providers.js +6 -211
- package/dist/infra/providers.js.map +1 -1
- package/dist/usecases/direct.js +3 -4
- package/dist/usecases/direct.js.map +1 -1
- package/dist/usecases/doctor.js +2 -5
- package/dist/usecases/doctor.js.map +1 -1
- package/dist/usecases/script.d.ts +5 -0
- package/dist/usecases/script.js +172 -5
- package/dist/usecases/script.js.map +1 -1
- package/package.json +2 -3
- package/dist/domain/asset-registry.d.ts +0 -141
- package/dist/domain/asset-registry.js +0 -318
- package/dist/domain/asset-registry.js.map +0 -1
- package/dist/domain/collision-detector.d.ts +0 -83
- package/dist/domain/collision-detector.js +0 -248
- package/dist/domain/collision-detector.js.map +0 -1
- package/dist/infra/default-writing-prompt.d.ts +0 -31
- package/dist/infra/default-writing-prompt.js +0 -50
- package/dist/infra/default-writing-prompt.js.map +0 -1
- package/dist/infra/default-writing-prompt.md +0 -115
- package/dist/infra/gemini-writer.d.ts +0 -107
- package/dist/infra/gemini-writer.js +0 -207
- package/dist/infra/gemini-writer.js.map +0 -1
- package/dist/usecases/episode.d.ts +0 -48
- package/dist/usecases/episode.js +0 -1242
- package/dist/usecases/episode.js.map +0 -1
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Episode drafting via configured provider.
|
|
3
|
-
*
|
|
4
|
-
* `gemini-writer` is the bridge between scriptctl's `episode draft` orchestrator and
|
|
5
|
-
* the underlying provider. It does two things:
|
|
6
|
-
*
|
|
7
|
-
* 1. **Context assembly** — takes an agent-supplied list of reference files
|
|
8
|
-
* (`refs: [{title, path}, ...]`) plus the per-episode outline, reads them off
|
|
9
|
-
* disk, and composes a single prompt string conforming to the writing-prompt
|
|
10
|
-
* template. scriptctl itself knows nothing about anchor.md / analysis-workspace /
|
|
11
|
-
* adaptation-workspace etc. — those names belong to whichever SKILL is calling.
|
|
12
|
-
* 2. **Provider invocation** — calls `provider.complete(prompt)` and returns raw
|
|
13
|
-
* markdown for downstream parsing.
|
|
14
|
-
*
|
|
15
|
-
* The only files scriptctl looks up *automatically* are inside its own writing
|
|
16
|
-
* directory (`<workspace>/episodes/`): the per-episode outline (when default
|
|
17
|
-
* template is used) and the previous episode's body (for style continuity).
|
|
18
|
-
* Everything else must be passed in via `refs`.
|
|
19
|
-
*/
|
|
20
|
-
import * as fs from "node:fs";
|
|
21
|
-
import * as path from "node:path";
|
|
22
|
-
import { DEFAULT_BATCH_MAX_TOKENS, exists, readText } from "../common.js";
|
|
23
|
-
import { summarizeForPrompt } from "../domain/asset-registry.js";
|
|
24
|
-
/** Tail of the previous episode's body to inject for style/hook continuity. */
|
|
25
|
-
const PREV_EPISODE_TAIL_CHARS = 12_000;
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
// Template resolution
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
/**
|
|
30
|
-
* Substitute `{NN}` placeholder in a path template with the given 2-digit-padded
|
|
31
|
-
* episode number. `{NN}` is the only form scriptctl uses anywhere.
|
|
32
|
-
*/
|
|
33
|
-
export function resolveTemplate(template, episode) {
|
|
34
|
-
return template.replace(/\{NN\}/g, String(episode).padStart(2, "0"));
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Parse one `--ref "<title>=<path>"` CLI argument into a RefDeclaration. The agent
|
|
38
|
-
* passes labels in the same language they want them to appear in the prompt; the
|
|
39
|
-
* label becomes the `## <label>` heading in the assembled prompt.
|
|
40
|
-
*/
|
|
41
|
-
export function parseRefArg(raw) {
|
|
42
|
-
const idx = raw.indexOf("=");
|
|
43
|
-
if (idx <= 0 || idx === raw.length - 1) {
|
|
44
|
-
throw new Error(`invalid --ref format: "${raw}". Expected "<title>=<path>", e.g. --ref "全局设定=analysis-workspace/全局设定.md".`);
|
|
45
|
-
}
|
|
46
|
-
const title = raw.slice(0, idx).trim();
|
|
47
|
-
const path = raw.slice(idx + 1).trim();
|
|
48
|
-
if (!title || !path) {
|
|
49
|
-
throw new Error(`invalid --ref format: "${raw}". Both title and path must be non-empty.`);
|
|
50
|
-
}
|
|
51
|
-
return { title, path };
|
|
52
|
-
}
|
|
53
|
-
/** Dedupe a list of refs by title; later entries win. */
|
|
54
|
-
export function dedupeRefs(refs) {
|
|
55
|
-
const seen = new Map();
|
|
56
|
-
for (const ref of refs)
|
|
57
|
-
seen.set(ref.title, ref);
|
|
58
|
-
return [...seen.values()];
|
|
59
|
-
}
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
// Prompt composition
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
/**
|
|
64
|
-
* Strip control characters / heading-level markers from agent-supplied titles so
|
|
65
|
-
* a malformed `--ref "Title\n# Something=path"` can't escape the prompt structure.
|
|
66
|
-
*/
|
|
67
|
-
function sanitizeTitle(raw) {
|
|
68
|
-
return raw.replace(/[\r\n]/g, " ").replace(/[`]/g, "").replace(/^#+\s*/, "").trim() || "未命名段";
|
|
69
|
-
}
|
|
70
|
-
function renderBlocks(blocks) {
|
|
71
|
-
if (blocks.length === 0)
|
|
72
|
-
return "(暂无参考资料)";
|
|
73
|
-
return blocks.map((b) => `## ${sanitizeTitle(b.title)}\n\n${b.body.trim()}\n`).join("\n");
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Assemble the full prompt for one `episode draft` call.
|
|
77
|
-
*
|
|
78
|
-
* Sections (in order):
|
|
79
|
-
* 1. The writing-prompt template (output format + creative rules)
|
|
80
|
-
* 2. 已存在资产清单 (collision prevention — auto from scriptctl-owned registry)
|
|
81
|
-
* 3. Agent-supplied reference blocks (anchor / setup / adaptation plan / ...)
|
|
82
|
-
* 4. **当前集集纲** (the episode-specific outline, REQUIRED)
|
|
83
|
-
* 5. Optional parser feedback (when retrying after a failed parse)
|
|
84
|
-
* 6. Footer reminder
|
|
85
|
-
*/
|
|
86
|
-
export function composePrompt(req) {
|
|
87
|
-
const sections = [];
|
|
88
|
-
sections.push(req.promptTemplate.trim());
|
|
89
|
-
sections.push("");
|
|
90
|
-
sections.push("---");
|
|
91
|
-
sections.push("");
|
|
92
|
-
const registrySummary = summarizeForPrompt(req.registry);
|
|
93
|
-
if (registrySummary) {
|
|
94
|
-
sections.push(registrySummary);
|
|
95
|
-
sections.push("");
|
|
96
|
-
sections.push("---");
|
|
97
|
-
sections.push("");
|
|
98
|
-
}
|
|
99
|
-
sections.push("# 项目上下文");
|
|
100
|
-
sections.push("");
|
|
101
|
-
const blocks = [...req.context.refBlocks];
|
|
102
|
-
if (req.context.previousEpisodeBody) {
|
|
103
|
-
blocks.push({
|
|
104
|
-
title: "上一集已生成正文(用于风格 / 钩子衔接)",
|
|
105
|
-
body: req.context.previousEpisodeBody,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
sections.push(renderBlocks(blocks));
|
|
109
|
-
sections.push("");
|
|
110
|
-
sections.push("---");
|
|
111
|
-
sections.push("");
|
|
112
|
-
sections.push(`# 当前集集纲(第 ${req.episode} 集)`);
|
|
113
|
-
sections.push("");
|
|
114
|
-
sections.push(req.context.outlineText.trim());
|
|
115
|
-
sections.push("");
|
|
116
|
-
sections.push("---");
|
|
117
|
-
sections.push("");
|
|
118
|
-
if (req.parserErrorFeedback) {
|
|
119
|
-
sections.push("# 上一次输出失败的原因(请这次修复后重新输出,避免重复错误)");
|
|
120
|
-
sections.push("");
|
|
121
|
-
sections.push("```");
|
|
122
|
-
sections.push(req.parserErrorFeedback.trim());
|
|
123
|
-
sections.push("```");
|
|
124
|
-
sections.push("");
|
|
125
|
-
sections.push("---");
|
|
126
|
-
sections.push("");
|
|
127
|
-
}
|
|
128
|
-
sections.push(`# 任务:按上面"输出格式(scriptctl spec markdown,硬约束)"的规则,输出第 ${req.episode} 集的剧本片段。`);
|
|
129
|
-
sections.push("");
|
|
130
|
-
sections.push("再次提醒:");
|
|
131
|
-
sections.push("- 直接以 `# 剧本` 开头,**不要**用 ``` 围栏包裹");
|
|
132
|
-
sections.push("- 不要写 `第X集:副标题` 等首行标题");
|
|
133
|
-
sections.push("- 资产段只列**本集首次出现且需要跨场景复用**的人物 / 场景 / 道具 / 发声源");
|
|
134
|
-
sections.push("- 已存在资产清单里的角色,**只在 ref 处用名字,不重复登记到 `## 人物`**");
|
|
135
|
-
return sections.join("\n");
|
|
136
|
-
}
|
|
137
|
-
// ---------------------------------------------------------------------------
|
|
138
|
-
// Context loading
|
|
139
|
-
// ---------------------------------------------------------------------------
|
|
140
|
-
function tryRead(filePath) {
|
|
141
|
-
if (!exists(filePath))
|
|
142
|
-
return undefined;
|
|
143
|
-
try {
|
|
144
|
-
const text = readText(filePath).trim();
|
|
145
|
-
return text || undefined;
|
|
146
|
-
}
|
|
147
|
-
catch {
|
|
148
|
-
return undefined;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
function findPreviousEpisodeBody(episodesDir, episode) {
|
|
152
|
-
if (!fs.existsSync(episodesDir))
|
|
153
|
-
return undefined;
|
|
154
|
-
for (let n = episode - 1; n >= 1; n--) {
|
|
155
|
-
const candidate = path.join(episodesDir, `ep${String(n).padStart(2, "0")}.md`);
|
|
156
|
-
if (fs.existsSync(candidate)) {
|
|
157
|
-
const text = readText(candidate).trim();
|
|
158
|
-
if (text)
|
|
159
|
-
return text.slice(-PREV_EPISODE_TAIL_CHARS);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Read the outline + all declared refs + the previous-episode tail (when present).
|
|
166
|
-
*
|
|
167
|
-
* Throws Error (caller wraps in CliError) if the per-episode outline can't be
|
|
168
|
-
* located: the writer must have something to write _from_.
|
|
169
|
-
*
|
|
170
|
-
* Missing optional refs are silently skipped. Missing required refs (optional:false)
|
|
171
|
-
* throw.
|
|
172
|
-
*/
|
|
173
|
-
export function loadWriterContext(opts) {
|
|
174
|
-
const defaultOutlineTemplate = path.join(opts.workspace, "episodes", "ep{NN}.outline.md");
|
|
175
|
-
const outlinePath = resolveTemplate(opts.outlineTemplate ?? defaultOutlineTemplate, opts.episode);
|
|
176
|
-
const outlineText = tryRead(outlinePath);
|
|
177
|
-
if (!outlineText) {
|
|
178
|
-
throw new Error(`episode outline not found at ${outlinePath}. Pass --outline <path> (literal or template with {NN}), ` +
|
|
179
|
-
`or place the outline at ${defaultOutlineTemplate.replace(/\{NN\}/g, String(opts.episode).padStart(2, "0"))}.`);
|
|
180
|
-
}
|
|
181
|
-
const refBlocks = [];
|
|
182
|
-
for (const ref of opts.refs) {
|
|
183
|
-
const body = tryRead(ref.path);
|
|
184
|
-
if (body) {
|
|
185
|
-
refBlocks.push({ title: ref.title, body });
|
|
186
|
-
}
|
|
187
|
-
else if (ref.optional === false) {
|
|
188
|
-
throw new Error(`required ref "${ref.title}" not found at ${ref.path}`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
const previousEpisodeBody = findPreviousEpisodeBody(path.join(opts.workspace, "episodes"), opts.episode);
|
|
192
|
-
return { outlineText, refBlocks, previousEpisodeBody };
|
|
193
|
-
}
|
|
194
|
-
// ---------------------------------------------------------------------------
|
|
195
|
-
// Driver
|
|
196
|
-
// ---------------------------------------------------------------------------
|
|
197
|
-
/**
|
|
198
|
-
* Compose the prompt + invoke the provider. Single-shot — retry on parser failure
|
|
199
|
-
* is the orchestrator's responsibility (it constructs a new `WriterRequest` with
|
|
200
|
-
* `parserErrorFeedback` set and calls `draftEpisode` again).
|
|
201
|
-
*/
|
|
202
|
-
export async function draftEpisode(provider, req) {
|
|
203
|
-
const prompt = composePrompt(req);
|
|
204
|
-
const raw = await provider.complete(prompt, req.maxTokens ?? DEFAULT_BATCH_MAX_TOKENS);
|
|
205
|
-
return { raw, prompt };
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=gemini-writer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini-writer.js","sourceRoot":"","sources":["../../src/infra/gemini-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `scriptctl episode` subcommand group.
|
|
3
|
-
*
|
|
4
|
-
* Atomic per-episode production loop for the creative mainline (灵感线 / 小说线 / 原创线
|
|
5
|
-
* → 剧本). The five commands compose into three modes:
|
|
6
|
-
*
|
|
7
|
-
* - **single**: user manually drives `draft → preview → commit` for each episode
|
|
8
|
-
* - **batch**: `episode batch --range a-b` internally loops draft → preview;
|
|
9
|
-
* user commits each episode after reviewing
|
|
10
|
-
* - **mixed**: first N episodes single (to lock in style), then batch
|
|
11
|
-
*
|
|
12
|
-
* The orchestrator is intentionally thin. Heavy lifting lives elsewhere:
|
|
13
|
-
* - prompt assembly + provider call → `infra/gemini-writer.ts`
|
|
14
|
-
* - markdown parsing → `domain/direct-core.ts::parseMarkdownBatch(.., {fragmentMode:true})`
|
|
15
|
-
* - asset state → `domain/asset-registry.ts`
|
|
16
|
-
* - collision detection → `domain/collision-detector.ts`
|
|
17
|
-
* - gateway upload → existing `infra/script-output-api.ts` (commit calls it)
|
|
18
|
-
*/
|
|
19
|
-
import { type Report } from "../common.js";
|
|
20
|
-
interface EpisodeOpts {
|
|
21
|
-
workspace_path?: string;
|
|
22
|
-
prompt_template?: string;
|
|
23
|
-
provider?: string;
|
|
24
|
-
model?: string;
|
|
25
|
-
outline?: string;
|
|
26
|
-
ref?: string[];
|
|
27
|
-
from_md?: string;
|
|
28
|
-
regen?: boolean;
|
|
29
|
-
resume?: boolean;
|
|
30
|
-
max_tokens?: string;
|
|
31
|
-
range?: string;
|
|
32
|
-
auto_commit?: boolean;
|
|
33
|
-
meta_path?: string;
|
|
34
|
-
from?: string;
|
|
35
|
-
to?: string;
|
|
36
|
-
force?: boolean;
|
|
37
|
-
project_group_no?: string;
|
|
38
|
-
request_id?: string;
|
|
39
|
-
_args?: string[];
|
|
40
|
-
}
|
|
41
|
-
export declare function commandEpisodeDraft(opts: EpisodeOpts): Promise<[Report, number]>;
|
|
42
|
-
export declare function commandEpisodeBatch(opts: EpisodeOpts): Promise<[Report, number]>;
|
|
43
|
-
export declare function commandEpisodeSpec(opts: EpisodeOpts): [Report, number];
|
|
44
|
-
export declare function commandEpisodeWorkspace(opts: EpisodeOpts): [Report, number];
|
|
45
|
-
export declare function commandEpisodeMerge(opts: EpisodeOpts): Promise<[Report, number]>;
|
|
46
|
-
export declare function commandEpisodePush(opts: EpisodeOpts): Promise<[Report, number]>;
|
|
47
|
-
export declare function commandEpisodeInit(opts: EpisodeOpts): [Report, number];
|
|
48
|
-
export {};
|