geo-ai-search-optimization 1.3.0 → 1.3.2
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 +37 -0
- package/package.json +1 -1
- package/resources/geo-ai-search-optimization/references/skill-bundle-map.md +10 -0
- package/resources/geo-ai-search-optimization-agent-state-pack/SKILL.md +44 -0
- package/resources/geo-ai-search-optimization-agent-state-pack/agents/openai.yaml +4 -0
- package/resources/geo-ai-search-optimization-usage/SKILL.md +30 -25
- package/src/agent-resume.js +3 -0
- package/src/agent-state-pack.js +260 -0
- package/src/auto-flow.js +28 -3
- package/src/cli-flow-commands.js +143 -0
- package/src/cli-shared.js +54 -0
- package/src/cli.js +6 -185
- package/src/index.js +1 -0
- package/src/skills.js +3 -0
package/README.md
CHANGED
|
@@ -104,6 +104,26 @@ geo-ai-search-optimization agent-continue ./reports/agent-resume.json --format j
|
|
|
104
104
|
- 可以进入收尾时跑什么
|
|
105
105
|
- 可直接复制给 agent 的 continue prompt
|
|
106
106
|
|
|
107
|
+
## Agent State Pack 命令
|
|
108
|
+
|
|
109
|
+
如果你希望下一个 agent 直接拿到一份统一的当前状态工件,而不是自己拼 `agent-resume / agent-continue / agent-status-board / agent-checkpoint`,可以直接用 `agent-state-pack`:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
geo-ai-search-optimization agent-state-pack ./your-site
|
|
113
|
+
geo-ai-search-optimization agent-state-pack ./reports/agent-playbook-pack.json
|
|
114
|
+
geo-ai-search-optimization agent-state-pack ./reports/agent-continue.json --format json --out ./reports/agent-state-pack.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
它会输出:
|
|
118
|
+
|
|
119
|
+
- 当前阶段和状态等级
|
|
120
|
+
- 现在先执行哪条命令
|
|
121
|
+
- 当前包与下一包
|
|
122
|
+
- 执行前先确认什么
|
|
123
|
+
- 执行后先验证什么
|
|
124
|
+
- 这一轮完成后要同步哪些工件
|
|
125
|
+
- 可直接复制给 agent 的 state prompt
|
|
126
|
+
|
|
107
127
|
## Auto Flow 命令
|
|
108
128
|
|
|
109
129
|
如果你希望 agent 不用自己判断现在该用哪个 skill、该跑哪个命令,可以直接用 `auto-flow`:
|
|
@@ -725,6 +745,7 @@ geo-ai-search-optimization install --target ./tmp/custom-skills --json
|
|
|
725
745
|
geo-ai-search-optimization agent-orchestrator ./your-site
|
|
726
746
|
geo-ai-search-optimization agent-resume ./your-site
|
|
727
747
|
geo-ai-search-optimization agent-continue ./your-site
|
|
748
|
+
geo-ai-search-optimization agent-state-pack ./your-site
|
|
728
749
|
geo-ai-search-optimization auto-flow "audit this site and tell me the next skill"
|
|
729
750
|
geo-ai-search-optimization agent-session ./your-site
|
|
730
751
|
geo-ai-search-optimization agent-runbook ./your-site
|
|
@@ -815,6 +836,21 @@ geo-ai-search-optimization help
|
|
|
815
836
|
- `auto-flow`、`agent-session` 已能把 `playbook-pack / agent-resume / agent-continue` 统一接成继续链
|
|
816
837
|
- 新增 `geo-ai-search-optimization-agent-continue` skill
|
|
817
838
|
|
|
839
|
+
## New in 1.3.1
|
|
840
|
+
|
|
841
|
+
- 新增 `agent-state-pack`
|
|
842
|
+
- 把 `agent-resume + agent-continue + agent-status-board + agent-checkpoint` 压成一个统一状态工件
|
|
843
|
+
- 输出当前阶段、当前包、现在先执行哪条命令、执行后验证项、同步状态命令和收尾路径
|
|
844
|
+
- `auto-flow` 已能识别 `geo-agent-state-pack` 并继续往下路由
|
|
845
|
+
- 新增 `geo-ai-search-optimization-agent-state-pack` skill
|
|
846
|
+
|
|
847
|
+
## New in 1.3.2
|
|
848
|
+
|
|
849
|
+
- 进行了 CLI 架构迭代,把 flow/routing 相关命令从主 `cli.js` 拆到独立模块
|
|
850
|
+
- 新增 `src/cli-flow-commands.js`,让 `auto-flow / agent-orchestrator / agent-resume / agent-continue / agent-state-pack / agent-session` 形成一个明确的 adapter 边界
|
|
851
|
+
- 新增 `src/cli-shared.js`,集中处理 flag 解析、输入校验和输出写回,降低后续继续加命令时的耦合
|
|
852
|
+
- 主 `cli.js` 现在更像薄路由层,后续扩充 command family 会更稳
|
|
853
|
+
|
|
818
854
|
## New in 1.2.20
|
|
819
855
|
|
|
820
856
|
- 新增 `agent-continue`
|
|
@@ -1079,6 +1115,7 @@ The installed package now includes a bundled GEO skill pack, including:
|
|
|
1079
1115
|
- `geo-ai-search-optimization-agent-orchestrator`
|
|
1080
1116
|
- `geo-ai-search-optimization-agent-resume`
|
|
1081
1117
|
- `geo-ai-search-optimization-agent-continue`
|
|
1118
|
+
- `geo-ai-search-optimization-agent-state-pack`
|
|
1082
1119
|
- `geo-ai-search-optimization-agent-session`
|
|
1083
1120
|
- `geo-ai-search-optimization-agent-runbook`
|
|
1084
1121
|
- `geo-ai-search-optimization-agent-executor`
|
package/package.json
CHANGED
|
@@ -62,6 +62,16 @@ Best for:
|
|
|
62
62
|
- turning a resume point into a one-round execution loop
|
|
63
63
|
- giving the next agent one execution command, one validation set, and one writeback list
|
|
64
64
|
|
|
65
|
+
### `geo-ai-search-optimization-agent-state-pack`
|
|
66
|
+
|
|
67
|
+
Use this when the next agent should get one normalized current-state artifact instead of manually stitching together resume, continue, board, and checkpoint outputs.
|
|
68
|
+
|
|
69
|
+
Best for:
|
|
70
|
+
|
|
71
|
+
- creating one state snapshot from a URL, directory, or GEO execution artifact
|
|
72
|
+
- telling the next agent what command runs now and what must be synced afterward
|
|
73
|
+
- reducing handoff ambiguity between PM, agent, and the next execution round
|
|
74
|
+
|
|
65
75
|
### `geo-ai-search-optimization-agent-session`
|
|
66
76
|
|
|
67
77
|
Use this when the next agent needs a runnable session plan, not just a routing answer.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-ai-search-optimization-agent-state-pack
|
|
3
|
+
description: Normalize the current GEO execution state into one handoff-ready artifact for the next agent. Use when an agent, PM, or workflow already has a GEO URL, codebase, resume point, continue artifact, status board, checkpoint, decision log, or playbook pack and needs one current-state package with the command to run now, the validation steps, the state writeback commands, and the closeout path.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GEO Agent State Pack
|
|
7
|
+
|
|
8
|
+
Use this skill when the next agent should not piece together `agent-resume`, `agent-continue`, `agent-status-board`, and `agent-checkpoint` manually.
|
|
9
|
+
|
|
10
|
+
## What this skill should do
|
|
11
|
+
|
|
12
|
+
- create one normalized current-state artifact
|
|
13
|
+
- state what command should run now
|
|
14
|
+
- state what to validate after this round
|
|
15
|
+
- state which GEO artifacts must be written back
|
|
16
|
+
- state when the workflow is ready for closeout
|
|
17
|
+
|
|
18
|
+
## Preferred command
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx geo-ai-search-optimization agent-state-pack <input>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Where `<input>` can be:
|
|
25
|
+
|
|
26
|
+
- a website URL
|
|
27
|
+
- a local project directory
|
|
28
|
+
- a GEO JSON artifact such as `agent-resume`, `agent-continue`, `agent-status-board`, `agent-checkpoint`, or `agent-playbook-pack`
|
|
29
|
+
|
|
30
|
+
## Output expectations
|
|
31
|
+
|
|
32
|
+
Return the result in PM-readable language while keeping the command contract explicit:
|
|
33
|
+
|
|
34
|
+
- current stage
|
|
35
|
+
- state level
|
|
36
|
+
- now command
|
|
37
|
+
- expected artifact
|
|
38
|
+
- current packet
|
|
39
|
+
- next packet
|
|
40
|
+
- validation list
|
|
41
|
+
- sync-after-round commands
|
|
42
|
+
- closeout path
|
|
43
|
+
|
|
44
|
+
If the state shows blockers or missing context, say that clearly and do not pretend the next agent should already be editing code.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "GEO Agent State Pack"
|
|
3
|
+
short_description: "Normalize current GEO state for the next agent"
|
|
4
|
+
default_prompt: "Use $geo-ai-search-optimization-agent-state-pack to turn this GEO input into one current-state artifact with the command to run now, validation steps, writeback commands, and closeout path."
|
|
@@ -13,35 +13,36 @@ 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 twenty-
|
|
16
|
+
The package is best explained as twenty-eight layers:
|
|
17
17
|
|
|
18
18
|
1. `agent-orchestrator`: choose the one next GEO command to run right now
|
|
19
19
|
2. `agent-resume`: resume from the latest reliable GEO checkpoint instead of restarting the whole chain
|
|
20
20
|
3. `agent-continue`: continue this round and write status artifacts back after execution
|
|
21
|
-
4. `
|
|
22
|
-
5. `
|
|
23
|
-
6. `agent-
|
|
24
|
-
7. `agent-
|
|
25
|
-
8. `agent-
|
|
26
|
-
9. `agent-
|
|
27
|
-
10. `agent-
|
|
28
|
-
11. `agent-
|
|
29
|
-
12. `agent-
|
|
30
|
-
13. `agent-
|
|
31
|
-
14. `agent-
|
|
32
|
-
15. `
|
|
33
|
-
16. `
|
|
34
|
-
17. `
|
|
35
|
-
18. `
|
|
36
|
-
19. `
|
|
37
|
-
20. `
|
|
38
|
-
21. `
|
|
39
|
-
22. `
|
|
40
|
-
23. `
|
|
41
|
-
24. `
|
|
42
|
-
25. `
|
|
43
|
-
26. `
|
|
44
|
-
27. `
|
|
21
|
+
4. `agent-state-pack`: compress resume, continue, board, and checkpoint into one current-state artifact
|
|
22
|
+
5. `auto-flow`: auto-select the next skill and command chain
|
|
23
|
+
6. `agent-session`: build a runnable session for the next agent
|
|
24
|
+
7. `agent-runbook`: execution manual and checklist for the next agent
|
|
25
|
+
8. `agent-executor`: choose one packet to execute right now
|
|
26
|
+
9. `agent-batch-executor`: queue the first few packets, but still advance one packet at a time
|
|
27
|
+
10. `agent-progress-tracker`: track which packet is done, which one is active, and what comes next
|
|
28
|
+
11. `agent-status-board`: turn the execution state into a board view for PM and agents
|
|
29
|
+
12. `agent-checkpoint`: freeze the current round into a continue / unblock / closeout decision
|
|
30
|
+
13. `agent-decision-log`: preserve why each round continued, paused, or closed out
|
|
31
|
+
14. `agent-retrospective`: explain multi-round patterns, lessons, and next-round advice
|
|
32
|
+
15. `agent-playbook-pack`: compress retrospective, decision history, and handoff into one resume entrypoint
|
|
33
|
+
16. `skills`: inspect the bundled skill package
|
|
34
|
+
17. `onboard-url` / `onboard`: first look
|
|
35
|
+
18. `scan`: raw signal check
|
|
36
|
+
19. `audit` / `report`: diagnosis
|
|
37
|
+
20. `fix-plan` / `owner-board`: execution planning
|
|
38
|
+
21. `agent-handoff`: agent takeover package
|
|
39
|
+
22. `apply-plan`: execution loop
|
|
40
|
+
23. `completion-report`: closeout
|
|
41
|
+
24. `handoff-bundle`: all-in-one package
|
|
42
|
+
25. `share-pack`: audience-ready delivery
|
|
43
|
+
26. `export-pack`: folder export
|
|
44
|
+
27. `html-pack` / `publish-pack`: browsable and final delivery output
|
|
45
|
+
28. `pm-brief` / `roadmap`: stakeholder alignment
|
|
45
46
|
|
|
46
47
|
## Recommended command order
|
|
47
48
|
|
|
@@ -51,6 +52,7 @@ If the user only has a website URL:
|
|
|
51
52
|
npx geo-ai-search-optimization agent-orchestrator https://example.com
|
|
52
53
|
npx geo-ai-search-optimization agent-resume https://example.com
|
|
53
54
|
npx geo-ai-search-optimization agent-continue https://example.com
|
|
55
|
+
npx geo-ai-search-optimization agent-state-pack https://example.com
|
|
54
56
|
npx geo-ai-search-optimization auto-flow https://example.com
|
|
55
57
|
npx geo-ai-search-optimization agent-session https://example.com
|
|
56
58
|
npx geo-ai-search-optimization agent-runbook https://example.com
|
|
@@ -73,6 +75,7 @@ If the user has the website codebase:
|
|
|
73
75
|
npx geo-ai-search-optimization agent-orchestrator ./your-site
|
|
74
76
|
npx geo-ai-search-optimization agent-resume ./your-site
|
|
75
77
|
npx geo-ai-search-optimization agent-continue ./your-site
|
|
78
|
+
npx geo-ai-search-optimization agent-state-pack ./your-site
|
|
76
79
|
npx geo-ai-search-optimization auto-flow ./your-site
|
|
77
80
|
npx geo-ai-search-optimization agent-session ./your-site
|
|
78
81
|
npx geo-ai-search-optimization agent-runbook ./your-site
|
|
@@ -104,6 +107,7 @@ npx geo-ai-search-optimization roadmap ./your-site
|
|
|
104
107
|
- `agent-orchestrator`: choose the one next GEO command to run now, plus expected artifact, stop conditions, and follow-up command
|
|
105
108
|
- `agent-resume`: resume from the latest reliable checkpoint, confirm what not to reset, and tell the next agent the one resume command to run
|
|
106
109
|
- `agent-continue`: continue the current round, validate it, and tell the next agent which state artifacts to update right after execution
|
|
110
|
+
- `agent-state-pack`: turn the current round into one normalized state artifact with the command to run now, the validation list, and the sync-after-round commands
|
|
107
111
|
- `auto-flow`: auto-select the next skill and command order from a task brief, URL, project path, or GEO artifact
|
|
108
112
|
- `agent-session`: build a step-by-step session packet for the next agent from the same kinds of inputs
|
|
109
113
|
- `agent-runbook`: build a checklist-driven runbook with preflight, validation, and reporting rules
|
|
@@ -142,6 +146,7 @@ When explaining the tool to a user:
|
|
|
142
146
|
- if the user or next agent wants just one next command, move them to `agent-orchestrator`
|
|
143
147
|
- if the user or next agent needs to continue from the latest reliable checkpoint without restarting, move them to `agent-resume`
|
|
144
148
|
- if the user or next agent needs one round of execution plus status writeback, move them to `agent-continue`
|
|
149
|
+
- if the user or next agent wants one unified current-state artifact for handoff, move them to `agent-state-pack`
|
|
145
150
|
- if the user or the next agent is unsure where to start, move them to `auto-flow` first
|
|
146
151
|
- if the user wants something the next agent can follow step by step, move them to `agent-session`
|
|
147
152
|
- if the user wants the next agent to follow a checklist and execution manual, move them to `agent-runbook`
|
package/src/agent-resume.js
CHANGED
|
@@ -37,6 +37,9 @@ async function tryReadExistingPlaybookPack(input) {
|
|
|
37
37
|
if (parsed.kind === "geo-agent-resume" && parsed.playbookPack) {
|
|
38
38
|
return parsed.playbookPack;
|
|
39
39
|
}
|
|
40
|
+
if (parsed.kind === "geo-agent-state-pack" && parsed.resume?.playbookPack) {
|
|
41
|
+
return parsed.resume.playbookPack;
|
|
42
|
+
}
|
|
40
43
|
} catch {
|
|
41
44
|
return null;
|
|
42
45
|
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { createAgentCheckpoint } from "./agent-checkpoint.js";
|
|
2
|
+
import { createAgentContinue } from "./agent-continue.js";
|
|
3
|
+
import { createAgentResume } from "./agent-resume.js";
|
|
4
|
+
import { createAgentStatusBoard } from "./agent-status-board.js";
|
|
5
|
+
import { writeScanOutput } from "./scan.js";
|
|
6
|
+
|
|
7
|
+
const VALID_FORMATS = new Set(["markdown", "json"]);
|
|
8
|
+
|
|
9
|
+
function normalizeFormat(format) {
|
|
10
|
+
const resolved = (format || "markdown").toLowerCase();
|
|
11
|
+
if (!VALID_FORMATS.has(resolved)) {
|
|
12
|
+
throw new Error(`不支持的 agent-state-pack 格式:${format}。可选值:${Array.from(VALID_FORMATS).join(", ")}`);
|
|
13
|
+
}
|
|
14
|
+
return resolved;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function uniqueList(items) {
|
|
18
|
+
return Array.from(new Set((items || []).filter(Boolean)));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function inferStateLevel(continueArtifact, board, checkpoint) {
|
|
22
|
+
if (continueArtifact.continue_mode === "needs-context") {
|
|
23
|
+
return "needs-context";
|
|
24
|
+
}
|
|
25
|
+
if (
|
|
26
|
+
continueArtifact.continue_mode === "closeout-loop" ||
|
|
27
|
+
checkpoint.decision === "move-to-closeout" ||
|
|
28
|
+
board.boardStatus === "completed"
|
|
29
|
+
) {
|
|
30
|
+
return "closeout-ready";
|
|
31
|
+
}
|
|
32
|
+
if (checkpoint.decision === "resolve-blockers" || board.boardStatus === "blocked") {
|
|
33
|
+
return "blocked";
|
|
34
|
+
}
|
|
35
|
+
if (board.boardStatus === "in-progress" || continueArtifact.currentPacket) {
|
|
36
|
+
return "active";
|
|
37
|
+
}
|
|
38
|
+
if (board.boardStatus === "not-started") {
|
|
39
|
+
return "ready-to-start";
|
|
40
|
+
}
|
|
41
|
+
return "tracking";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function buildStateSummary(level, resume, continueArtifact, board, checkpoint) {
|
|
45
|
+
if (level === "needs-context") {
|
|
46
|
+
return "当前还缺继续执行所需的上下文,先补网址、目录或现成 GEO 工件。";
|
|
47
|
+
}
|
|
48
|
+
if (level === "closeout-ready") {
|
|
49
|
+
return "当前已经接近或进入收尾,下一步重点是复盘、交接和交付,而不是再开新包。";
|
|
50
|
+
}
|
|
51
|
+
if (level === "blocked") {
|
|
52
|
+
return checkpoint.decisionReason || `当前执行被阻塞,先解除阻塞,再回到 ${continueArtifact.currentPacket?.id || "当前包"}。`;
|
|
53
|
+
}
|
|
54
|
+
if (level === "ready-to-start") {
|
|
55
|
+
return `当前已经有明确入口,可以从 ${continueArtifact.currentPacket?.id || "第一包"} 启动这一轮。`;
|
|
56
|
+
}
|
|
57
|
+
if (continueArtifact.currentPacket) {
|
|
58
|
+
return `当前应继续 ${continueArtifact.currentPacket.id},并在这一轮结束后同步状态工件。`;
|
|
59
|
+
}
|
|
60
|
+
return resume.resume_summary || board.boardSummary;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function buildNowCommand(continueArtifact, resume) {
|
|
64
|
+
return continueArtifact.continue_now || resume.resume_command || resume.orchestrator?.next_command || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function buildAfterNow(level, continueArtifact, resume) {
|
|
68
|
+
if (level === "closeout-ready") {
|
|
69
|
+
return continueArtifact.closeout_when_ready[0] || resume.after_resume || null;
|
|
70
|
+
}
|
|
71
|
+
return continueArtifact.update_artifacts[0] || resume.after_resume || continueArtifact.closeout_when_ready[0] || null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function buildPreflightChecks(resume, checkpoint) {
|
|
75
|
+
return uniqueList([
|
|
76
|
+
...(resume.verify_before_resume || []),
|
|
77
|
+
checkpoint.gateChecks?.find((item) => item.status === "fail")?.detail,
|
|
78
|
+
checkpoint.gateChecks?.find((item) => item.status === "warn")?.detail
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildStatePrompt(pack) {
|
|
83
|
+
const lines = [
|
|
84
|
+
"你现在进入 GEO Agent State Pack 模式。",
|
|
85
|
+
`当前输入:${pack.source}`,
|
|
86
|
+
`当前状态等级:${pack.state_level}`,
|
|
87
|
+
`当前阶段:${pack.current_stage}`,
|
|
88
|
+
`状态摘要:${pack.state_summary}`,
|
|
89
|
+
`现在先执行:${pack.now_command || "先补上下文"}`
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
if (pack.currentPacket) {
|
|
93
|
+
lines.push(`当前包:${pack.currentPacket.id}|${pack.currentPacket.title}`);
|
|
94
|
+
}
|
|
95
|
+
if (pack.nextPacket) {
|
|
96
|
+
lines.push(`下一包:${pack.nextPacket.id}|${pack.nextPacket.title}`);
|
|
97
|
+
}
|
|
98
|
+
lines.push(`看板状态:${pack.board_status}|进度:${pack.progress_percent}%`);
|
|
99
|
+
lines.push(`检查点决策:${pack.checkpoint_decision}`);
|
|
100
|
+
|
|
101
|
+
if (pack.preflight_checks.length > 0) {
|
|
102
|
+
lines.push("执行前先确认:");
|
|
103
|
+
for (const item of pack.preflight_checks) {
|
|
104
|
+
lines.push(`- ${item}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (pack.sync_after_round.length > 0) {
|
|
108
|
+
lines.push("这一轮完成后要同步这些工件:");
|
|
109
|
+
for (const item of pack.sync_after_round) {
|
|
110
|
+
lines.push(`- ${item}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
lines.push("请先解释为什么现在应沿着这份状态包继续,而不是重新生成整条链。");
|
|
115
|
+
lines.push("然后给出本轮动作、验证点、回写动作和何时进入收尾。");
|
|
116
|
+
return lines.join("\n");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function createAgentStatePack(input, options = {}) {
|
|
120
|
+
const format = normalizeFormat(options.format);
|
|
121
|
+
const [resume, continueArtifact, statusBoard, checkpoint] = await Promise.all([
|
|
122
|
+
createAgentResume(input, { format: "json", intent: options.intent }),
|
|
123
|
+
createAgentContinue(input, { format: "json", intent: options.intent }),
|
|
124
|
+
createAgentStatusBoard(input, {
|
|
125
|
+
format: "json",
|
|
126
|
+
currentTaskId: options.currentTaskId,
|
|
127
|
+
completedPacketIds: options.completedPacketIds,
|
|
128
|
+
blockedReasons: options.blockedReasons
|
|
129
|
+
}),
|
|
130
|
+
createAgentCheckpoint(input, {
|
|
131
|
+
format: "json",
|
|
132
|
+
currentTaskId: options.currentTaskId,
|
|
133
|
+
completedPacketIds: options.completedPacketIds,
|
|
134
|
+
blockedReasons: options.blockedReasons
|
|
135
|
+
})
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
const stateLevel = inferStateLevel(continueArtifact, statusBoard, checkpoint);
|
|
139
|
+
const source = continueArtifact.source || resume.source || statusBoard.source;
|
|
140
|
+
|
|
141
|
+
const pack = {
|
|
142
|
+
kind: "geo-agent-state-pack",
|
|
143
|
+
input,
|
|
144
|
+
source,
|
|
145
|
+
sourceType: continueArtifact.sourceType || resume.sourceType || statusBoard.sourceType,
|
|
146
|
+
artifactKind: resume.artifactKind || statusBoard.artifactKind,
|
|
147
|
+
format,
|
|
148
|
+
state_level: stateLevel,
|
|
149
|
+
state_summary: buildStateSummary(stateLevel, resume, continueArtifact, statusBoard, checkpoint),
|
|
150
|
+
current_stage: resume.orchestrator?.current_stage || "Agent 执行",
|
|
151
|
+
now_command: buildNowCommand(continueArtifact, resume),
|
|
152
|
+
expected_artifact: resume.expected_artifact || continueArtifact.executor?.expectedArtifact || null,
|
|
153
|
+
after_now: buildAfterNow(stateLevel, continueArtifact, resume),
|
|
154
|
+
currentPacket: continueArtifact.currentPacket || checkpoint.currentPacket || null,
|
|
155
|
+
nextPacket: continueArtifact.nextPacket || checkpoint.nextPacket || null,
|
|
156
|
+
board_status: statusBoard.boardStatus,
|
|
157
|
+
progress_percent: statusBoard.progressPercent,
|
|
158
|
+
checkpoint_type: checkpoint.checkpointType,
|
|
159
|
+
checkpoint_decision: checkpoint.decision,
|
|
160
|
+
checkpoint_reason: checkpoint.decisionReason,
|
|
161
|
+
preflight_checks: buildPreflightChecks(resume, checkpoint),
|
|
162
|
+
do_now_checklist: uniqueList(continueArtifact.do_now_checklist),
|
|
163
|
+
validate_after: uniqueList(continueArtifact.validate_after),
|
|
164
|
+
sync_after_round: uniqueList(continueArtifact.update_artifacts),
|
|
165
|
+
closeout_when_ready: uniqueList(continueArtifact.closeout_when_ready),
|
|
166
|
+
do_not_reset: uniqueList(continueArtifact.do_not_restart),
|
|
167
|
+
handoff_note: checkpoint.handoffNote,
|
|
168
|
+
selectedSkill: {
|
|
169
|
+
name: "geo-ai-search-optimization-agent-state-pack",
|
|
170
|
+
displayName: "GEO Agent State Pack",
|
|
171
|
+
shortDescription: "Normalize the current GEO state for the next agent"
|
|
172
|
+
},
|
|
173
|
+
next_skill: continueArtifact.selectedSkill?.name || "geo-ai-search-optimization-agent-continue",
|
|
174
|
+
resume,
|
|
175
|
+
continue: continueArtifact,
|
|
176
|
+
statusBoard,
|
|
177
|
+
checkpoint,
|
|
178
|
+
state_prompt: ""
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
pack.state_prompt = buildStatePrompt(pack);
|
|
182
|
+
return pack;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function renderAgentStatePackMarkdown(pack) {
|
|
186
|
+
const lines = [
|
|
187
|
+
"# GEO Agent State Pack",
|
|
188
|
+
"",
|
|
189
|
+
`- 输入:\`${pack.source}\``,
|
|
190
|
+
`- 输入类型:\`${pack.sourceType}\``,
|
|
191
|
+
`- 工件类型:\`${pack.artifactKind}\``,
|
|
192
|
+
`- 当前阶段:${pack.current_stage}`,
|
|
193
|
+
`- 状态等级:\`${pack.state_level}\``,
|
|
194
|
+
`- 看板状态:\`${pack.board_status}\``,
|
|
195
|
+
`- 进度:\`${pack.progress_percent}%\``,
|
|
196
|
+
`- 检查点决策:\`${pack.checkpoint_decision}\``,
|
|
197
|
+
"",
|
|
198
|
+
"## 当前摘要",
|
|
199
|
+
"",
|
|
200
|
+
`- ${pack.state_summary}`,
|
|
201
|
+
`- 现在先执行:\`${pack.now_command || "先补上下文"}\``
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
if (pack.expected_artifact) {
|
|
205
|
+
lines.push(`- 预期产物:${pack.expected_artifact}`);
|
|
206
|
+
}
|
|
207
|
+
if (pack.after_now) {
|
|
208
|
+
lines.push(`- 做完后第一条:\`${pack.after_now}\``);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (pack.currentPacket) {
|
|
212
|
+
lines.push("", "## 当前包", "", `- ${pack.currentPacket.id}|${pack.currentPacket.title}`);
|
|
213
|
+
}
|
|
214
|
+
if (pack.nextPacket) {
|
|
215
|
+
lines.push("", "## 下一包", "", `- ${pack.nextPacket.id}|${pack.nextPacket.title}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
lines.push("", "## 执行前先确认", "");
|
|
219
|
+
if (pack.preflight_checks.length === 0) {
|
|
220
|
+
lines.push("- 当前没有额外 preflight 项。");
|
|
221
|
+
} else {
|
|
222
|
+
for (const item of pack.preflight_checks) {
|
|
223
|
+
lines.push(`- ${item}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
lines.push("", "## 这一轮先做什么", "");
|
|
228
|
+
for (const item of pack.do_now_checklist) {
|
|
229
|
+
lines.push(`- ${item}`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
lines.push("", "## 执行后先验证", "");
|
|
233
|
+
for (const item of pack.validate_after) {
|
|
234
|
+
lines.push(`- ${item}`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
lines.push("", "## 这一轮完成后同步什么", "");
|
|
238
|
+
for (const item of pack.sync_after_round) {
|
|
239
|
+
lines.push(`- \`${item}\``);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
lines.push("", "## 可以进入收尾时跑什么", "");
|
|
243
|
+
for (const item of pack.closeout_when_ready) {
|
|
244
|
+
lines.push(`- \`${item}\``);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
lines.push("", "## 不要重置什么", "");
|
|
248
|
+
for (const item of pack.do_not_reset) {
|
|
249
|
+
lines.push(`- ${item}`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
lines.push("", "## 交接说明", "", `- ${pack.handoff_note}`);
|
|
253
|
+
lines.push("", "## 可直接复制给 Agent 的 State Prompt", "", "```text", pack.state_prompt, "```");
|
|
254
|
+
|
|
255
|
+
return `${lines.join("\n")}\n`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export async function writeAgentStatePackOutput(outputPath, content) {
|
|
259
|
+
return writeScanOutput(outputPath, content);
|
|
260
|
+
}
|
package/src/auto-flow.js
CHANGED
|
@@ -41,6 +41,9 @@ function detectArtifactKindFromParsedJson(parsed) {
|
|
|
41
41
|
function inferTaskTextMode(text) {
|
|
42
42
|
const normalized = String(text).toLowerCase();
|
|
43
43
|
|
|
44
|
+
if (/(agent-state-pack|state pack|state snapshot|统一状态包|当前状态包|state artifact)/i.test(normalized)) {
|
|
45
|
+
return "execute";
|
|
46
|
+
}
|
|
44
47
|
if (/(agent-continue|continue this round|继续这轮|继续当前轮次|回写状态后继续)/i.test(normalized)) {
|
|
45
48
|
return "execute";
|
|
46
49
|
}
|
|
@@ -177,6 +180,9 @@ function resolveEffectiveIntent(intent, detected) {
|
|
|
177
180
|
if (detected.artifactKind === "geo-agent-playbook-pack") {
|
|
178
181
|
return detected.parsed?.playbookStatus === "closeout-ready" ? "closeout" : "execute";
|
|
179
182
|
}
|
|
183
|
+
if (detected.artifactKind === "geo-agent-state-pack") {
|
|
184
|
+
return detected.parsed?.state_level === "closeout-ready" ? "closeout" : "execute";
|
|
185
|
+
}
|
|
180
186
|
if (detected.artifactKind === "geo-agent-resume") {
|
|
181
187
|
return detected.parsed?.resume_mode === "resume-closeout" ? "closeout" : "execute";
|
|
182
188
|
}
|
|
@@ -205,6 +211,7 @@ function resolveEffectiveIntent(intent, detected) {
|
|
|
205
211
|
"geo-agent-status-board",
|
|
206
212
|
"geo-agent-checkpoint",
|
|
207
213
|
"geo-agent-decision-log",
|
|
214
|
+
"geo-agent-state-pack",
|
|
208
215
|
"geo-apply-plan",
|
|
209
216
|
"geo-handoff-bundle",
|
|
210
217
|
"geo-fix-plan"
|
|
@@ -246,10 +253,11 @@ function buildCommandChain(detected, intent) {
|
|
|
246
253
|
}
|
|
247
254
|
|
|
248
255
|
if (intent === "closeout") {
|
|
256
|
+
const baseSource = detected.parsed?.source || source;
|
|
249
257
|
return [
|
|
250
|
-
`geo-ai-search-optimization completion-report ${
|
|
251
|
-
`geo-ai-search-optimization meeting-pack ${
|
|
252
|
-
`geo-ai-search-optimization publish-pack ${
|
|
258
|
+
`geo-ai-search-optimization completion-report ${baseSource}`,
|
|
259
|
+
`geo-ai-search-optimization meeting-pack ${baseSource}`,
|
|
260
|
+
`geo-ai-search-optimization publish-pack ${baseSource}`
|
|
253
261
|
];
|
|
254
262
|
}
|
|
255
263
|
|
|
@@ -447,6 +455,11 @@ function buildCommandChain(detected, intent) {
|
|
|
447
455
|
`geo-ai-search-optimization agent-decision-log ${baseSource}`
|
|
448
456
|
];
|
|
449
457
|
}
|
|
458
|
+
case "geo-agent-state-pack": {
|
|
459
|
+
const nowCommand = detected.parsed?.now_command;
|
|
460
|
+
const syncCommands = Array.isArray(detected.parsed?.sync_after_round) ? detected.parsed.sync_after_round : [];
|
|
461
|
+
return [nowCommand, ...syncCommands.slice(0, 2)].filter(Boolean);
|
|
462
|
+
}
|
|
450
463
|
case "geo-agent-resume": {
|
|
451
464
|
return [`geo-ai-search-optimization agent-continue ${source}`];
|
|
452
465
|
}
|
|
@@ -534,6 +547,8 @@ function pickSkillName(detected, intent) {
|
|
|
534
547
|
case "geo-agent-status-board":
|
|
535
548
|
case "geo-agent-checkpoint":
|
|
536
549
|
case "geo-agent-decision-log":
|
|
550
|
+
case "geo-agent-state-pack":
|
|
551
|
+
return "geo-ai-search-optimization-agent-state-pack";
|
|
537
552
|
case "geo-agent-playbook-pack":
|
|
538
553
|
case "geo-agent-resume":
|
|
539
554
|
case "geo-agent-continue":
|
|
@@ -581,6 +596,7 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
581
596
|
"geo-agent-status-board",
|
|
582
597
|
"geo-agent-checkpoint",
|
|
583
598
|
"geo-agent-decision-log",
|
|
599
|
+
"geo-agent-state-pack",
|
|
584
600
|
"geo-agent-resume",
|
|
585
601
|
"geo-agent-continue",
|
|
586
602
|
"geo-agent-playbook-pack",
|
|
@@ -591,6 +607,7 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
591
607
|
) {
|
|
592
608
|
names.add("geo-ai-search-optimization-agent-resume");
|
|
593
609
|
names.add("geo-ai-search-optimization-agent-continue");
|
|
610
|
+
names.add("geo-ai-search-optimization-agent-state-pack");
|
|
594
611
|
names.add("geo-ai-search-optimization-agent-batch-executor");
|
|
595
612
|
names.add("geo-ai-search-optimization-agent-progress-tracker");
|
|
596
613
|
names.add("geo-ai-search-optimization-agent-status-board");
|
|
@@ -612,6 +629,9 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
612
629
|
}
|
|
613
630
|
|
|
614
631
|
function buildStage(intent, detected) {
|
|
632
|
+
if (detected.artifactKind === "geo-agent-state-pack") {
|
|
633
|
+
return "当前状态";
|
|
634
|
+
}
|
|
615
635
|
if (detected.artifactKind === "geo-agent-continue") {
|
|
616
636
|
return "继续执行";
|
|
617
637
|
}
|
|
@@ -638,6 +658,7 @@ function buildStage(intent, detected) {
|
|
|
638
658
|
"geo-agent-status-board",
|
|
639
659
|
"geo-agent-checkpoint",
|
|
640
660
|
"geo-agent-decision-log",
|
|
661
|
+
"geo-agent-state-pack",
|
|
641
662
|
"geo-agent-resume",
|
|
642
663
|
"geo-agent-continue",
|
|
643
664
|
"geo-agent-playbook-pack",
|
|
@@ -659,6 +680,7 @@ function buildStage(intent, detected) {
|
|
|
659
680
|
"geo-agent-status-board",
|
|
660
681
|
"geo-agent-checkpoint",
|
|
661
682
|
"geo-agent-decision-log",
|
|
683
|
+
"geo-agent-state-pack",
|
|
662
684
|
"geo-agent-resume",
|
|
663
685
|
"geo-agent-continue",
|
|
664
686
|
"geo-agent-playbook-pack",
|
|
@@ -749,6 +771,9 @@ function buildNextAction(detected, intent, commands) {
|
|
|
749
771
|
return `先运行 \`${commands[0]}\` 生成适合外发或交接的结果。`;
|
|
750
772
|
}
|
|
751
773
|
if (intent === "execute") {
|
|
774
|
+
if (detected.artifactKind === "geo-agent-state-pack") {
|
|
775
|
+
return `先运行 \`${commands[0]}\`,沿着这份统一状态包继续当前这一轮,并按包内要求回写状态工件。`;
|
|
776
|
+
}
|
|
752
777
|
if (detected.artifactKind === "geo-agent-continue") {
|
|
753
778
|
return `先运行 \`${commands[0]}\`,继续当前这一轮,并把状态与决策工件一起回写。`;
|
|
754
779
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { createAutoFlow, renderAutoFlowMarkdown, writeAutoFlowOutput } from "./auto-flow.js";
|
|
2
|
+
import {
|
|
3
|
+
createAgentContinue,
|
|
4
|
+
renderAgentContinueMarkdown,
|
|
5
|
+
writeAgentContinueOutput
|
|
6
|
+
} from "./agent-continue.js";
|
|
7
|
+
import {
|
|
8
|
+
createAgentOrchestrator,
|
|
9
|
+
renderAgentOrchestratorMarkdown,
|
|
10
|
+
writeAgentOrchestratorOutput
|
|
11
|
+
} from "./agent-orchestrator.js";
|
|
12
|
+
import { createAgentResume, renderAgentResumeMarkdown, writeAgentResumeOutput } from "./agent-resume.js";
|
|
13
|
+
import {
|
|
14
|
+
createAgentStatePack,
|
|
15
|
+
renderAgentStatePackMarkdown,
|
|
16
|
+
writeAgentStatePackOutput
|
|
17
|
+
} from "./agent-state-pack.js";
|
|
18
|
+
import { createAgentSession, renderAgentSessionMarkdown, writeAgentSessionOutput } from "./agent-session.js";
|
|
19
|
+
import {
|
|
20
|
+
getFlagValue,
|
|
21
|
+
getJsonCapableFormat,
|
|
22
|
+
getRequiredInput,
|
|
23
|
+
hasFlag,
|
|
24
|
+
writeOrPrintArtifact
|
|
25
|
+
} from "./cli-shared.js";
|
|
26
|
+
|
|
27
|
+
export const FLOW_HELP_LINES = [
|
|
28
|
+
" geo-ai-search-optimization agent-orchestrator <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
29
|
+
" geo-ai-search-optimization agent-resume <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
30
|
+
" geo-ai-search-optimization agent-continue <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
31
|
+
" geo-ai-search-optimization agent-state-pack <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--current <id>] [--completed <id,id>] [--blocked <reason,reason>] [--format <markdown|json>] [--out <file>]",
|
|
32
|
+
" geo-ai-search-optimization auto-flow <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
|
|
33
|
+
" geo-ai-search-optimization agent-session <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]"
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
async function handleAutoFlow(args) {
|
|
37
|
+
const input = getRequiredInput(args, "auto-flow");
|
|
38
|
+
const flow = await createAutoFlow(input, {
|
|
39
|
+
intent: getFlagValue(args, "--intent")
|
|
40
|
+
});
|
|
41
|
+
const outputJson = hasFlag(args, "--json");
|
|
42
|
+
const renderedOutput = outputJson ? `${JSON.stringify(flow, null, 2)}\n` : renderAutoFlowMarkdown(flow);
|
|
43
|
+
const outputPath = getFlagValue(args, "--out");
|
|
44
|
+
|
|
45
|
+
if (outputPath) {
|
|
46
|
+
const resolvedOutputPath = await writeAutoFlowOutput(outputPath, renderedOutput);
|
|
47
|
+
process.stdout.write(`已保存 auto-flow 结果:${resolvedOutputPath}\n`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
process.stdout.write(renderedOutput);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function handleAgentOrchestrator(args) {
|
|
55
|
+
const input = getRequiredInput(args, "agent-orchestrator");
|
|
56
|
+
const artifact = await createAgentOrchestrator(input, {
|
|
57
|
+
intent: getFlagValue(args, "--intent"),
|
|
58
|
+
format: getJsonCapableFormat(args)
|
|
59
|
+
});
|
|
60
|
+
return writeOrPrintArtifact({
|
|
61
|
+
args,
|
|
62
|
+
commandName: "agent-orchestrator",
|
|
63
|
+
artifact,
|
|
64
|
+
renderMarkdown: renderAgentOrchestratorMarkdown,
|
|
65
|
+
writeOutput: writeAgentOrchestratorOutput,
|
|
66
|
+
outputJson: artifact.format === "json"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function handleAgentResume(args) {
|
|
71
|
+
const input = getRequiredInput(args, "agent-resume");
|
|
72
|
+
const artifact = await createAgentResume(input, {
|
|
73
|
+
intent: getFlagValue(args, "--intent"),
|
|
74
|
+
format: getJsonCapableFormat(args)
|
|
75
|
+
});
|
|
76
|
+
return writeOrPrintArtifact({
|
|
77
|
+
args,
|
|
78
|
+
commandName: "agent-resume",
|
|
79
|
+
artifact,
|
|
80
|
+
renderMarkdown: renderAgentResumeMarkdown,
|
|
81
|
+
writeOutput: writeAgentResumeOutput,
|
|
82
|
+
outputJson: artifact.format === "json"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function handleAgentContinue(args) {
|
|
87
|
+
const input = getRequiredInput(args, "agent-continue");
|
|
88
|
+
const artifact = await createAgentContinue(input, {
|
|
89
|
+
intent: getFlagValue(args, "--intent"),
|
|
90
|
+
format: getJsonCapableFormat(args)
|
|
91
|
+
});
|
|
92
|
+
return writeOrPrintArtifact({
|
|
93
|
+
args,
|
|
94
|
+
commandName: "agent-continue",
|
|
95
|
+
artifact,
|
|
96
|
+
renderMarkdown: renderAgentContinueMarkdown,
|
|
97
|
+
writeOutput: writeAgentContinueOutput,
|
|
98
|
+
outputJson: artifact.format === "json"
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function handleAgentStatePack(args) {
|
|
103
|
+
const input = getRequiredInput(args, "agent-state-pack");
|
|
104
|
+
const artifact = await createAgentStatePack(input, {
|
|
105
|
+
intent: getFlagValue(args, "--intent"),
|
|
106
|
+
format: getJsonCapableFormat(args),
|
|
107
|
+
currentTaskId: getFlagValue(args, "--current"),
|
|
108
|
+
completedPacketIds: getFlagValue(args, "--completed"),
|
|
109
|
+
blockedReasons: getFlagValue(args, "--blocked")
|
|
110
|
+
});
|
|
111
|
+
return writeOrPrintArtifact({
|
|
112
|
+
args,
|
|
113
|
+
commandName: "agent-state-pack",
|
|
114
|
+
artifact,
|
|
115
|
+
renderMarkdown: renderAgentStatePackMarkdown,
|
|
116
|
+
writeOutput: writeAgentStatePackOutput,
|
|
117
|
+
outputJson: artifact.format === "json"
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function handleAgentSession(args) {
|
|
122
|
+
const input = getRequiredInput(args, "agent-session");
|
|
123
|
+
const artifact = await createAgentSession(input, {
|
|
124
|
+
intent: getFlagValue(args, "--intent")
|
|
125
|
+
});
|
|
126
|
+
return writeOrPrintArtifact({
|
|
127
|
+
args,
|
|
128
|
+
commandName: "agent-session",
|
|
129
|
+
artifact,
|
|
130
|
+
renderMarkdown: renderAgentSessionMarkdown,
|
|
131
|
+
writeOutput: writeAgentSessionOutput,
|
|
132
|
+
outputJson: hasFlag(args, "--json")
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const FLOW_COMMAND_HANDLERS = {
|
|
137
|
+
"auto-flow": handleAutoFlow,
|
|
138
|
+
"agent-orchestrator": handleAgentOrchestrator,
|
|
139
|
+
"agent-resume": handleAgentResume,
|
|
140
|
+
"agent-continue": handleAgentContinue,
|
|
141
|
+
"agent-state-pack": handleAgentStatePack,
|
|
142
|
+
"agent-session": handleAgentSession
|
|
143
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function getFlagValue(args, flagName) {
|
|
2
|
+
const index = args.indexOf(flagName);
|
|
3
|
+
if (index === -1) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
if (index === args.length - 1) {
|
|
7
|
+
throw new Error(`${flagName} requires a value`);
|
|
8
|
+
}
|
|
9
|
+
return args[index + 1];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function hasFlag(args, ...flagNames) {
|
|
13
|
+
return flagNames.some((flagName) => args.includes(flagName));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function parsePositiveInteger(value, flagName) {
|
|
17
|
+
const parsed = Number.parseInt(value, 10);
|
|
18
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
19
|
+
throw new Error(`${flagName} must be a positive integer`);
|
|
20
|
+
}
|
|
21
|
+
return parsed;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getRequiredInput(args, commandName) {
|
|
25
|
+
const input = args.find((value) => !value.startsWith("-"));
|
|
26
|
+
if (!input) {
|
|
27
|
+
throw new Error(`${commandName} 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件`);
|
|
28
|
+
}
|
|
29
|
+
return input;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getJsonCapableFormat(args) {
|
|
33
|
+
return getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function writeOrPrintArtifact({
|
|
37
|
+
args,
|
|
38
|
+
commandName,
|
|
39
|
+
artifact,
|
|
40
|
+
renderMarkdown,
|
|
41
|
+
writeOutput,
|
|
42
|
+
outputJson
|
|
43
|
+
}) {
|
|
44
|
+
const renderedOutput = outputJson ? `${JSON.stringify(artifact, null, 2)}\n` : renderMarkdown(artifact);
|
|
45
|
+
const outputPath = getFlagValue(args, "--out");
|
|
46
|
+
|
|
47
|
+
if (outputPath) {
|
|
48
|
+
const resolvedOutputPath = await writeOutput(outputPath, renderedOutput);
|
|
49
|
+
process.stdout.write(`已保存 ${commandName} 结果:${resolvedOutputPath}\n`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
process.stdout.write(renderedOutput);
|
|
54
|
+
}
|
package/src/cli.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { FLOW_COMMAND_HANDLERS, FLOW_HELP_LINES } from "./cli-flow-commands.js";
|
|
5
|
+
import { getFlagValue, hasFlag, parsePositiveInteger } from "./cli-shared.js";
|
|
4
6
|
import { createApplyPlan, renderApplyPlanMarkdown, writeApplyPlanOutput } from "./apply-plan.js";
|
|
5
7
|
import {
|
|
6
8
|
createAgentBatchExecutor,
|
|
7
9
|
renderAgentBatchExecutorMarkdown,
|
|
8
10
|
writeAgentBatchExecutorOutput
|
|
9
11
|
} from "./agent-batch-executor.js";
|
|
10
|
-
import {
|
|
11
|
-
createAgentContinue,
|
|
12
|
-
renderAgentContinueMarkdown,
|
|
13
|
-
writeAgentContinueOutput
|
|
14
|
-
} from "./agent-continue.js";
|
|
15
12
|
import { createAgentExecutor, renderAgentExecutorMarkdown, writeAgentExecutorOutput } from "./agent-executor.js";
|
|
16
13
|
import { createAgentHandoff, renderAgentHandoffMarkdown, writeAgentHandoffOutput } from "./agent-handoff.js";
|
|
17
14
|
import {
|
|
@@ -21,12 +18,6 @@ import {
|
|
|
21
18
|
} from "./agent-progress-tracker.js";
|
|
22
19
|
import { createAgentCheckpoint, renderAgentCheckpointMarkdown, writeAgentCheckpointOutput } from "./agent-checkpoint.js";
|
|
23
20
|
import { createAgentDecisionLog, renderAgentDecisionLogMarkdown, writeAgentDecisionLogOutput } from "./agent-decision-log.js";
|
|
24
|
-
import {
|
|
25
|
-
createAgentOrchestrator,
|
|
26
|
-
renderAgentOrchestratorMarkdown,
|
|
27
|
-
writeAgentOrchestratorOutput
|
|
28
|
-
} from "./agent-orchestrator.js";
|
|
29
|
-
import { createAgentResume, renderAgentResumeMarkdown, writeAgentResumeOutput } from "./agent-resume.js";
|
|
30
21
|
import {
|
|
31
22
|
createAgentPlaybookPack,
|
|
32
23
|
renderAgentPlaybookPackMarkdown,
|
|
@@ -35,8 +26,6 @@ import {
|
|
|
35
26
|
import { createAgentRetrospective, renderAgentRetrospectiveMarkdown, writeAgentRetrospectiveOutput } from "./agent-retrospective.js";
|
|
36
27
|
import { createAgentStatusBoard, renderAgentStatusBoardMarkdown, writeAgentStatusBoardOutput } from "./agent-status-board.js";
|
|
37
28
|
import { createAgentRunbook, renderAgentRunbookMarkdown, writeAgentRunbookOutput } from "./agent-runbook.js";
|
|
38
|
-
import { createAgentSession, renderAgentSessionMarkdown, writeAgentSessionOutput } from "./agent-session.js";
|
|
39
|
-
import { createAutoFlow, renderAutoFlowMarkdown, writeAutoFlowOutput } from "./auto-flow.js";
|
|
40
29
|
import {
|
|
41
30
|
createCompletionReport,
|
|
42
31
|
renderCompletionReportMarkdown,
|
|
@@ -91,11 +80,7 @@ function printHelp() {
|
|
|
91
80
|
"Usage:",
|
|
92
81
|
" geo-ai-search-optimization",
|
|
93
82
|
" geo-ai-search-optimization install [--target <dir>] [--json]",
|
|
94
|
-
|
|
95
|
-
" geo-ai-search-optimization agent-resume <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
96
|
-
" geo-ai-search-optimization agent-continue <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
97
|
-
" geo-ai-search-optimization auto-flow <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
|
|
98
|
-
" geo-ai-search-optimization agent-session <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
|
|
83
|
+
...FLOW_HELP_LINES,
|
|
99
84
|
" geo-ai-search-optimization agent-runbook <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--format <markdown|json>] [--out <file>]",
|
|
100
85
|
" geo-ai-search-optimization agent-executor <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--format <markdown|json>] [--out <file>]",
|
|
101
86
|
" geo-ai-search-optimization agent-batch-executor <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--count <count>] [--format <markdown|json>] [--out <file>]",
|
|
@@ -142,29 +127,6 @@ function printHelp() {
|
|
|
142
127
|
);
|
|
143
128
|
}
|
|
144
129
|
|
|
145
|
-
function getFlagValue(args, flagName) {
|
|
146
|
-
const index = args.indexOf(flagName);
|
|
147
|
-
if (index === -1) {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
if (index === args.length - 1) {
|
|
151
|
-
throw new Error(`${flagName} requires a value`);
|
|
152
|
-
}
|
|
153
|
-
return args[index + 1];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function hasFlag(args, ...flagNames) {
|
|
157
|
-
return flagNames.some((flagName) => args.includes(flagName));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function parsePositiveInteger(value, flagName) {
|
|
161
|
-
const parsed = Number.parseInt(value, 10);
|
|
162
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
163
|
-
throw new Error(`${flagName} must be a positive integer`);
|
|
164
|
-
}
|
|
165
|
-
return parsed;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
130
|
async function handleInstall(args) {
|
|
169
131
|
const targetDir = getFlagValue(args, "--target");
|
|
170
132
|
const outputJson = hasFlag(args, "--json");
|
|
@@ -175,128 +137,6 @@ async function handleInstall(args) {
|
|
|
175
137
|
}
|
|
176
138
|
}
|
|
177
139
|
|
|
178
|
-
async function handleAutoFlow(args) {
|
|
179
|
-
const input = args.find((value) => !value.startsWith("-"));
|
|
180
|
-
if (!input) {
|
|
181
|
-
throw new Error("auto-flow 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const flow = await createAutoFlow(input, {
|
|
185
|
-
intent: getFlagValue(args, "--intent")
|
|
186
|
-
});
|
|
187
|
-
const outputJson = hasFlag(args, "--json");
|
|
188
|
-
const renderedOutput = outputJson ? `${JSON.stringify(flow, null, 2)}\n` : renderAutoFlowMarkdown(flow);
|
|
189
|
-
|
|
190
|
-
const outputPath = getFlagValue(args, "--out");
|
|
191
|
-
if (outputPath) {
|
|
192
|
-
const resolvedOutputPath = await writeAutoFlowOutput(outputPath, renderedOutput);
|
|
193
|
-
process.stdout.write(`已保存 auto-flow 结果:${resolvedOutputPath}\n`);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
process.stdout.write(renderedOutput);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async function handleAgentOrchestrator(args) {
|
|
201
|
-
const input = args.find((value) => !value.startsWith("-"));
|
|
202
|
-
if (!input) {
|
|
203
|
-
throw new Error("agent-orchestrator 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
207
|
-
const orchestrator = await createAgentOrchestrator(input, {
|
|
208
|
-
intent: getFlagValue(args, "--intent"),
|
|
209
|
-
format
|
|
210
|
-
});
|
|
211
|
-
const outputJson = orchestrator.format === "json";
|
|
212
|
-
const renderedOutput = outputJson
|
|
213
|
-
? `${JSON.stringify(orchestrator, null, 2)}\n`
|
|
214
|
-
: renderAgentOrchestratorMarkdown(orchestrator);
|
|
215
|
-
|
|
216
|
-
const outputPath = getFlagValue(args, "--out");
|
|
217
|
-
if (outputPath) {
|
|
218
|
-
const resolvedOutputPath = await writeAgentOrchestratorOutput(outputPath, renderedOutput);
|
|
219
|
-
process.stdout.write(`已保存 agent-orchestrator 结果:${resolvedOutputPath}\n`);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
process.stdout.write(renderedOutput);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async function handleAgentResume(args) {
|
|
227
|
-
const input = args.find((value) => !value.startsWith("-"));
|
|
228
|
-
if (!input) {
|
|
229
|
-
throw new Error("agent-resume 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
233
|
-
const resume = await createAgentResume(input, {
|
|
234
|
-
intent: getFlagValue(args, "--intent"),
|
|
235
|
-
format
|
|
236
|
-
});
|
|
237
|
-
const outputJson = resume.format === "json";
|
|
238
|
-
const renderedOutput = outputJson ? `${JSON.stringify(resume, null, 2)}\n` : renderAgentResumeMarkdown(resume);
|
|
239
|
-
|
|
240
|
-
const outputPath = getFlagValue(args, "--out");
|
|
241
|
-
if (outputPath) {
|
|
242
|
-
const resolvedOutputPath = await writeAgentResumeOutput(outputPath, renderedOutput);
|
|
243
|
-
process.stdout.write(`已保存 agent-resume 结果:${resolvedOutputPath}\n`);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
process.stdout.write(renderedOutput);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async function handleAgentContinue(args) {
|
|
251
|
-
const input = args.find((value) => !value.startsWith("-"));
|
|
252
|
-
if (!input) {
|
|
253
|
-
throw new Error("agent-continue 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
257
|
-
const artifact = await createAgentContinue(input, {
|
|
258
|
-
intent: getFlagValue(args, "--intent"),
|
|
259
|
-
format
|
|
260
|
-
});
|
|
261
|
-
const outputJson = artifact.format === "json";
|
|
262
|
-
const renderedOutput = outputJson
|
|
263
|
-
? `${JSON.stringify(artifact, null, 2)}\n`
|
|
264
|
-
: renderAgentContinueMarkdown(artifact);
|
|
265
|
-
|
|
266
|
-
const outputPath = getFlagValue(args, "--out");
|
|
267
|
-
if (outputPath) {
|
|
268
|
-
const resolvedOutputPath = await writeAgentContinueOutput(outputPath, renderedOutput);
|
|
269
|
-
process.stdout.write(`已保存 agent-continue 结果:${resolvedOutputPath}\n`);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
process.stdout.write(renderedOutput);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
async function handleAgentSession(args) {
|
|
277
|
-
const input = args.find((value) => !value.startsWith("-"));
|
|
278
|
-
if (!input) {
|
|
279
|
-
throw new Error("agent-session 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const session = await createAgentSession(input, {
|
|
283
|
-
intent: getFlagValue(args, "--intent")
|
|
284
|
-
});
|
|
285
|
-
const outputJson = hasFlag(args, "--json");
|
|
286
|
-
const renderedOutput = outputJson
|
|
287
|
-
? `${JSON.stringify(session, null, 2)}\n`
|
|
288
|
-
: renderAgentSessionMarkdown(session);
|
|
289
|
-
|
|
290
|
-
const outputPath = getFlagValue(args, "--out");
|
|
291
|
-
if (outputPath) {
|
|
292
|
-
const resolvedOutputPath = await writeAgentSessionOutput(outputPath, renderedOutput);
|
|
293
|
-
process.stdout.write(`已保存 agent-session 结果:${resolvedOutputPath}\n`);
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
process.stdout.write(renderedOutput);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
140
|
async function handleAgentRunbook(args) {
|
|
301
141
|
const input = args.find((value) => !value.startsWith("-"));
|
|
302
142
|
if (!input) {
|
|
@@ -1068,6 +908,7 @@ async function handleRoadmap(args) {
|
|
|
1068
908
|
|
|
1069
909
|
export async function runCli(args = []) {
|
|
1070
910
|
const [command = "install", ...rest] = args;
|
|
911
|
+
const flowHandler = FLOW_COMMAND_HANDLERS[command];
|
|
1071
912
|
|
|
1072
913
|
if (command === "help" || command === "--help" || command === "-h") {
|
|
1073
914
|
printHelp();
|
|
@@ -1084,28 +925,8 @@ export async function runCli(args = []) {
|
|
|
1084
925
|
return;
|
|
1085
926
|
}
|
|
1086
927
|
|
|
1087
|
-
if (
|
|
1088
|
-
await
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
|
|
1092
|
-
if (command === "agent-orchestrator") {
|
|
1093
|
-
await handleAgentOrchestrator(rest);
|
|
1094
|
-
return;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
if (command === "agent-resume") {
|
|
1098
|
-
await handleAgentResume(rest);
|
|
1099
|
-
return;
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
if (command === "agent-continue") {
|
|
1103
|
-
await handleAgentContinue(rest);
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
if (command === "agent-session") {
|
|
1108
|
-
await handleAgentSession(rest);
|
|
928
|
+
if (flowHandler) {
|
|
929
|
+
await flowHandler(rest);
|
|
1109
930
|
return;
|
|
1110
931
|
}
|
|
1111
932
|
|
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 { createAgentContinue, renderAgentContinueMarkdown, writeAgentContinueOutput } from "./agent-continue.js";
|
|
11
|
+
export { createAgentStatePack, renderAgentStatePackMarkdown, writeAgentStatePackOutput } from "./agent-state-pack.js";
|
|
11
12
|
export { createAgentOrchestrator, renderAgentOrchestratorMarkdown, writeAgentOrchestratorOutput } from "./agent-orchestrator.js";
|
|
12
13
|
export { createAgentResume, renderAgentResumeMarkdown, writeAgentResumeOutput } from "./agent-resume.js";
|
|
13
14
|
export { createAgentBatchExecutor, renderAgentBatchExecutorMarkdown, writeAgentBatchExecutorOutput } from "./agent-batch-executor.js";
|
package/src/skills.js
CHANGED
|
@@ -8,6 +8,7 @@ const SKILL_ORDER = [
|
|
|
8
8
|
"geo-ai-search-optimization-agent-orchestrator",
|
|
9
9
|
"geo-ai-search-optimization-agent-resume",
|
|
10
10
|
"geo-ai-search-optimization-agent-continue",
|
|
11
|
+
"geo-ai-search-optimization-agent-state-pack",
|
|
11
12
|
"geo-ai-search-optimization-agent-session",
|
|
12
13
|
"geo-ai-search-optimization-agent-runbook",
|
|
13
14
|
"geo-ai-search-optimization-agent-executor",
|
|
@@ -35,6 +36,7 @@ const SKILL_CATEGORY = {
|
|
|
35
36
|
"geo-ai-search-optimization-agent-orchestrator": "routing",
|
|
36
37
|
"geo-ai-search-optimization-agent-resume": "routing",
|
|
37
38
|
"geo-ai-search-optimization-agent-continue": "routing",
|
|
39
|
+
"geo-ai-search-optimization-agent-state-pack": "routing",
|
|
38
40
|
"geo-ai-search-optimization-agent-session": "routing",
|
|
39
41
|
"geo-ai-search-optimization-agent-runbook": "execution",
|
|
40
42
|
"geo-ai-search-optimization-agent-executor": "execution",
|
|
@@ -180,6 +182,7 @@ export function renderBundledSkillsMarkdown(bundle) {
|
|
|
180
182
|
"- 如果你只想让 agent 立刻知道现在唯一该跑哪条命令,先跑 agent-orchestrator。",
|
|
181
183
|
"- 如果工作中断后要从最近一个可靠恢复点继续,先跑 agent-resume。",
|
|
182
184
|
"- 如果你希望 agent 不只恢复,还要拿到这一轮继续后的状态回写动作,继续跑 agent-continue。",
|
|
185
|
+
"- 如果你希望下一个 agent 直接拿到统一的当前状态工件,而不是自己拼 resume / continue / board / checkpoint,跑 agent-state-pack。",
|
|
183
186
|
"- 如果 agent 需要自动选 skill,先跑 auto-flow。",
|
|
184
187
|
"- 如果要给 agent 明确步骤,继续进入 agent-session。",
|
|
185
188
|
"- 如果要给 agent 一份执行手册和检查表,再进入 agent-runbook。",
|