geo-ai-search-optimization 1.2.12 → 1.2.14
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 +60 -0
- package/package.json +1 -1
- package/resources/geo-ai-search-optimization/references/skill-bundle-map.md +20 -0
- package/resources/geo-ai-search-optimization-agent-checkpoint/SKILL.md +23 -0
- package/resources/geo-ai-search-optimization-agent-checkpoint/agents/openai.yaml +4 -0
- package/resources/geo-ai-search-optimization-agent-status-board/SKILL.md +23 -0
- package/resources/geo-ai-search-optimization-agent-status-board/agents/openai.yaml +4 -0
- package/resources/geo-ai-search-optimization-usage/SKILL.md +24 -14
- package/src/agent-checkpoint.js +358 -0
- package/src/agent-progress-tracker.js +48 -0
- package/src/agent-session.js +20 -0
- package/src/agent-status-board.js +261 -0
- package/src/auto-flow.js +56 -0
- package/src/cli.js +70 -0
- package/src/index.js +2 -0
- package/src/skills.js +6 -0
package/README.md
CHANGED
|
@@ -165,6 +165,48 @@ geo-ai-search-optimization agent-progress-tracker ./reports/agent-batch-executor
|
|
|
165
165
|
- 建议下一步命令
|
|
166
166
|
- 可直接复制给 agent 的 progress prompt
|
|
167
167
|
|
|
168
|
+
## Agent Status Board 命令
|
|
169
|
+
|
|
170
|
+
如果你希望把当前执行状态直接整理成更像团队协作看板的分栏视图,而不是只看一份文字进度摘要,可以直接用 `agent-status-board`:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
geo-ai-search-optimization agent-status-board ./your-site
|
|
174
|
+
geo-ai-search-optimization agent-status-board ./reports/apply-plan.json --completed fix-01 --current fix-02
|
|
175
|
+
geo-ai-search-optimization agent-status-board ./reports/agent-progress-tracker.json --blocked "缺少仓库权限,缺少模板文件" --format json --out ./reports/agent-status-board.json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`agent-status-board` 会输出:
|
|
179
|
+
|
|
180
|
+
- 已完成栏
|
|
181
|
+
- 进行中栏
|
|
182
|
+
- 阻塞栏
|
|
183
|
+
- 下一步栏
|
|
184
|
+
- 排队中栏
|
|
185
|
+
- 收尾栏
|
|
186
|
+
- 建议下一步命令
|
|
187
|
+
- 可直接复制给 agent 的 status board prompt
|
|
188
|
+
|
|
189
|
+
## Agent Checkpoint 命令
|
|
190
|
+
|
|
191
|
+
如果你希望在每一轮执行结束时,产出一个明确的阶段决策,而不只是状态展示,可以直接用 `agent-checkpoint`:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
geo-ai-search-optimization agent-checkpoint ./your-site
|
|
195
|
+
geo-ai-search-optimization agent-checkpoint ./reports/agent-status-board.json --completed fix-01 --current fix-02
|
|
196
|
+
geo-ai-search-optimization agent-checkpoint ./reports/agent-progress-tracker.json --blocked "缺少仓库权限" --format json --out ./reports/agent-checkpoint.json
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`agent-checkpoint` 会输出:
|
|
200
|
+
|
|
201
|
+
- 当前检查点类型
|
|
202
|
+
- 当前决策是继续、解除阻塞还是进入收尾
|
|
203
|
+
- gate checks
|
|
204
|
+
- 决策清单
|
|
205
|
+
- 建议下一步命令
|
|
206
|
+
- 备选命令
|
|
207
|
+
- 交接说明
|
|
208
|
+
- 可直接复制给 agent 的 checkpoint prompt
|
|
209
|
+
|
|
168
210
|
## Quick Start
|
|
169
211
|
|
|
170
212
|
如果你要从 0 到 1 启动一个 GEO 项目,建议照这个顺序做。
|
|
@@ -564,6 +606,8 @@ geo-ai-search-optimization agent-runbook ./your-site
|
|
|
564
606
|
geo-ai-search-optimization agent-executor ./your-site
|
|
565
607
|
geo-ai-search-optimization agent-batch-executor ./your-site
|
|
566
608
|
geo-ai-search-optimization agent-progress-tracker ./your-site
|
|
609
|
+
geo-ai-search-optimization agent-status-board ./your-site
|
|
610
|
+
geo-ai-search-optimization agent-checkpoint ./your-site
|
|
567
611
|
geo-ai-search-optimization skills
|
|
568
612
|
geo-ai-search-optimization where
|
|
569
613
|
geo-ai-search-optimization doctor
|
|
@@ -634,6 +678,20 @@ geo-ai-search-optimization help
|
|
|
634
678
|
- 输出 do-now checklist、stop checklist、success checklist、验证命令和回报模板
|
|
635
679
|
- 新增 `geo-ai-search-optimization-agent-executor` skill
|
|
636
680
|
|
|
681
|
+
## New in 1.2.14
|
|
682
|
+
|
|
683
|
+
- 新增 `agent-checkpoint` 命令
|
|
684
|
+
- 把每一轮执行状态压成 continue / unblock / closeout 的阶段决策工件
|
|
685
|
+
- 支持从 `agent-progress-tracker`、`agent-status-board`、`apply-plan` 等工件继续生成检查点
|
|
686
|
+
- 新增 `geo-ai-search-optimization-agent-checkpoint` skill
|
|
687
|
+
|
|
688
|
+
## New in 1.2.13
|
|
689
|
+
|
|
690
|
+
- 新增 `agent-status-board` 命令
|
|
691
|
+
- 把当前执行状态整理成更像看板的分栏视图
|
|
692
|
+
- 支持从 `apply-plan`、`agent-progress-tracker`、`agent-batch-executor` 等工件继续生成状态看板
|
|
693
|
+
- 新增 `geo-ai-search-optimization-agent-status-board` skill
|
|
694
|
+
|
|
637
695
|
## New in 1.2.12
|
|
638
696
|
|
|
639
697
|
- 新增 `agent-progress-tracker` 命令
|
|
@@ -840,6 +898,8 @@ The installed package now includes a bundled GEO skill pack, including:
|
|
|
840
898
|
- `geo-ai-search-optimization-agent-executor`
|
|
841
899
|
- `geo-ai-search-optimization-agent-batch-executor`
|
|
842
900
|
- `geo-ai-search-optimization-agent-progress-tracker`
|
|
901
|
+
- `geo-ai-search-optimization-agent-status-board`
|
|
902
|
+
- `geo-ai-search-optimization-agent-checkpoint`
|
|
843
903
|
- `geo-ai-search-optimization-usage`
|
|
844
904
|
- `geo-ai-search-optimization-agent-handoff`
|
|
845
905
|
- `geo-ai-search-optimization-repair-loop`
|
package/package.json
CHANGED
|
@@ -82,6 +82,26 @@ Best for:
|
|
|
82
82
|
- clarifying the current active packet and the next packet
|
|
83
83
|
- surfacing blockers before the team moves into closeout or the next batch
|
|
84
84
|
|
|
85
|
+
### `geo-ai-search-optimization-agent-status-board`
|
|
86
|
+
|
|
87
|
+
Use this when the next agent should present execution state as a board instead of a plain progress summary.
|
|
88
|
+
|
|
89
|
+
Best for:
|
|
90
|
+
|
|
91
|
+
- giving PM and agent the same execution view
|
|
92
|
+
- showing done, in-progress, blocked, next, and queued packets in one artifact
|
|
93
|
+
- turning progress tracking into a more shareable coordination output
|
|
94
|
+
|
|
95
|
+
### `geo-ai-search-optimization-agent-checkpoint`
|
|
96
|
+
|
|
97
|
+
Use this when the next agent should make a stage decision, not just show the current state.
|
|
98
|
+
|
|
99
|
+
Best for:
|
|
100
|
+
|
|
101
|
+
- deciding whether the round should continue, unblock, or close out
|
|
102
|
+
- producing a clean handoff note at the end of one execution round
|
|
103
|
+
- giving PM and the next agent one checkpoint artifact to align on
|
|
104
|
+
|
|
85
105
|
## Usage guide
|
|
86
106
|
|
|
87
107
|
### `geo-ai-search-optimization-usage`
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-ai-search-optimization-agent-checkpoint
|
|
3
|
+
description: Turn GEO execution state into a stage checkpoint decision. Use when an agent should decide whether the current round should continue, first resolve blockers, or move into closeout, based on progress trackers, status boards, apply-plan artifacts, or related execution outputs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GEO Agent Checkpoint
|
|
7
|
+
|
|
8
|
+
Use this skill when the next agent should make a round-level execution decision, not just summarize state.
|
|
9
|
+
|
|
10
|
+
`GEO = Generative Engine Optimization`
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- converts current GEO execution state into a checkpoint artifact
|
|
15
|
+
- decides whether to continue, unblock, or close out
|
|
16
|
+
- adds gate checks and a decision checklist
|
|
17
|
+
- produces a handoff note and next command for the next agent
|
|
18
|
+
|
|
19
|
+
## Best use
|
|
20
|
+
|
|
21
|
+
- when one execution round ends and the team needs a checkpoint
|
|
22
|
+
- when PM asks whether the team should keep going or stop and unblock first
|
|
23
|
+
- when another agent should take over from a stable checkpoint instead of raw state
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "GEO Agent Checkpoint"
|
|
3
|
+
short_description: "Decide continue, unblock, or closeout for this GEO round"
|
|
4
|
+
default_prompt: "Use $geo-ai-search-optimization-agent-checkpoint to turn this GEO execution state into a checkpoint decision with gate checks, next command, and handoff note."
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-ai-search-optimization-agent-status-board
|
|
3
|
+
description: Turn GEO execution state into a board-style artifact for PM and agent coordination. Use when an agent should present done, in-progress, blocked, next, queued, and closeout states from apply-plan, agent-progress-tracker, agent-batch-executor, or related execution artifacts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GEO Agent Status Board
|
|
7
|
+
|
|
8
|
+
Use this skill when the next agent should explain execution state as a board, not just as a paragraph summary.
|
|
9
|
+
|
|
10
|
+
`GEO = Generative Engine Optimization`
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- turns current GEO execution state into board columns
|
|
15
|
+
- keeps PM and agent aligned on the same packet status
|
|
16
|
+
- shows done, in-progress, blocked, next, queued, and closeout views
|
|
17
|
+
- points to the next command and preserves the underlying progress tracker
|
|
18
|
+
|
|
19
|
+
## Best use
|
|
20
|
+
|
|
21
|
+
- when a PM asks for a coordination-friendly view
|
|
22
|
+
- when progress tracking exists but still feels too text-heavy
|
|
23
|
+
- when the next agent should continue from a board artifact instead of rebuilding context
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "GEO Agent Status Board"
|
|
3
|
+
short_description: "Present GEO execution state as a board"
|
|
4
|
+
default_prompt: "Use $geo-ai-search-optimization-agent-status-board to turn this GEO execution state into a board with done, in-progress, blocked, next, queued, and closeout columns."
|
|
@@ -13,7 +13,7 @@ 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
|
|
16
|
+
The package is best explained as twenty-one 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
|
|
@@ -21,19 +21,21 @@ The package is best explained as nineteen layers:
|
|
|
21
21
|
4. `agent-executor`: choose one packet to execute right now
|
|
22
22
|
5. `agent-batch-executor`: queue the first few packets, but still advance one packet at a time
|
|
23
23
|
6. `agent-progress-tracker`: track which packet is done, which one is active, and what comes next
|
|
24
|
-
7. `
|
|
25
|
-
8. `
|
|
26
|
-
9. `
|
|
27
|
-
10. `
|
|
28
|
-
11. `
|
|
29
|
-
12. `
|
|
30
|
-
13. `
|
|
31
|
-
14. `
|
|
32
|
-
15. `
|
|
33
|
-
16. `
|
|
34
|
-
17. `
|
|
35
|
-
18. `
|
|
36
|
-
19. `
|
|
24
|
+
7. `agent-status-board`: turn the execution state into a board view for PM and agents
|
|
25
|
+
8. `agent-checkpoint`: freeze the current round into a continue / unblock / closeout decision
|
|
26
|
+
9. `skills`: inspect the bundled skill package
|
|
27
|
+
10. `onboard-url` / `onboard`: first look
|
|
28
|
+
11. `scan`: raw signal check
|
|
29
|
+
12. `audit` / `report`: diagnosis
|
|
30
|
+
13. `fix-plan` / `owner-board`: execution planning
|
|
31
|
+
14. `agent-handoff`: agent takeover package
|
|
32
|
+
15. `apply-plan`: execution loop
|
|
33
|
+
16. `completion-report`: closeout
|
|
34
|
+
17. `handoff-bundle`: all-in-one package
|
|
35
|
+
18. `share-pack`: audience-ready delivery
|
|
36
|
+
19. `export-pack`: folder export
|
|
37
|
+
20. `html-pack` / `publish-pack`: browsable and final delivery output
|
|
38
|
+
21. `pm-brief` / `roadmap`: stakeholder alignment
|
|
37
39
|
|
|
38
40
|
## Recommended command order
|
|
39
41
|
|
|
@@ -46,6 +48,8 @@ npx geo-ai-search-optimization agent-runbook https://example.com
|
|
|
46
48
|
npx geo-ai-search-optimization agent-executor https://example.com
|
|
47
49
|
npx geo-ai-search-optimization agent-batch-executor https://example.com
|
|
48
50
|
npx geo-ai-search-optimization agent-progress-tracker https://example.com
|
|
51
|
+
npx geo-ai-search-optimization agent-status-board https://example.com
|
|
52
|
+
npx geo-ai-search-optimization agent-checkpoint https://example.com
|
|
49
53
|
npx geo-ai-search-optimization onboard-url https://example.com
|
|
50
54
|
npx geo-ai-search-optimization pm-brief https://example.com
|
|
51
55
|
npx geo-ai-search-optimization roadmap https://example.com
|
|
@@ -60,6 +64,8 @@ npx geo-ai-search-optimization agent-runbook ./your-site
|
|
|
60
64
|
npx geo-ai-search-optimization agent-executor ./your-site
|
|
61
65
|
npx geo-ai-search-optimization agent-batch-executor ./your-site
|
|
62
66
|
npx geo-ai-search-optimization agent-progress-tracker ./your-site
|
|
67
|
+
npx geo-ai-search-optimization agent-status-board ./your-site
|
|
68
|
+
npx geo-ai-search-optimization agent-checkpoint ./your-site
|
|
63
69
|
npx geo-ai-search-optimization scan ./your-site
|
|
64
70
|
npx geo-ai-search-optimization audit ./your-site
|
|
65
71
|
npx geo-ai-search-optimization fix-plan ./your-site
|
|
@@ -83,6 +89,8 @@ npx geo-ai-search-optimization roadmap ./your-site
|
|
|
83
89
|
- `agent-executor`: select one packet to execute now and package it into a single-task entrypoint
|
|
84
90
|
- `agent-batch-executor`: line up the first few packets in execution order while preserving one-packet-at-a-time discipline
|
|
85
91
|
- `agent-progress-tracker`: show execution progress, current packet, blockers, and the next packet to advance
|
|
92
|
+
- `agent-status-board`: present the current execution state as a board with done, in-progress, blocked, next, and queued columns
|
|
93
|
+
- `agent-checkpoint`: convert the current round into a checkpoint decision for continue, unblock, or closeout
|
|
86
94
|
- `onboard-url`: first-time website check from a live URL
|
|
87
95
|
- `onboard`: interactive first-time onboarding
|
|
88
96
|
- `skills`: list the bundled skills and decide which skill or command chain fits the task
|
|
@@ -113,6 +121,8 @@ When explaining the tool to a user:
|
|
|
113
121
|
- if the user wants the next agent to start one concrete task now, move them to `agent-executor`
|
|
114
122
|
- 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
123
|
- if the user wants the next agent to explain current progress, blockers, and the next packet, move them to `agent-progress-tracker`
|
|
124
|
+
- if the user wants the next agent to present execution state as a board for PM and agent coordination, move them to `agent-status-board`
|
|
125
|
+
- if the user wants a per-round decision artifact that says continue, unblock, or close out, move them to `agent-checkpoint`
|
|
116
126
|
- explain the result in PM language, not implementation jargon
|
|
117
127
|
- if the user sounds new, start with `onboard-url` or `quick-start`
|
|
118
128
|
- if the user wants another agent to take over, move them to `agent-handoff`
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
createAgentStatusBoard,
|
|
5
|
+
renderAgentStatusBoardMarkdown,
|
|
6
|
+
writeAgentStatusBoardOutput
|
|
7
|
+
} from "./agent-status-board.js";
|
|
8
|
+
|
|
9
|
+
const VALID_FORMATS = new Set(["markdown", "json"]);
|
|
10
|
+
|
|
11
|
+
function normalizeFormat(format) {
|
|
12
|
+
const resolved = (format || "markdown").toLowerCase();
|
|
13
|
+
if (!VALID_FORMATS.has(resolved)) {
|
|
14
|
+
throw new Error(`不支持的 agent-checkpoint 格式:${format}。可选值:${Array.from(VALID_FORMATS).join(", ")}`);
|
|
15
|
+
}
|
|
16
|
+
return resolved;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function pathExists(targetPath) {
|
|
20
|
+
try {
|
|
21
|
+
await fs.access(targetPath);
|
|
22
|
+
return true;
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function resolveStatusBoard(input, options = {}) {
|
|
29
|
+
const resolvedPath = path.resolve(input);
|
|
30
|
+
if (await pathExists(resolvedPath)) {
|
|
31
|
+
try {
|
|
32
|
+
const raw = await fs.readFile(resolvedPath, "utf8");
|
|
33
|
+
const parsed = JSON.parse(raw);
|
|
34
|
+
if (parsed?.kind === "geo-agent-checkpoint" && parsed.statusBoard?.kind === "geo-agent-status-board") {
|
|
35
|
+
return createAgentStatusBoard(parsed.statusBoard.source || input, {
|
|
36
|
+
format: "json",
|
|
37
|
+
currentTaskId: options.currentTaskId || parsed.currentPacket?.id || parsed.statusBoard.tracker?.currentTaskId,
|
|
38
|
+
completedPacketIds:
|
|
39
|
+
options.completedPacketIds != null
|
|
40
|
+
? options.completedPacketIds
|
|
41
|
+
: (parsed.statusBoard.tracker?.completedPacketIds || []).join(","),
|
|
42
|
+
blockedReasons:
|
|
43
|
+
options.blockedReasons != null
|
|
44
|
+
? options.blockedReasons
|
|
45
|
+
: (parsed.statusBoard.tracker?.blockedReasons || []).join(",")
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
// Fall through to status board generation
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return createAgentStatusBoard(input, {
|
|
54
|
+
format: "json",
|
|
55
|
+
currentTaskId: options.currentTaskId,
|
|
56
|
+
completedPacketIds: options.completedPacketIds,
|
|
57
|
+
blockedReasons: options.blockedReasons
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function inferDecision(board) {
|
|
62
|
+
switch (board.boardStatus) {
|
|
63
|
+
case "blocked":
|
|
64
|
+
return "resolve-blockers";
|
|
65
|
+
case "completed":
|
|
66
|
+
return "move-to-closeout";
|
|
67
|
+
case "in-progress":
|
|
68
|
+
return "continue-current-packet";
|
|
69
|
+
case "not-started":
|
|
70
|
+
return "start-first-packet";
|
|
71
|
+
default:
|
|
72
|
+
return "gather-context";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function inferCheckpointType(decision) {
|
|
77
|
+
switch (decision) {
|
|
78
|
+
case "resolve-blockers":
|
|
79
|
+
return "blocker-checkpoint";
|
|
80
|
+
case "move-to-closeout":
|
|
81
|
+
return "closeout-checkpoint";
|
|
82
|
+
case "continue-current-packet":
|
|
83
|
+
case "start-first-packet":
|
|
84
|
+
return "execution-checkpoint";
|
|
85
|
+
default:
|
|
86
|
+
return "context-checkpoint";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function buildDecisionReason(board, decision) {
|
|
91
|
+
switch (decision) {
|
|
92
|
+
case "resolve-blockers":
|
|
93
|
+
return `当前存在 ${board.columns.blocked.length} 个阻塞项,先解除阻塞,再继续推进 ${board.columns.inProgress[0]?.id || "当前包"}。`;
|
|
94
|
+
case "move-to-closeout":
|
|
95
|
+
return "当前执行包已经全部完成,适合进入复盘、交接和交付阶段。";
|
|
96
|
+
case "continue-current-packet":
|
|
97
|
+
return `当前已有明确执行包 ${board.columns.inProgress[0]?.id || ""},且没有阻塞,可以继续推进。`;
|
|
98
|
+
case "start-first-packet":
|
|
99
|
+
return `当前尚未开始,但第一包 ${board.columns.inProgress[0]?.id || ""} 已经明确,可以直接启动。`;
|
|
100
|
+
default:
|
|
101
|
+
return "当前还缺执行上下文,先补充上下文再做下一步决策。";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function buildGateChecks(board, decision) {
|
|
106
|
+
const hasActive = board.columns.inProgress.length > 0;
|
|
107
|
+
const hasBlockers = board.columns.blocked.length > 0;
|
|
108
|
+
const canCloseout = board.boardStatus === "completed";
|
|
109
|
+
const hasNextCommand = Boolean(board.suggestedNextCommand);
|
|
110
|
+
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
id: "gate-active-packet",
|
|
114
|
+
label: "当前是否有明确执行包",
|
|
115
|
+
status: hasActive ? "pass" : "fail",
|
|
116
|
+
detail: hasActive ? `当前包:${board.columns.inProgress[0].id}` : "当前没有明确执行包。"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: "gate-blockers",
|
|
120
|
+
label: "当前是否无阻塞",
|
|
121
|
+
status: hasBlockers ? "fail" : "pass",
|
|
122
|
+
detail: hasBlockers ? `阻塞数:${board.columns.blocked.length}` : "当前没有阻塞。"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: "gate-closeout",
|
|
126
|
+
label: "是否达到收尾条件",
|
|
127
|
+
status: canCloseout ? "pass" : "warn",
|
|
128
|
+
detail: canCloseout ? "已可进入 closeout。" : "当前仍处于执行中或待开始。"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: "gate-next-command",
|
|
132
|
+
label: "是否有下一步命令",
|
|
133
|
+
status: hasNextCommand ? "pass" : "fail",
|
|
134
|
+
detail: hasNextCommand ? board.suggestedNextCommand : "还没有稳定的下一步命令。"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "gate-decision-fit",
|
|
138
|
+
label: "当前决策是否匹配状态",
|
|
139
|
+
status:
|
|
140
|
+
(decision === "resolve-blockers" && hasBlockers) ||
|
|
141
|
+
(decision === "move-to-closeout" && canCloseout) ||
|
|
142
|
+
(decision === "continue-current-packet" && hasActive && !hasBlockers) ||
|
|
143
|
+
(decision === "start-first-packet" && board.boardStatus === "not-started") ||
|
|
144
|
+
(decision === "gather-context" && board.boardStatus === "needs-context")
|
|
145
|
+
? "pass"
|
|
146
|
+
: "warn",
|
|
147
|
+
detail: `当前决策:${decision}`
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function buildDecisionChecklist(decision) {
|
|
153
|
+
switch (decision) {
|
|
154
|
+
case "resolve-blockers":
|
|
155
|
+
return [
|
|
156
|
+
"先确认阻塞是不是会影响当前包验收。",
|
|
157
|
+
"先补权限、仓库、模板或关键上下文。",
|
|
158
|
+
"阻塞解除后,重新生成 progress tracker 或 status board。"
|
|
159
|
+
];
|
|
160
|
+
case "move-to-closeout":
|
|
161
|
+
return [
|
|
162
|
+
"确认本轮执行包已全部完成。",
|
|
163
|
+
"进入 completion-report,总结已完成、剩余风险和下一轮任务。",
|
|
164
|
+
"进入 handoff-bundle 或 publish-pack 进行交接或交付。"
|
|
165
|
+
];
|
|
166
|
+
case "continue-current-packet":
|
|
167
|
+
return [
|
|
168
|
+
"继续推进当前执行包,不要切换到其他包。",
|
|
169
|
+
"先完成当前包的验证与回报,再进入下一包。",
|
|
170
|
+
"完成后重新生成 progress tracker 或 status board。"
|
|
171
|
+
];
|
|
172
|
+
case "start-first-packet":
|
|
173
|
+
return [
|
|
174
|
+
"从第一包开始执行。",
|
|
175
|
+
"不要同时展开多包任务。",
|
|
176
|
+
"开始后马上用 progress tracker 记录当前包。"
|
|
177
|
+
];
|
|
178
|
+
default:
|
|
179
|
+
return [
|
|
180
|
+
"先补仓库、模板、页面或执行工件上下文。",
|
|
181
|
+
"补完上下文后重新生成 checkpoint。",
|
|
182
|
+
"不要假装已经进入执行阶段。"
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function buildSuggestedNextCommand(board, decision) {
|
|
188
|
+
if (decision === "move-to-closeout") {
|
|
189
|
+
return `geo-ai-search-optimization completion-report ${board.source}`;
|
|
190
|
+
}
|
|
191
|
+
if (decision === "gather-context") {
|
|
192
|
+
return `geo-ai-search-optimization agent-session ${board.source}`;
|
|
193
|
+
}
|
|
194
|
+
return board.suggestedNextCommand;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function buildAlternateCommands(board, decision) {
|
|
198
|
+
const commands = new Set();
|
|
199
|
+
|
|
200
|
+
if (decision === "resolve-blockers") {
|
|
201
|
+
commands.add(board.suggestedNextCommand);
|
|
202
|
+
commands.add(`geo-ai-search-optimization agent-status-board ${board.source}`);
|
|
203
|
+
commands.add(`geo-ai-search-optimization agent-progress-tracker ${board.source}`);
|
|
204
|
+
} else if (decision === "move-to-closeout") {
|
|
205
|
+
commands.add(`geo-ai-search-optimization handoff-bundle ${board.source}`);
|
|
206
|
+
commands.add(`geo-ai-search-optimization publish-pack ${board.source}`);
|
|
207
|
+
} else if (decision === "continue-current-packet" || decision === "start-first-packet") {
|
|
208
|
+
commands.add(board.suggestedNextCommand);
|
|
209
|
+
commands.add(`geo-ai-search-optimization agent-progress-tracker ${board.source}`);
|
|
210
|
+
commands.add(`geo-ai-search-optimization agent-status-board ${board.source}`);
|
|
211
|
+
} else {
|
|
212
|
+
commands.add(`geo-ai-search-optimization agent-session ${board.source}`);
|
|
213
|
+
commands.add(`geo-ai-search-optimization agent-runbook ${board.source}`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return Array.from(commands).filter(Boolean);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function buildHandoffNote(board, decision) {
|
|
220
|
+
switch (decision) {
|
|
221
|
+
case "resolve-blockers":
|
|
222
|
+
return "下一位 agent 先不要继续修代码,先解除阻塞项,再回到当前执行包。";
|
|
223
|
+
case "move-to-closeout":
|
|
224
|
+
return "下一位 agent 可以直接进入复盘、交接和交付流程。";
|
|
225
|
+
case "continue-current-packet":
|
|
226
|
+
return `下一位 agent 继续当前包 ${board.columns.inProgress[0]?.id || ""},不要切换任务。`;
|
|
227
|
+
case "start-first-packet":
|
|
228
|
+
return `下一位 agent 从第一包 ${board.columns.inProgress[0]?.id || ""} 开始。`;
|
|
229
|
+
default:
|
|
230
|
+
return "下一位 agent 先补上下文,不要直接开始修改。";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function buildCheckpointPrompt(checkpoint) {
|
|
235
|
+
const lines = [
|
|
236
|
+
"你现在进入 GEO 阶段检查点模式。",
|
|
237
|
+
`当前输入:${checkpoint.source}`,
|
|
238
|
+
`检查点类型:${checkpoint.checkpointType}`,
|
|
239
|
+
`当前状态:${checkpoint.boardStatus}`,
|
|
240
|
+
`当前决策:${checkpoint.decision}`,
|
|
241
|
+
`决策原因:${checkpoint.decisionReason}`
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
if (checkpoint.currentPacket) {
|
|
245
|
+
lines.push(`当前包:${checkpoint.currentPacket.id}|${checkpoint.currentPacket.title}`);
|
|
246
|
+
}
|
|
247
|
+
if (checkpoint.nextPacket) {
|
|
248
|
+
lines.push(`下一包:${checkpoint.nextPacket.id}|${checkpoint.nextPacket.title}`);
|
|
249
|
+
}
|
|
250
|
+
if (checkpoint.blockedItems.length > 0) {
|
|
251
|
+
lines.push(`阻塞项:${checkpoint.blockedItems.map((item) => item.title).join(";")}`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
lines.push("请先回答:现在该继续、该解除阻塞,还是该进入收尾。");
|
|
255
|
+
lines.push("然后给出本轮 checkpoint 结论、下一步命令和交接说明。");
|
|
256
|
+
return lines.join("\n");
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export async function createAgentCheckpoint(input, options = {}) {
|
|
260
|
+
const format = normalizeFormat(options.format);
|
|
261
|
+
const statusBoard = await resolveStatusBoard(input, options);
|
|
262
|
+
const decision = inferDecision(statusBoard);
|
|
263
|
+
|
|
264
|
+
const checkpoint = {
|
|
265
|
+
kind: "geo-agent-checkpoint",
|
|
266
|
+
input,
|
|
267
|
+
source: statusBoard.source,
|
|
268
|
+
sourceType: statusBoard.sourceType,
|
|
269
|
+
artifactKind: statusBoard.kind,
|
|
270
|
+
format,
|
|
271
|
+
checkpointType: inferCheckpointType(decision),
|
|
272
|
+
boardStatus: statusBoard.boardStatus,
|
|
273
|
+
decision,
|
|
274
|
+
decisionReason: buildDecisionReason(statusBoard, decision),
|
|
275
|
+
progressPercent: statusBoard.progressPercent,
|
|
276
|
+
currentPacket: statusBoard.columns.inProgress[0] || null,
|
|
277
|
+
nextPacket: statusBoard.columns.nextUp[0] || null,
|
|
278
|
+
completedPackets: statusBoard.columns.completed,
|
|
279
|
+
blockedItems: statusBoard.columns.blocked,
|
|
280
|
+
gateChecks: buildGateChecks(statusBoard, decision),
|
|
281
|
+
decisionChecklist: buildDecisionChecklist(decision),
|
|
282
|
+
suggestedNextCommand: buildSuggestedNextCommand(statusBoard, decision),
|
|
283
|
+
alternateCommands: buildAlternateCommands(statusBoard, decision),
|
|
284
|
+
handoffNote: buildHandoffNote(statusBoard, decision),
|
|
285
|
+
checkpointPrompt: "",
|
|
286
|
+
statusBoard
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
checkpoint.checkpointPrompt = buildCheckpointPrompt(checkpoint);
|
|
290
|
+
return checkpoint;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function renderAgentCheckpointMarkdown(checkpoint) {
|
|
294
|
+
const lines = [
|
|
295
|
+
"# GEO Agent Checkpoint",
|
|
296
|
+
"",
|
|
297
|
+
`- 输入:\`${checkpoint.source}\``,
|
|
298
|
+
`- 来源类型:\`${checkpoint.sourceType}\``,
|
|
299
|
+
`- 工件类型:\`${checkpoint.artifactKind}\``,
|
|
300
|
+
`- 检查点类型:\`${checkpoint.checkpointType}\``,
|
|
301
|
+
`- 当前状态:\`${checkpoint.boardStatus}\``,
|
|
302
|
+
`- 当前决策:\`${checkpoint.decision}\``,
|
|
303
|
+
`- 进度:\`${checkpoint.progressPercent}%\``,
|
|
304
|
+
`- 决策原因:${checkpoint.decisionReason}`,
|
|
305
|
+
""
|
|
306
|
+
];
|
|
307
|
+
|
|
308
|
+
if (checkpoint.currentPacket) {
|
|
309
|
+
lines.push("## 当前包", "");
|
|
310
|
+
lines.push(`- ${checkpoint.currentPacket.id}|${checkpoint.currentPacket.title}`);
|
|
311
|
+
lines.push(`- Owner:${checkpoint.currentPacket.owner}`);
|
|
312
|
+
lines.push(`- 优先级:${checkpoint.currentPacket.priority}`);
|
|
313
|
+
lines.push("");
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (checkpoint.nextPacket) {
|
|
317
|
+
lines.push("## 下一包", "");
|
|
318
|
+
lines.push(`- ${checkpoint.nextPacket.id}|${checkpoint.nextPacket.title}`);
|
|
319
|
+
lines.push(`- Owner:${checkpoint.nextPacket.owner}`);
|
|
320
|
+
lines.push(`- 优先级:${checkpoint.nextPacket.priority}`);
|
|
321
|
+
lines.push("");
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
lines.push("## Gate Checks", "");
|
|
325
|
+
for (const gate of checkpoint.gateChecks) {
|
|
326
|
+
lines.push(`- [${gate.status}] ${gate.label}:${gate.detail}`);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
lines.push("", "## 决策清单", "");
|
|
330
|
+
for (const item of checkpoint.decisionChecklist) {
|
|
331
|
+
lines.push(`- [ ] ${item}`);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
lines.push("", "## 建议下一步命令", "");
|
|
335
|
+
lines.push(`- \`${checkpoint.suggestedNextCommand}\``);
|
|
336
|
+
|
|
337
|
+
lines.push("", "## 备选命令", "");
|
|
338
|
+
for (const command of checkpoint.alternateCommands) {
|
|
339
|
+
lines.push(`- \`${command}\``);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
lines.push("", "## 交接说明", "");
|
|
343
|
+
lines.push(`- ${checkpoint.handoffNote}`);
|
|
344
|
+
|
|
345
|
+
lines.push("", "## 可直接复制给 Agent 的 Checkpoint Prompt", "", "```text");
|
|
346
|
+
lines.push(checkpoint.checkpointPrompt);
|
|
347
|
+
lines.push("```");
|
|
348
|
+
|
|
349
|
+
lines.push("", "## 状态看板", "");
|
|
350
|
+
lines.push(renderAgentStatusBoardMarkdown(checkpoint.statusBoard).trim());
|
|
351
|
+
lines.push("");
|
|
352
|
+
|
|
353
|
+
return `${lines.join("\n")}\n`;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export async function writeAgentCheckpointOutput(outputPath, content) {
|
|
357
|
+
return writeAgentStatusBoardOutput(outputPath, content);
|
|
358
|
+
}
|
|
@@ -120,6 +120,54 @@ function buildExecutionContextFromParsedArtifact(parsed, input) {
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
if (parsed?.kind === "geo-agent-status-board" && parsed.tracker?.applyPlan?.kind === "geo-apply-plan") {
|
|
124
|
+
return {
|
|
125
|
+
source: parsed.source || parsed.tracker.source || parsed.tracker.applyPlan.source || input,
|
|
126
|
+
sourceType: parsed.sourceType || parsed.tracker.sourceType || parsed.tracker.applyPlan.sourceType || "json",
|
|
127
|
+
artifactKind: parsed.kind,
|
|
128
|
+
applyPlan: parsed.tracker.applyPlan,
|
|
129
|
+
trackerState: {
|
|
130
|
+
currentTaskId: parsed.tracker.currentTaskId || parsed.tracker.activePacket?.id || null,
|
|
131
|
+
completedPacketIds: parsed.tracker.completedPacketIds || [],
|
|
132
|
+
blockedReasons: parsed.tracker.blockedReasons || []
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (parsed?.kind === "geo-agent-checkpoint" && parsed.statusBoard?.tracker?.applyPlan?.kind === "geo-apply-plan") {
|
|
138
|
+
return {
|
|
139
|
+
source:
|
|
140
|
+
parsed.source ||
|
|
141
|
+
parsed.statusBoard.source ||
|
|
142
|
+
parsed.statusBoard.tracker.source ||
|
|
143
|
+
parsed.statusBoard.tracker.applyPlan.source ||
|
|
144
|
+
input,
|
|
145
|
+
sourceType:
|
|
146
|
+
parsed.sourceType ||
|
|
147
|
+
parsed.statusBoard.sourceType ||
|
|
148
|
+
parsed.statusBoard.tracker.sourceType ||
|
|
149
|
+
parsed.statusBoard.tracker.applyPlan.sourceType ||
|
|
150
|
+
"json",
|
|
151
|
+
artifactKind: parsed.kind,
|
|
152
|
+
applyPlan: parsed.statusBoard.tracker.applyPlan,
|
|
153
|
+
trackerState: {
|
|
154
|
+
currentTaskId:
|
|
155
|
+
parsed.currentPacket?.id ||
|
|
156
|
+
parsed.statusBoard.tracker.currentTaskId ||
|
|
157
|
+
parsed.statusBoard.tracker.activePacket?.id ||
|
|
158
|
+
null,
|
|
159
|
+
completedPacketIds:
|
|
160
|
+
parsed.statusBoard.tracker.completedPacketIds ||
|
|
161
|
+
parsed.completedPackets?.map((packet) => packet.id) ||
|
|
162
|
+
[],
|
|
163
|
+
blockedReasons:
|
|
164
|
+
parsed.statusBoard.tracker.blockedReasons ||
|
|
165
|
+
parsed.blockedItems?.map((item) => item.title) ||
|
|
166
|
+
[]
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
123
171
|
if (parsed?.kind === "geo-completion-report") {
|
|
124
172
|
return {
|
|
125
173
|
source: parsed.source || input,
|
package/src/agent-session.js
CHANGED
|
@@ -58,6 +58,12 @@ function inferSkillForCommand(commandName, flow) {
|
|
|
58
58
|
if (commandName === "agent-progress-tracker") {
|
|
59
59
|
return "geo-ai-search-optimization-agent-progress-tracker";
|
|
60
60
|
}
|
|
61
|
+
if (commandName === "agent-status-board") {
|
|
62
|
+
return "geo-ai-search-optimization-agent-status-board";
|
|
63
|
+
}
|
|
64
|
+
if (commandName === "agent-checkpoint") {
|
|
65
|
+
return "geo-ai-search-optimization-agent-checkpoint";
|
|
66
|
+
}
|
|
61
67
|
if (commandName === "skills" || commandName === "quick-start") {
|
|
62
68
|
return "geo-ai-search-optimization-usage";
|
|
63
69
|
}
|
|
@@ -126,6 +132,10 @@ function inferStepPurpose(commandName, flow) {
|
|
|
126
132
|
return "把前几包任务排成连续执行顺序,但保持一次只推进一包。";
|
|
127
133
|
case "agent-progress-tracker":
|
|
128
134
|
return "追踪当前做到第几包、卡点在哪里,以及下一包该推进什么。";
|
|
135
|
+
case "agent-status-board":
|
|
136
|
+
return "把当前执行状态整理成 PM 和 agent 都能直接消费的分栏看板。";
|
|
137
|
+
case "agent-checkpoint":
|
|
138
|
+
return "把当前阶段压成继续 / 阻塞 / 收尾的决策检查点。";
|
|
129
139
|
case "apply-plan":
|
|
130
140
|
return "把交接结果推进到具体执行包。";
|
|
131
141
|
case "completion-report":
|
|
@@ -174,6 +184,10 @@ function inferExpectedArtifact(commandName) {
|
|
|
174
184
|
return "agent 多任务批次执行包";
|
|
175
185
|
case "agent-progress-tracker":
|
|
176
186
|
return "agent 执行进度追踪工件";
|
|
187
|
+
case "agent-status-board":
|
|
188
|
+
return "agent 执行状态看板";
|
|
189
|
+
case "agent-checkpoint":
|
|
190
|
+
return "agent 阶段检查点工件";
|
|
177
191
|
case "apply-plan":
|
|
178
192
|
return "执行包";
|
|
179
193
|
case "completion-report":
|
|
@@ -218,6 +232,12 @@ function buildStepInstructions(parsedCommand, flow) {
|
|
|
218
232
|
if (parsedCommand.commandName === "agent-progress-tracker") {
|
|
219
233
|
lines.push("这一步用于校准当前做到哪、当前卡点和下一包,不要跳过状态确认直接进入收尾。");
|
|
220
234
|
}
|
|
235
|
+
if (parsedCommand.commandName === "agent-status-board") {
|
|
236
|
+
lines.push("这一步用于把当前执行状态转成看板视图,方便 PM 和 agent 对齐当前阶段。");
|
|
237
|
+
}
|
|
238
|
+
if (parsedCommand.commandName === "agent-checkpoint") {
|
|
239
|
+
lines.push("这一步用于明确此刻应该继续、先解除阻塞,还是进入收尾。");
|
|
240
|
+
}
|
|
221
241
|
if (parsedCommand.commandName === "agent-handoff" && flow.intent === "execute") {
|
|
222
242
|
lines.push("如果还是 advice-only,说明还缺仓库或本地项目上下文。");
|
|
223
243
|
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
createAgentProgressTracker,
|
|
5
|
+
renderAgentProgressTrackerMarkdown,
|
|
6
|
+
writeAgentProgressTrackerOutput
|
|
7
|
+
} from "./agent-progress-tracker.js";
|
|
8
|
+
|
|
9
|
+
const VALID_FORMATS = new Set(["markdown", "json"]);
|
|
10
|
+
|
|
11
|
+
function normalizeFormat(format) {
|
|
12
|
+
const resolved = (format || "markdown").toLowerCase();
|
|
13
|
+
if (!VALID_FORMATS.has(resolved)) {
|
|
14
|
+
throw new Error(`不支持的 agent-status-board 格式:${format}。可选值:${Array.from(VALID_FORMATS).join(", ")}`);
|
|
15
|
+
}
|
|
16
|
+
return resolved;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function pathExists(targetPath) {
|
|
20
|
+
try {
|
|
21
|
+
await fs.access(targetPath);
|
|
22
|
+
return true;
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function buildCard(packet, extra = {}) {
|
|
29
|
+
if (!packet) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
id: packet.id,
|
|
35
|
+
title: packet.title,
|
|
36
|
+
owner: packet.owner,
|
|
37
|
+
priority: packet.priority || "P1",
|
|
38
|
+
...extra
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function buildBlockedCards(tracker) {
|
|
43
|
+
if (tracker.blockedReasons.length === 0) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return tracker.blockedReasons.map((reason, index) => ({
|
|
48
|
+
id: `block-${index + 1}`,
|
|
49
|
+
title: reason,
|
|
50
|
+
owner: tracker.activePacket?.owner || "待确认",
|
|
51
|
+
priority: tracker.activePacket?.priority || "P1",
|
|
52
|
+
currentPacketId: tracker.activePacket?.id || null
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function buildQueuedCards(tracker) {
|
|
57
|
+
return tracker.remainingPackets
|
|
58
|
+
.filter((packet) => packet.id !== tracker.activePacket?.id && packet.id !== tracker.nextPacket?.id)
|
|
59
|
+
.map((packet) => buildCard(packet));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function buildColumns(tracker) {
|
|
63
|
+
return {
|
|
64
|
+
completed: tracker.completedPackets.map((packet) => buildCard(packet)),
|
|
65
|
+
inProgress: tracker.activePacket ? [buildCard(tracker.activePacket)] : [],
|
|
66
|
+
blocked: buildBlockedCards(tracker),
|
|
67
|
+
nextUp: tracker.nextPacket ? [buildCard(tracker.nextPacket)] : [],
|
|
68
|
+
queued: buildQueuedCards(tracker),
|
|
69
|
+
closeout:
|
|
70
|
+
tracker.status === "completed"
|
|
71
|
+
? [
|
|
72
|
+
{
|
|
73
|
+
id: "closeout-01",
|
|
74
|
+
title: "进入 completion-report / handoff-bundle / publish-pack",
|
|
75
|
+
owner: "PM / Agent",
|
|
76
|
+
priority: "P1"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
: []
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function buildBoardSummary(tracker) {
|
|
84
|
+
if (tracker.status === "blocked") {
|
|
85
|
+
return `当前执行被阻塞,先处理 ${tracker.blockedReasons.length} 个阻塞项,再继续推进 ${tracker.activePacket?.id || "当前包"}。`;
|
|
86
|
+
}
|
|
87
|
+
if (tracker.status === "completed") {
|
|
88
|
+
return "当前批次已完成,接下来适合进入复盘与交付阶段。";
|
|
89
|
+
}
|
|
90
|
+
if (tracker.status === "in-progress") {
|
|
91
|
+
return `当前正在推进 ${tracker.activePacket?.id || "当前包"},下一包是 ${tracker.nextPacket?.id || "收尾"}。`;
|
|
92
|
+
}
|
|
93
|
+
if (tracker.status === "not-started") {
|
|
94
|
+
return `当前还没开始,建议从 ${tracker.activePacket?.id || "第一包"} 启动。`;
|
|
95
|
+
}
|
|
96
|
+
return "当前还缺上下文,先补执行信息再进入状态看板。";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function buildBoardPrompt(board) {
|
|
100
|
+
const lines = [
|
|
101
|
+
"你现在进入 GEO 执行状态看板模式。",
|
|
102
|
+
`当前输入:${board.source}`,
|
|
103
|
+
`当前状态:${board.boardStatus}`,
|
|
104
|
+
`进度:${board.progressPercent}%`,
|
|
105
|
+
`看板总结:${board.boardSummary}`
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
if (board.columns.inProgress.length > 0) {
|
|
109
|
+
const current = board.columns.inProgress[0];
|
|
110
|
+
lines.push(`当前进行中:${current.id}|${current.title}`);
|
|
111
|
+
}
|
|
112
|
+
if (board.columns.nextUp.length > 0) {
|
|
113
|
+
const next = board.columns.nextUp[0];
|
|
114
|
+
lines.push(`下一步:${next.id}|${next.title}`);
|
|
115
|
+
}
|
|
116
|
+
if (board.columns.blocked.length > 0) {
|
|
117
|
+
lines.push(`阻塞项数量:${board.columns.blocked.length}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
lines.push("请按看板方式说明:已完成、进行中、阻塞、下一步、排队中的任务。");
|
|
121
|
+
return lines.join("\n");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function resolveTracker(input, options = {}) {
|
|
125
|
+
const resolvedPath = path.resolve(input);
|
|
126
|
+
if (await pathExists(resolvedPath)) {
|
|
127
|
+
try {
|
|
128
|
+
const raw = await fs.readFile(resolvedPath, "utf8");
|
|
129
|
+
const parsed = JSON.parse(raw);
|
|
130
|
+
if (parsed?.kind === "geo-agent-status-board" && parsed.tracker?.kind === "geo-agent-progress-tracker") {
|
|
131
|
+
return createAgentProgressTracker(parsed.tracker.source || input, {
|
|
132
|
+
format: "json",
|
|
133
|
+
currentTaskId: options.currentTaskId || parsed.tracker.currentTaskId,
|
|
134
|
+
completedPacketIds:
|
|
135
|
+
options.completedPacketIds != null
|
|
136
|
+
? options.completedPacketIds
|
|
137
|
+
: (parsed.tracker.completedPacketIds || []).join(","),
|
|
138
|
+
blockedReasons:
|
|
139
|
+
options.blockedReasons != null ? options.blockedReasons : (parsed.tracker.blockedReasons || []).join(",")
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (parsed?.kind === "geo-agent-checkpoint" && parsed.statusBoard?.tracker?.kind === "geo-agent-progress-tracker") {
|
|
143
|
+
return createAgentProgressTracker(parsed.statusBoard.tracker.source || input, {
|
|
144
|
+
format: "json",
|
|
145
|
+
currentTaskId:
|
|
146
|
+
options.currentTaskId || parsed.currentPacket?.id || parsed.statusBoard.tracker.currentTaskId,
|
|
147
|
+
completedPacketIds:
|
|
148
|
+
options.completedPacketIds != null
|
|
149
|
+
? options.completedPacketIds
|
|
150
|
+
: (parsed.statusBoard.tracker.completedPacketIds || []).join(","),
|
|
151
|
+
blockedReasons:
|
|
152
|
+
options.blockedReasons != null
|
|
153
|
+
? options.blockedReasons
|
|
154
|
+
: (parsed.statusBoard.tracker.blockedReasons || []).join(",")
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
// Fall through to tracker generation
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return createAgentProgressTracker(input, {
|
|
163
|
+
format: "json",
|
|
164
|
+
currentTaskId: options.currentTaskId,
|
|
165
|
+
completedPacketIds: options.completedPacketIds,
|
|
166
|
+
blockedReasons: options.blockedReasons
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export async function createAgentStatusBoard(input, options = {}) {
|
|
171
|
+
const format = normalizeFormat(options.format);
|
|
172
|
+
const tracker = await resolveTracker(input, options);
|
|
173
|
+
const columns = buildColumns(tracker);
|
|
174
|
+
|
|
175
|
+
const board = {
|
|
176
|
+
kind: "geo-agent-status-board",
|
|
177
|
+
input,
|
|
178
|
+
source: tracker.source,
|
|
179
|
+
sourceType: tracker.sourceType,
|
|
180
|
+
artifactKind: tracker.artifactKind,
|
|
181
|
+
format,
|
|
182
|
+
boardStatus: tracker.status,
|
|
183
|
+
boardSummary: buildBoardSummary(tracker),
|
|
184
|
+
progressPercent: tracker.progressPercent,
|
|
185
|
+
totalPackets: tracker.totalPackets,
|
|
186
|
+
completedCount: tracker.completedCount,
|
|
187
|
+
remainingCount: tracker.remainingCount,
|
|
188
|
+
columns,
|
|
189
|
+
suggestedNextCommand: tracker.suggestedNextCommand,
|
|
190
|
+
followupCommands: tracker.followupCommands,
|
|
191
|
+
boardPrompt: "",
|
|
192
|
+
tracker
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
board.boardPrompt = buildBoardPrompt(board);
|
|
196
|
+
return board;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function renderAgentStatusBoardMarkdown(board) {
|
|
200
|
+
const lines = [
|
|
201
|
+
"# GEO Agent Status Board",
|
|
202
|
+
"",
|
|
203
|
+
`- 输入:\`${board.source}\``,
|
|
204
|
+
`- 来源类型:\`${board.sourceType}\``,
|
|
205
|
+
`- 工件类型:\`${board.artifactKind}\``,
|
|
206
|
+
`- 看板状态:\`${board.boardStatus}\``,
|
|
207
|
+
`- 进度:\`${board.progressPercent}%\``,
|
|
208
|
+
`- 已完成:\`${board.completedCount}/${board.totalPackets}\``,
|
|
209
|
+
`- 看板总结:${board.boardSummary}`,
|
|
210
|
+
""
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
const sections = [
|
|
214
|
+
["已完成", board.columns.completed],
|
|
215
|
+
["进行中", board.columns.inProgress],
|
|
216
|
+
["阻塞", board.columns.blocked],
|
|
217
|
+
["下一步", board.columns.nextUp],
|
|
218
|
+
["排队中", board.columns.queued],
|
|
219
|
+
["收尾", board.columns.closeout]
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
for (const [label, items] of sections) {
|
|
223
|
+
lines.push(`## ${label}`, "");
|
|
224
|
+
if (items.length === 0) {
|
|
225
|
+
lines.push("- 当前没有内容。", "");
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (const item of items) {
|
|
230
|
+
lines.push(`- ${item.id}|${item.title}`);
|
|
231
|
+
lines.push(` - Owner:${item.owner}`);
|
|
232
|
+
lines.push(` - 优先级:${item.priority}`);
|
|
233
|
+
if (item.currentPacketId) {
|
|
234
|
+
lines.push(` - 当前关联包:${item.currentPacketId}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
lines.push("");
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
lines.push("## 建议下一步命令", "");
|
|
241
|
+
lines.push(`- \`${board.suggestedNextCommand}\``);
|
|
242
|
+
|
|
243
|
+
lines.push("", "## 后续命令", "");
|
|
244
|
+
for (const command of board.followupCommands) {
|
|
245
|
+
lines.push(`- \`${command}\``);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
lines.push("", "## 可直接复制给 Agent 的 Status Board Prompt", "", "```text");
|
|
249
|
+
lines.push(board.boardPrompt || buildBoardPrompt(board));
|
|
250
|
+
lines.push("```");
|
|
251
|
+
|
|
252
|
+
lines.push("", "## 详细进度追踪", "");
|
|
253
|
+
lines.push(renderAgentProgressTrackerMarkdown(board.tracker).trim());
|
|
254
|
+
lines.push("");
|
|
255
|
+
|
|
256
|
+
return `${lines.join("\n")}\n`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export async function writeAgentStatusBoardOutput(outputPath, content) {
|
|
260
|
+
return writeAgentProgressTrackerOutput(outputPath, content);
|
|
261
|
+
}
|
package/src/auto-flow.js
CHANGED
|
@@ -50,6 +50,12 @@ function inferTaskTextMode(text) {
|
|
|
50
50
|
if (/(progress-tracker|progress tracker|进度追踪|做到第几包|卡在哪|下一包是什么)/i.test(normalized)) {
|
|
51
51
|
return "execute";
|
|
52
52
|
}
|
|
53
|
+
if (/(status-board|status board|状态看板|执行看板|看板视图|board 视图)/i.test(normalized)) {
|
|
54
|
+
return "execute";
|
|
55
|
+
}
|
|
56
|
+
if (/(checkpoint|检查点|阶段检查点|继续还是收尾|解除阻塞还是继续)/i.test(normalized)) {
|
|
57
|
+
return "execute";
|
|
58
|
+
}
|
|
53
59
|
if (/(executor|先做哪一个|先做哪一包|single task|执行第一包|先执行一个任务)/i.test(normalized)) {
|
|
54
60
|
return "execute";
|
|
55
61
|
}
|
|
@@ -169,6 +175,8 @@ function resolveEffectiveIntent(intent, detected) {
|
|
|
169
175
|
"geo-agent-executor",
|
|
170
176
|
"geo-agent-batch-executor",
|
|
171
177
|
"geo-agent-progress-tracker",
|
|
178
|
+
"geo-agent-status-board",
|
|
179
|
+
"geo-agent-checkpoint",
|
|
172
180
|
"geo-apply-plan",
|
|
173
181
|
"geo-handoff-bundle",
|
|
174
182
|
"geo-fix-plan"
|
|
@@ -329,6 +337,42 @@ function buildCommandChain(detected, intent) {
|
|
|
329
337
|
`geo-ai-search-optimization completion-report ${source}`,
|
|
330
338
|
`geo-ai-search-optimization handoff-bundle ${source}`
|
|
331
339
|
];
|
|
340
|
+
case "geo-agent-status-board":
|
|
341
|
+
return detected.parsed?.boardStatus === "completed"
|
|
342
|
+
? [
|
|
343
|
+
`geo-ai-search-optimization completion-report ${source}`,
|
|
344
|
+
`geo-ai-search-optimization handoff-bundle ${source}`,
|
|
345
|
+
`geo-ai-search-optimization publish-pack ${source}`
|
|
346
|
+
]
|
|
347
|
+
: detected.parsed?.tracker?.currentTaskId
|
|
348
|
+
? [
|
|
349
|
+
`geo-ai-search-optimization agent-executor ${source} --task ${detected.parsed.tracker.currentTaskId}`,
|
|
350
|
+
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
351
|
+
`geo-ai-search-optimization completion-report ${source}`
|
|
352
|
+
]
|
|
353
|
+
: [
|
|
354
|
+
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
355
|
+
`geo-ai-search-optimization completion-report ${source}`,
|
|
356
|
+
`geo-ai-search-optimization handoff-bundle ${source}`
|
|
357
|
+
];
|
|
358
|
+
case "geo-agent-checkpoint":
|
|
359
|
+
return detected.parsed?.decision === "move-to-closeout"
|
|
360
|
+
? [
|
|
361
|
+
`geo-ai-search-optimization completion-report ${source}`,
|
|
362
|
+
`geo-ai-search-optimization handoff-bundle ${source}`,
|
|
363
|
+
`geo-ai-search-optimization publish-pack ${source}`
|
|
364
|
+
]
|
|
365
|
+
: detected.parsed?.decision === "resolve-blockers"
|
|
366
|
+
? [
|
|
367
|
+
detected.parsed.suggestedNextCommand || `geo-ai-search-optimization agent-runbook ${source}`,
|
|
368
|
+
`geo-ai-search-optimization agent-status-board ${source}`,
|
|
369
|
+
`geo-ai-search-optimization agent-progress-tracker ${source}`
|
|
370
|
+
]
|
|
371
|
+
: [
|
|
372
|
+
detected.parsed?.suggestedNextCommand || `geo-ai-search-optimization agent-executor ${source}`,
|
|
373
|
+
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
374
|
+
`geo-ai-search-optimization completion-report ${source}`
|
|
375
|
+
];
|
|
332
376
|
case "geo-apply-plan":
|
|
333
377
|
return [
|
|
334
378
|
`geo-ai-search-optimization agent-executor ${source}`,
|
|
@@ -406,6 +450,10 @@ function pickSkillName(detected, intent) {
|
|
|
406
450
|
return "geo-ai-search-optimization-agent-batch-executor";
|
|
407
451
|
case "geo-agent-progress-tracker":
|
|
408
452
|
return "geo-ai-search-optimization-agent-progress-tracker";
|
|
453
|
+
case "geo-agent-status-board":
|
|
454
|
+
return "geo-ai-search-optimization-agent-status-board";
|
|
455
|
+
case "geo-agent-checkpoint":
|
|
456
|
+
return "geo-ai-search-optimization-agent-checkpoint";
|
|
409
457
|
case "geo-completion-report":
|
|
410
458
|
return "geo-ai-search-optimization-completion-report";
|
|
411
459
|
case "geo-handoff-bundle":
|
|
@@ -444,6 +492,8 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
444
492
|
"geo-agent-executor",
|
|
445
493
|
"geo-agent-batch-executor",
|
|
446
494
|
"geo-agent-progress-tracker",
|
|
495
|
+
"geo-agent-status-board",
|
|
496
|
+
"geo-agent-checkpoint",
|
|
447
497
|
"geo-apply-plan"
|
|
448
498
|
].includes(
|
|
449
499
|
detected.artifactKind
|
|
@@ -451,6 +501,8 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
451
501
|
) {
|
|
452
502
|
names.add("geo-ai-search-optimization-agent-batch-executor");
|
|
453
503
|
names.add("geo-ai-search-optimization-agent-progress-tracker");
|
|
504
|
+
names.add("geo-ai-search-optimization-agent-status-board");
|
|
505
|
+
names.add("geo-ai-search-optimization-agent-checkpoint");
|
|
454
506
|
names.add("geo-ai-search-optimization-agent-executor");
|
|
455
507
|
names.add("geo-ai-search-optimization-agent-runbook");
|
|
456
508
|
names.add("geo-ai-search-optimization-agent-handoff");
|
|
@@ -482,6 +534,8 @@ function buildStage(intent, detected) {
|
|
|
482
534
|
"geo-agent-executor",
|
|
483
535
|
"geo-agent-batch-executor",
|
|
484
536
|
"geo-agent-progress-tracker",
|
|
537
|
+
"geo-agent-status-board",
|
|
538
|
+
"geo-agent-checkpoint",
|
|
485
539
|
"geo-apply-plan",
|
|
486
540
|
"geo-handoff-bundle"
|
|
487
541
|
].includes(detected.artifactKind)
|
|
@@ -496,6 +550,8 @@ function buildStage(intent, detected) {
|
|
|
496
550
|
"geo-agent-executor",
|
|
497
551
|
"geo-agent-batch-executor",
|
|
498
552
|
"geo-agent-progress-tracker",
|
|
553
|
+
"geo-agent-status-board",
|
|
554
|
+
"geo-agent-checkpoint",
|
|
499
555
|
"geo-apply-plan",
|
|
500
556
|
"geo-handoff-bundle"
|
|
501
557
|
].includes(detected.artifactKind)
|
package/src/cli.js
CHANGED
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
renderAgentProgressTrackerMarkdown,
|
|
15
15
|
writeAgentProgressTrackerOutput
|
|
16
16
|
} from "./agent-progress-tracker.js";
|
|
17
|
+
import { createAgentCheckpoint, renderAgentCheckpointMarkdown, writeAgentCheckpointOutput } from "./agent-checkpoint.js";
|
|
18
|
+
import { createAgentStatusBoard, renderAgentStatusBoardMarkdown, writeAgentStatusBoardOutput } from "./agent-status-board.js";
|
|
17
19
|
import { createAgentRunbook, renderAgentRunbookMarkdown, writeAgentRunbookOutput } from "./agent-runbook.js";
|
|
18
20
|
import { createAgentSession, renderAgentSessionMarkdown, writeAgentSessionOutput } from "./agent-session.js";
|
|
19
21
|
import { createAutoFlow, renderAutoFlowMarkdown, writeAutoFlowOutput } from "./auto-flow.js";
|
|
@@ -77,6 +79,8 @@ function printHelp() {
|
|
|
77
79
|
" geo-ai-search-optimization agent-executor <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--format <markdown|json>] [--out <file>]",
|
|
78
80
|
" geo-ai-search-optimization agent-batch-executor <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--count <count>] [--format <markdown|json>] [--out <file>]",
|
|
79
81
|
" geo-ai-search-optimization agent-progress-tracker <input> [--current <id>] [--completed <id,id>] [--blocked <reason,reason>] [--format <markdown|json>] [--out <file>]",
|
|
82
|
+
" geo-ai-search-optimization agent-status-board <input> [--current <id>] [--completed <id,id>] [--blocked <reason,reason>] [--format <markdown|json>] [--out <file>]",
|
|
83
|
+
" geo-ai-search-optimization agent-checkpoint <input> [--current <id>] [--completed <id,id>] [--blocked <reason,reason>] [--format <markdown|json>] [--out <file>]",
|
|
80
84
|
" geo-ai-search-optimization skills [--json]",
|
|
81
85
|
" geo-ai-search-optimization where",
|
|
82
86
|
" geo-ai-search-optimization doctor [--json]",
|
|
@@ -303,6 +307,62 @@ async function handleAgentProgressTracker(args) {
|
|
|
303
307
|
process.stdout.write(renderedOutput);
|
|
304
308
|
}
|
|
305
309
|
|
|
310
|
+
async function handleAgentStatusBoard(args) {
|
|
311
|
+
const input = args.find((value) => !value.startsWith("-"));
|
|
312
|
+
if (!input) {
|
|
313
|
+
throw new Error("agent-status-board 需要一个输入值,可以是项目路径、网站网址或已导出的工件");
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
317
|
+
const board = await createAgentStatusBoard(input, {
|
|
318
|
+
format,
|
|
319
|
+
currentTaskId: getFlagValue(args, "--current"),
|
|
320
|
+
completedPacketIds: getFlagValue(args, "--completed"),
|
|
321
|
+
blockedReasons: getFlagValue(args, "--blocked")
|
|
322
|
+
});
|
|
323
|
+
const outputJson = board.format === "json";
|
|
324
|
+
const renderedOutput = outputJson
|
|
325
|
+
? `${JSON.stringify(board, null, 2)}\n`
|
|
326
|
+
: renderAgentStatusBoardMarkdown(board);
|
|
327
|
+
|
|
328
|
+
const outputPath = getFlagValue(args, "--out");
|
|
329
|
+
if (outputPath) {
|
|
330
|
+
const resolvedOutputPath = await writeAgentStatusBoardOutput(outputPath, renderedOutput);
|
|
331
|
+
process.stdout.write(`已保存 agent status board:${resolvedOutputPath}\n`);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
process.stdout.write(renderedOutput);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async function handleAgentCheckpoint(args) {
|
|
339
|
+
const input = args.find((value) => !value.startsWith("-"));
|
|
340
|
+
if (!input) {
|
|
341
|
+
throw new Error("agent-checkpoint 需要一个输入值,可以是项目路径、网站网址或已导出的工件");
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
345
|
+
const checkpoint = await createAgentCheckpoint(input, {
|
|
346
|
+
format,
|
|
347
|
+
currentTaskId: getFlagValue(args, "--current"),
|
|
348
|
+
completedPacketIds: getFlagValue(args, "--completed"),
|
|
349
|
+
blockedReasons: getFlagValue(args, "--blocked")
|
|
350
|
+
});
|
|
351
|
+
const outputJson = checkpoint.format === "json";
|
|
352
|
+
const renderedOutput = outputJson
|
|
353
|
+
? `${JSON.stringify(checkpoint, null, 2)}\n`
|
|
354
|
+
: renderAgentCheckpointMarkdown(checkpoint);
|
|
355
|
+
|
|
356
|
+
const outputPath = getFlagValue(args, "--out");
|
|
357
|
+
if (outputPath) {
|
|
358
|
+
const resolvedOutputPath = await writeAgentCheckpointOutput(outputPath, renderedOutput);
|
|
359
|
+
process.stdout.write(`已保存 agent checkpoint:${resolvedOutputPath}\n`);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
process.stdout.write(renderedOutput);
|
|
364
|
+
}
|
|
365
|
+
|
|
306
366
|
function handleWhere() {
|
|
307
367
|
process.stdout.write(
|
|
308
368
|
[
|
|
@@ -873,6 +933,16 @@ export async function runCli(args = []) {
|
|
|
873
933
|
return;
|
|
874
934
|
}
|
|
875
935
|
|
|
936
|
+
if (command === "agent-status-board") {
|
|
937
|
+
await handleAgentStatusBoard(rest);
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
if (command === "agent-checkpoint") {
|
|
942
|
+
await handleAgentCheckpoint(rest);
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
|
|
876
946
|
if (command === "skills") {
|
|
877
947
|
await handleSkills(rest);
|
|
878
948
|
return;
|
package/src/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export {
|
|
|
8
8
|
export { createAutoFlow, renderAutoFlowMarkdown, writeAutoFlowOutput } from "./auto-flow.js";
|
|
9
9
|
export { createApplyPlan, renderApplyPlanMarkdown, writeApplyPlanOutput } from "./apply-plan.js";
|
|
10
10
|
export { createAgentBatchExecutor, renderAgentBatchExecutorMarkdown, writeAgentBatchExecutorOutput } from "./agent-batch-executor.js";
|
|
11
|
+
export { createAgentCheckpoint, renderAgentCheckpointMarkdown, writeAgentCheckpointOutput } from "./agent-checkpoint.js";
|
|
11
12
|
export { createAgentHandoff, renderAgentHandoffMarkdown, writeAgentHandoffOutput } from "./agent-handoff.js";
|
|
12
13
|
export { createAgentExecutor, renderAgentExecutorMarkdown, writeAgentExecutorOutput } from "./agent-executor.js";
|
|
13
14
|
export {
|
|
@@ -15,6 +16,7 @@ export {
|
|
|
15
16
|
renderAgentProgressTrackerMarkdown,
|
|
16
17
|
writeAgentProgressTrackerOutput
|
|
17
18
|
} from "./agent-progress-tracker.js";
|
|
19
|
+
export { createAgentStatusBoard, renderAgentStatusBoardMarkdown, writeAgentStatusBoardOutput } from "./agent-status-board.js";
|
|
18
20
|
export { createAgentRunbook, renderAgentRunbookMarkdown, writeAgentRunbookOutput } from "./agent-runbook.js";
|
|
19
21
|
export { createAgentSession, renderAgentSessionMarkdown, writeAgentSessionOutput } from "./agent-session.js";
|
|
20
22
|
export { createCompletionReport, renderCompletionReportMarkdown, writeCompletionReportOutput } from "./completion-report.js";
|
package/src/skills.js
CHANGED
|
@@ -10,6 +10,8 @@ const SKILL_ORDER = [
|
|
|
10
10
|
"geo-ai-search-optimization-agent-executor",
|
|
11
11
|
"geo-ai-search-optimization-agent-batch-executor",
|
|
12
12
|
"geo-ai-search-optimization-agent-progress-tracker",
|
|
13
|
+
"geo-ai-search-optimization-agent-status-board",
|
|
14
|
+
"geo-ai-search-optimization-agent-checkpoint",
|
|
13
15
|
"geo-ai-search-optimization-usage",
|
|
14
16
|
"geo-ai-search-optimization-agent-handoff",
|
|
15
17
|
"geo-ai-search-optimization-repair-loop",
|
|
@@ -29,6 +31,8 @@ const SKILL_CATEGORY = {
|
|
|
29
31
|
"geo-ai-search-optimization-agent-executor": "execution",
|
|
30
32
|
"geo-ai-search-optimization-agent-batch-executor": "execution",
|
|
31
33
|
"geo-ai-search-optimization-agent-progress-tracker": "execution",
|
|
34
|
+
"geo-ai-search-optimization-agent-status-board": "execution",
|
|
35
|
+
"geo-ai-search-optimization-agent-checkpoint": "execution",
|
|
32
36
|
"geo-ai-search-optimization-usage": "guidance",
|
|
33
37
|
"geo-ai-search-optimization-agent-handoff": "execution",
|
|
34
38
|
"geo-ai-search-optimization-repair-loop": "execution",
|
|
@@ -167,6 +171,8 @@ export function renderBundledSkillsMarkdown(bundle) {
|
|
|
167
171
|
"- 如果要直接告诉 agent 这轮先做哪 1 包,再进入 agent-executor。",
|
|
168
172
|
"- 如果要连续推进前 2 到 3 包,但仍然一次只做一包,再进入 agent-batch-executor。",
|
|
169
173
|
"- 如果要追踪目前做到第几包、卡在哪、下一包是什么,再进入 agent-progress-tracker。",
|
|
174
|
+
"- 如果要把当前执行状态直接整理成看板,再进入 agent-status-board。",
|
|
175
|
+
"- 如果要在每轮结束时做继续 / 阻塞 / 收尾决策,再进入 agent-checkpoint。",
|
|
170
176
|
"- 再看 usage skill,知道什么时候该跑哪个命令。",
|
|
171
177
|
"- 如果要交给 agent 执行,再进入 handoff / apply / completion 这一条执行链。",
|
|
172
178
|
"- 如果要产出给团队分发,再进入 share / export / html / publish 这一条交付链。",
|