geo-ai-search-optimization 1.2.10 → 1.2.12

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/README.md CHANGED
@@ -124,6 +124,47 @@ geo-ai-search-optimization agent-executor ./reports/apply-plan.json --task fix-0
124
124
  - 给用户的回报模板
125
125
  - 可直接复制给 agent 的 executor prompt
126
126
 
127
+ ## Agent Batch Executor 命令
128
+
129
+ 如果你希望 agent 不只做 1 包,而是把前 2 到 3 包排成一个连续执行序列,同时仍然保持“一次只推进一包”,可以直接用 `agent-batch-executor`:
130
+
131
+ ```bash
132
+ geo-ai-search-optimization agent-batch-executor ./your-site
133
+ geo-ai-search-optimization agent-batch-executor ./reports/apply-plan.json
134
+ geo-ai-search-optimization agent-batch-executor ./reports/apply-plan.json --task fix-02 --count 3 --format json --out ./reports/agent-batch-executor.json
135
+ ```
136
+
137
+ `agent-batch-executor` 会输出:
138
+
139
+ - 当前批次先推进哪几包
140
+ - 为什么按这个顺序推进
141
+ - 每一包的 do-now checklist
142
+ - 每一包的 stop checklist
143
+ - 每一包的 success checklist
144
+ - 批次总验证命令
145
+ - 批次收尾命令
146
+ - 可直接复制给 agent 的 batch prompt
147
+
148
+ ## Agent Progress Tracker 命令
149
+
150
+ 如果你希望 agent 不是只拿到执行队列,而是能够明确回答“现在做到第几包、当前卡在哪、下一包是什么”,可以直接用 `agent-progress-tracker`:
151
+
152
+ ```bash
153
+ geo-ai-search-optimization agent-progress-tracker ./your-site
154
+ geo-ai-search-optimization agent-progress-tracker ./reports/apply-plan.json --completed fix-01,fix-02 --current fix-03
155
+ geo-ai-search-optimization agent-progress-tracker ./reports/agent-batch-executor.json --blocked "缺少仓库权限,缺少模板文件" --format json --out ./reports/agent-progress-tracker.json
156
+ ```
157
+
158
+ `agent-progress-tracker` 会输出:
159
+
160
+ - 当前状态是未开始、进行中、阻塞还是已完成
161
+ - 已完成到哪几包
162
+ - 当前正在推进哪一包
163
+ - 下一包是什么
164
+ - 当前阻塞项
165
+ - 建议下一步命令
166
+ - 可直接复制给 agent 的 progress prompt
167
+
127
168
  ## Quick Start
128
169
 
129
170
  如果你要从 0 到 1 启动一个 GEO 项目,建议照这个顺序做。
@@ -521,6 +562,8 @@ geo-ai-search-optimization auto-flow "audit this site and tell me the next skill
521
562
  geo-ai-search-optimization agent-session ./your-site
522
563
  geo-ai-search-optimization agent-runbook ./your-site
523
564
  geo-ai-search-optimization agent-executor ./your-site
565
+ geo-ai-search-optimization agent-batch-executor ./your-site
566
+ geo-ai-search-optimization agent-progress-tracker ./your-site
524
567
  geo-ai-search-optimization skills
525
568
  geo-ai-search-optimization where
526
569
  geo-ai-search-optimization doctor
@@ -591,6 +634,20 @@ geo-ai-search-optimization help
591
634
  - 输出 do-now checklist、stop checklist、success checklist、验证命令和回报模板
592
635
  - 新增 `geo-ai-search-optimization-agent-executor` skill
593
636
 
637
+ ## New in 1.2.12
638
+
639
+ - 新增 `agent-progress-tracker` 命令
640
+ - 可以从 `apply-plan`、`agent-executor`、`agent-batch-executor` 等工件推导当前执行进度
641
+ - 输出已完成任务、当前包、下一包、阻塞项和建议下一步命令
642
+ - 新增 `geo-ai-search-optimization-agent-progress-tracker` skill
643
+
644
+ ## New in 1.2.11
645
+
646
+ - 新增 `agent-batch-executor` 命令
647
+ - 让 agent 可以连续推进前几包任务,但仍然保持一次只执行一包
648
+ - 输出批次顺序、每包检查清单、批次总验证命令和收尾命令
649
+ - 新增 `geo-ai-search-optimization-agent-batch-executor` skill
650
+
594
651
  ## New in 1.2.5
595
652
 
596
653
  - 新增 `publish-pack`
@@ -781,6 +838,8 @@ The installed package now includes a bundled GEO skill pack, including:
781
838
  - `geo-ai-search-optimization-agent-session`
782
839
  - `geo-ai-search-optimization-agent-runbook`
783
840
  - `geo-ai-search-optimization-agent-executor`
841
+ - `geo-ai-search-optimization-agent-batch-executor`
842
+ - `geo-ai-search-optimization-agent-progress-tracker`
784
843
  - `geo-ai-search-optimization-usage`
785
844
  - `geo-ai-search-optimization-agent-handoff`
786
845
  - `geo-ai-search-optimization-repair-loop`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geo-ai-search-optimization",
3
- "version": "1.2.10",
3
+ "version": "1.2.12",
4
4
  "description": "Install and run a Generative Engine Optimization (GEO)-first, SEO-supported Codex skill for website optimization.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -62,6 +62,26 @@ Best for:
62
62
  - reducing a runbook into one actionable task
63
63
  - giving the next agent a single-task prompt, validation commands, and reply template
64
64
 
65
+ ### `geo-ai-search-optimization-agent-batch-executor`
66
+
67
+ Use this when the next agent should continuously advance the first few execution packets, but still only work on one packet at a time.
68
+
69
+ Best for:
70
+
71
+ - turning an `apply-plan` into a short execution queue
72
+ - making the next agent finish packet 1 before packet 2 starts
73
+ - giving the next agent a batch-level prompt, per-packet checklists, and final closeout commands
74
+
75
+ ### `geo-ai-search-optimization-agent-progress-tracker`
76
+
77
+ Use this when the next agent should explain current execution status, not just produce the next queue.
78
+
79
+ Best for:
80
+
81
+ - showing which packet is already done
82
+ - clarifying the current active packet and the next packet
83
+ - surfacing blockers before the team moves into closeout or the next batch
84
+
65
85
  ## Usage guide
66
86
 
67
87
  ### `geo-ai-search-optimization-usage`
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: geo-ai-search-optimization-agent-batch-executor
3
+ description: Turn a GEO input into a short multi-packet execution queue for the next agent. Use when an agent should continuously advance the first 2 to 3 GEO packets in order, while still executing only one packet at a time, with per-packet checklists, validation commands, and closeout steps.
4
+ ---
5
+
6
+ # GEO Agent Batch Executor
7
+
8
+ Use this skill when the next agent should not stop at one task, but also should not expand into an uncontrolled multi-task run.
9
+
10
+ `GEO = Generative Engine Optimization`
11
+
12
+ ## What it does
13
+
14
+ - select the first few execution packets from an apply-plan or equivalent artifact
15
+ - keep the execution order explicit
16
+ - enforce one-packet-at-a-time progress
17
+ - provide per-packet do-now, stop, and success checklists
18
+ - give the next agent one batch prompt plus final closeout commands
19
+
20
+ ## Best use
21
+
22
+ - when `agent-executor` is too narrow because the next agent should keep going after packet 1
23
+ - when a PM wants “finish the first 2 to 3 packets in order”
24
+ - when the next agent needs a short queue, not a full open-ended plan
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "GEO Agent Batch Executor"
3
+ short_description: "Queue the first GEO packets for one-by-one execution"
4
+ default_prompt: "Use $geo-ai-search-optimization-agent-batch-executor to choose the first 2 to 3 GEO packets to advance in order, while still executing only one packet at a time."
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: geo-ai-search-optimization-agent-progress-tracker
3
+ description: Track GEO execution progress from apply-plan, agent-executor, agent-batch-executor, completion-report, or related artifacts. Use when an agent should explain which GEO packet is already done, which one is active, what is blocked, and what command should run next.
4
+ ---
5
+
6
+ # GEO Agent Progress Tracker
7
+
8
+ Use this skill when the next agent should stop guessing current status and make the execution state explicit.
9
+
10
+ `GEO = Generative Engine Optimization`
11
+
12
+ ## What it does
13
+
14
+ - reads GEO execution artifacts and infers the current packet state
15
+ - shows completed packets, the active packet, the next packet, and blockers
16
+ - recommends the next command for continuing or closing out the work
17
+ - gives the next agent a progress-tracking prompt instead of another open-ended plan
18
+
19
+ ## Best use
20
+
21
+ - when a PM asks “现在做到哪了?”
22
+ - when the next agent should explain status before touching the next packet
23
+ - when batch execution is underway and the team needs a stable progress checkpoint
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "GEO Agent Progress Tracker"
3
+ short_description: "Track which GEO packet is done, active, or blocked"
4
+ default_prompt: "Use $geo-ai-search-optimization-agent-progress-tracker to explain GEO execution progress, blockers, the current packet, and the next command."
@@ -13,25 +13,27 @@ Treat this tool as a PM-friendly GEO workflow for websites.
13
13
 
14
14
  `GEO = Generative Engine Optimization`
15
15
 
16
- The package is best explained as seventeen layers:
16
+ The package is best explained as nineteen layers:
17
17
 
18
18
  1. `auto-flow`: auto-select the next skill and command chain
19
19
  2. `agent-session`: build a runnable session for the next agent
20
20
  3. `agent-runbook`: execution manual and checklist for the next agent
21
21
  4. `agent-executor`: choose one packet to execute right now
22
- 5. `skills`: inspect the bundled skill package
23
- 6. `onboard-url` / `onboard`: first look
24
- 7. `scan`: raw signal check
25
- 8. `audit` / `report`: diagnosis
26
- 9. `fix-plan` / `owner-board`: execution planning
27
- 10. `agent-handoff`: agent takeover package
28
- 11. `apply-plan`: execution loop
29
- 12. `completion-report`: closeout
30
- 13. `handoff-bundle`: all-in-one package
31
- 14. `share-pack`: audience-ready delivery
32
- 15. `export-pack`: folder export
33
- 16. `html-pack` / `publish-pack`: browsable and final delivery output
34
- 17. `pm-brief` / `roadmap`: stakeholder alignment
22
+ 5. `agent-batch-executor`: queue the first few packets, but still advance one packet at a time
23
+ 6. `agent-progress-tracker`: track which packet is done, which one is active, and what comes next
24
+ 7. `skills`: inspect the bundled skill package
25
+ 8. `onboard-url` / `onboard`: first look
26
+ 9. `scan`: raw signal check
27
+ 10. `audit` / `report`: diagnosis
28
+ 11. `fix-plan` / `owner-board`: execution planning
29
+ 12. `agent-handoff`: agent takeover package
30
+ 13. `apply-plan`: execution loop
31
+ 14. `completion-report`: closeout
32
+ 15. `handoff-bundle`: all-in-one package
33
+ 16. `share-pack`: audience-ready delivery
34
+ 17. `export-pack`: folder export
35
+ 18. `html-pack` / `publish-pack`: browsable and final delivery output
36
+ 19. `pm-brief` / `roadmap`: stakeholder alignment
35
37
 
36
38
  ## Recommended command order
37
39
 
@@ -42,6 +44,8 @@ npx geo-ai-search-optimization auto-flow https://example.com
42
44
  npx geo-ai-search-optimization agent-session https://example.com
43
45
  npx geo-ai-search-optimization agent-runbook https://example.com
44
46
  npx geo-ai-search-optimization agent-executor https://example.com
47
+ npx geo-ai-search-optimization agent-batch-executor https://example.com
48
+ npx geo-ai-search-optimization agent-progress-tracker https://example.com
45
49
  npx geo-ai-search-optimization onboard-url https://example.com
46
50
  npx geo-ai-search-optimization pm-brief https://example.com
47
51
  npx geo-ai-search-optimization roadmap https://example.com
@@ -54,6 +58,8 @@ npx geo-ai-search-optimization auto-flow ./your-site
54
58
  npx geo-ai-search-optimization agent-session ./your-site
55
59
  npx geo-ai-search-optimization agent-runbook ./your-site
56
60
  npx geo-ai-search-optimization agent-executor ./your-site
61
+ npx geo-ai-search-optimization agent-batch-executor ./your-site
62
+ npx geo-ai-search-optimization agent-progress-tracker ./your-site
57
63
  npx geo-ai-search-optimization scan ./your-site
58
64
  npx geo-ai-search-optimization audit ./your-site
59
65
  npx geo-ai-search-optimization fix-plan ./your-site
@@ -75,6 +81,8 @@ npx geo-ai-search-optimization roadmap ./your-site
75
81
  - `agent-session`: build a step-by-step session packet for the next agent from the same kinds of inputs
76
82
  - `agent-runbook`: build a checklist-driven runbook with preflight, validation, and reporting rules
77
83
  - `agent-executor`: select one packet to execute now and package it into a single-task entrypoint
84
+ - `agent-batch-executor`: line up the first few packets in execution order while preserving one-packet-at-a-time discipline
85
+ - `agent-progress-tracker`: show execution progress, current packet, blockers, and the next packet to advance
78
86
  - `onboard-url`: first-time website check from a live URL
79
87
  - `onboard`: interactive first-time onboarding
80
88
  - `skills`: list the bundled skills and decide which skill or command chain fits the task
@@ -103,6 +111,8 @@ When explaining the tool to a user:
103
111
  - if the user wants something the next agent can follow step by step, move them to `agent-session`
104
112
  - if the user wants the next agent to follow a checklist and execution manual, move them to `agent-runbook`
105
113
  - if the user wants the next agent to start one concrete task now, move them to `agent-executor`
114
+ - if the user wants the next agent to continuously advance the first 2 to 3 packets in order, move them to `agent-batch-executor`
115
+ - if the user wants the next agent to explain current progress, blockers, and the next packet, move them to `agent-progress-tracker`
106
116
  - explain the result in PM language, not implementation jargon
107
117
  - if the user sounds new, start with `onboard-url` or `quick-start`
108
118
  - if the user wants another agent to take over, move them to `agent-handoff`
@@ -0,0 +1,327 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { createApplyPlan } from "./apply-plan.js";
3
+ import { createAgentExecutor } from "./agent-executor.js";
4
+ import { writeScanOutput } from "./scan.js";
5
+
6
+ const VALID_FORMATS = new Set(["markdown", "json"]);
7
+
8
+ function normalizeFormat(format) {
9
+ const resolved = (format || "markdown").toLowerCase();
10
+ if (!VALID_FORMATS.has(resolved)) {
11
+ throw new Error(`不支持的 agent-batch-executor 格式:${format}。可选值:${Array.from(VALID_FORMATS).join(", ")}`);
12
+ }
13
+ return resolved;
14
+ }
15
+
16
+ function normalizeCount(count) {
17
+ if (count == null) {
18
+ return 3;
19
+ }
20
+
21
+ const parsed = Number.parseInt(count, 10);
22
+ if (!Number.isInteger(parsed) || parsed <= 0) {
23
+ throw new Error("--count 必须是正整数");
24
+ }
25
+
26
+ return Math.min(parsed, 5);
27
+ }
28
+
29
+ async function loadApplyPlanArtifact(input) {
30
+ const raw = await readFile(input, "utf8");
31
+ const parsed = JSON.parse(raw);
32
+
33
+ if (parsed?.kind === "geo-apply-plan") {
34
+ return parsed;
35
+ }
36
+ if (parsed?.kind === "geo-agent-runbook" && parsed.applyPlan?.kind === "geo-apply-plan") {
37
+ return parsed.applyPlan;
38
+ }
39
+ if (parsed?.kind === "geo-agent-executor" && parsed.applyPlan?.kind === "geo-apply-plan") {
40
+ return parsed.applyPlan;
41
+ }
42
+
43
+ return null;
44
+ }
45
+
46
+ async function resolveApplyPlan(input) {
47
+ const artifact = await loadApplyPlanArtifact(input).catch(() => null);
48
+ if (artifact) {
49
+ return artifact;
50
+ }
51
+
52
+ return createApplyPlan(input, {
53
+ format: "json"
54
+ });
55
+ }
56
+
57
+ function selectPackets(applyPlan, count, startTaskId) {
58
+ const packets = applyPlan?.packets || [];
59
+ if (packets.length === 0) {
60
+ return [];
61
+ }
62
+
63
+ let startIndex = 0;
64
+ if (startTaskId) {
65
+ startIndex = packets.findIndex((packet) => packet.id === startTaskId);
66
+ if (startIndex === -1) {
67
+ throw new Error(`找不到执行包:${startTaskId}`);
68
+ }
69
+ }
70
+
71
+ return packets.slice(startIndex, startIndex + count);
72
+ }
73
+
74
+ async function buildPacketExecutors(input, packets, options) {
75
+ const results = [];
76
+
77
+ for (const packet of packets) {
78
+ const executor = await createAgentExecutor(input, {
79
+ format: "json",
80
+ intent: options.intent,
81
+ taskId: packet.id
82
+ });
83
+
84
+ results.push({
85
+ position: results.length + 1,
86
+ id: packet.id,
87
+ title: packet.title,
88
+ priority: packet.priority,
89
+ owner: packet.owner,
90
+ executorMode: executor.executorMode,
91
+ doNowChecklist: executor.doNowChecklist,
92
+ stopChecklist: executor.stopChecklist,
93
+ successChecklist: executor.successChecklist,
94
+ validationCommands: executor.validationCommands,
95
+ userReplyTemplate: executor.userReplyTemplate,
96
+ executorPrompt: executor.executorPrompt,
97
+ startCommand: `geo-ai-search-optimization agent-executor ${executor.source} --task ${packet.id}`,
98
+ nextCommands: executor.nextCommands
99
+ });
100
+ }
101
+
102
+ return results;
103
+ }
104
+
105
+ function inferBatchMode(packetExecutors) {
106
+ if (packetExecutors.length === 0) {
107
+ return "needs-context";
108
+ }
109
+
110
+ const modes = new Set(packetExecutors.map((packet) => packet.executorMode));
111
+ if (modes.size === 1) {
112
+ return packetExecutors[0].executorMode;
113
+ }
114
+ return "mixed";
115
+ }
116
+
117
+ function buildSelectionReason(packets, applyPlan, count, startTaskId) {
118
+ if (packets.length === 0) {
119
+ return "当前还没有可批量执行的任务包,说明需要先补上下文或先生成 apply-plan。";
120
+ }
121
+
122
+ if (startTaskId) {
123
+ return `已从指定任务 ${startTaskId} 开始,连续选出后续 ${packets.length} 包,按顺序推进。`;
124
+ }
125
+
126
+ if (packets.length === 1) {
127
+ return "当前只拿到 1 个任务包,因此直接把它作为本轮批处理入口。";
128
+ }
129
+
130
+ const available = applyPlan?.packets?.length || packets.length;
131
+ if (available < count) {
132
+ return `计划最多取前 ${count} 包,但当前只有 ${available} 包可用,因此按现有顺序推进这 ${packets.length} 包。`;
133
+ }
134
+
135
+ return `已按优先级选出前 ${packets.length} 包,按顺序推进,但一次只执行一包。`;
136
+ }
137
+
138
+ function buildBatchRules(batchMode) {
139
+ const items = [
140
+ "始终一次只推进一包,不要同时展开多个修复包。",
141
+ "每做完一包,都先检查完成标准和验证命令,再决定是否进入下一包。",
142
+ "如果上一包没有通过验收,不要直接跳到下一包。"
143
+ ];
144
+
145
+ if (batchMode === "direct-fix") {
146
+ items.push("每包都优先改复用层,而不是只 patch 单页。");
147
+ }
148
+ if (batchMode === "recommendation-only") {
149
+ items.push("当前更适合给建议,不要伪造已经完成的代码修改。");
150
+ }
151
+
152
+ return items;
153
+ }
154
+
155
+ function buildQueueSummary(packetExecutors) {
156
+ return packetExecutors.map((packet, index) => ({
157
+ position: index + 1,
158
+ id: packet.id,
159
+ title: packet.title,
160
+ priority: packet.priority,
161
+ owner: packet.owner,
162
+ startCommand: packet.startCommand,
163
+ stopIf: packet.stopChecklist[packet.stopChecklist.length - 1] || "当前包未达成完成标准时不要继续。",
164
+ afterSuccess:
165
+ index < packetExecutors.length - 1
166
+ ? `进入下一包:${packetExecutors[index + 1].id}`
167
+ : "进入 completion-report 与 handoff-bundle 收尾。"
168
+ }));
169
+ }
170
+
171
+ function buildValidationRollup(packetExecutors) {
172
+ const commands = new Set();
173
+ for (const packet of packetExecutors) {
174
+ for (const command of packet.validationCommands) {
175
+ commands.add(command);
176
+ }
177
+ }
178
+ return Array.from(commands);
179
+ }
180
+
181
+ function buildFinalCommands(source) {
182
+ return [
183
+ `geo-ai-search-optimization completion-report ${source}`,
184
+ `geo-ai-search-optimization handoff-bundle ${source}`,
185
+ `geo-ai-search-optimization publish-pack ${source}`
186
+ ];
187
+ }
188
+
189
+ function buildBatchPrompt(batch) {
190
+ const lines = [
191
+ "你现在进入 GEO 多任务批次执行模式。",
192
+ `当前输入:${batch.source}`,
193
+ `批次模式:${batch.batchMode}`,
194
+ `批次目标:${batch.goal}`,
195
+ `批次选择原因:${batch.selectionReason}`,
196
+ "请遵守:一次只推进一包,上一包通过验证后再进入下一包。"
197
+ ];
198
+
199
+ if (batch.packetExecutors.length > 0) {
200
+ lines.push("当前批次顺序:");
201
+ for (const packet of batch.packetExecutors) {
202
+ lines.push(`${packet.position}. ${packet.id}|${packet.title}`);
203
+ }
204
+ } else {
205
+ lines.push("当前还没有可执行包。请先告诉用户缺什么上下文。");
206
+ }
207
+
208
+ lines.push("每一包都要输出:先检查什么、怎么做、如何验证、完成后如何回报。");
209
+ return lines.join("\n");
210
+ }
211
+
212
+ export async function createAgentBatchExecutor(input, options = {}) {
213
+ const format = normalizeFormat(options.format);
214
+ const count = normalizeCount(options.count);
215
+ const applyPlan = await resolveApplyPlan(input);
216
+ const selectedPackets = selectPackets(applyPlan, count, options.taskId);
217
+ const packetExecutors = await buildPacketExecutors(input, selectedPackets, options);
218
+ const batchMode = inferBatchMode(packetExecutors);
219
+ const source = packetExecutors[0]?.startCommand ? applyPlan.source || input : applyPlan?.source || input;
220
+
221
+ return {
222
+ kind: "geo-agent-batch-executor",
223
+ input,
224
+ source,
225
+ sourceType: applyPlan?.sourceType || "unknown",
226
+ artifactKind: applyPlan?.kind || "unknown",
227
+ format,
228
+ batchMode,
229
+ packetCount: packetExecutors.length,
230
+ goal:
231
+ packetExecutors.length > 0
232
+ ? `按顺序推进这 ${packetExecutors.length} 包,但每次只执行一包。`
233
+ : "当前先补上下文,再进入多任务批次执行。",
234
+ selectionReason: buildSelectionReason(selectedPackets, applyPlan, count, options.taskId),
235
+ batchRules: buildBatchRules(batchMode),
236
+ queueSummary: buildQueueSummary(packetExecutors),
237
+ packetExecutors,
238
+ validationRollup: buildValidationRollup(packetExecutors),
239
+ finalCommands: buildFinalCommands(source),
240
+ batchPrompt: buildBatchPrompt({
241
+ source,
242
+ batchMode,
243
+ goal:
244
+ packetExecutors.length > 0
245
+ ? `按顺序推进这 ${packetExecutors.length} 包,但每次只执行一包。`
246
+ : "当前先补上下文,再进入多任务批次执行。",
247
+ selectionReason: buildSelectionReason(selectedPackets, applyPlan, count, options.taskId),
248
+ packetExecutors
249
+ }),
250
+ applyPlan
251
+ };
252
+ }
253
+
254
+ export function renderAgentBatchExecutorMarkdown(batch) {
255
+ const lines = [
256
+ "# GEO Agent Batch Executor",
257
+ "",
258
+ `- 输入:\`${batch.source}\``,
259
+ `- 来源类型:\`${batch.sourceType}\``,
260
+ `- 工件类型:\`${batch.artifactKind}\``,
261
+ `- 批次模式:\`${batch.batchMode}\``,
262
+ `- 批次数量:\`${batch.packetCount}\``,
263
+ `- 目标:${batch.goal}`,
264
+ `- 选择原因:${batch.selectionReason}`,
265
+ "",
266
+ "## 批次规则",
267
+ ""
268
+ ];
269
+
270
+ for (const item of batch.batchRules) {
271
+ lines.push(`- [ ] ${item}`);
272
+ }
273
+
274
+ lines.push("", "## 执行顺序", "");
275
+ for (const item of batch.queueSummary) {
276
+ lines.push(`### ${item.position}. ${item.id}|${item.title}`, "");
277
+ lines.push(`- 优先级:${item.priority}`);
278
+ lines.push(`- Owner:${item.owner}`);
279
+ lines.push(`- 开始命令:\`${item.startCommand}\``);
280
+ lines.push(`- 继续条件:${item.afterSuccess}`);
281
+ lines.push(`- 停下条件:${item.stopIf}`);
282
+ lines.push("");
283
+ }
284
+
285
+ for (const packet of batch.packetExecutors) {
286
+ lines.push(`## ${packet.position}. ${packet.id}|${packet.title}`, "");
287
+ lines.push("- Do now:");
288
+ for (const item of packet.doNowChecklist) {
289
+ lines.push(` - [ ] ${item}`);
290
+ }
291
+ lines.push("- 停下条件:");
292
+ for (const item of packet.stopChecklist) {
293
+ lines.push(` - [ ] ${item}`);
294
+ }
295
+ lines.push("- 完成标准:");
296
+ for (const item of packet.successChecklist) {
297
+ lines.push(` - [ ] ${item}`);
298
+ }
299
+ lines.push("- 验证命令:");
300
+ for (const command of packet.validationCommands) {
301
+ lines.push(` - \`${command}\``);
302
+ }
303
+ lines.push("- 回报模板:");
304
+ lines.push("```text");
305
+ lines.push(packet.userReplyTemplate);
306
+ lines.push("```");
307
+ lines.push("");
308
+ }
309
+
310
+ lines.push("## 批次总验证命令", "");
311
+ for (const command of batch.validationRollup) {
312
+ lines.push(`- \`${command}\``);
313
+ }
314
+
315
+ lines.push("", "## 最终收尾命令", "");
316
+ for (const command of batch.finalCommands) {
317
+ lines.push(`- \`${command}\``);
318
+ }
319
+
320
+ lines.push("", "## 可直接复制给 Agent 的 Batch Prompt", "", "```text", batch.batchPrompt, "```");
321
+
322
+ return `${lines.join("\n")}\n`;
323
+ }
324
+
325
+ export async function writeAgentBatchExecutorOutput(outputPath, content) {
326
+ return writeScanOutput(outputPath, content);
327
+ }