geo-ai-search-optimization 1.3.1 → 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 CHANGED
@@ -844,6 +844,13 @@ geo-ai-search-optimization help
844
844
  - `auto-flow` 已能识别 `geo-agent-state-pack` 并继续往下路由
845
845
  - 新增 `geo-ai-search-optimization-agent-state-pack` skill
846
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
+
847
854
  ## New in 1.2.20
848
855
 
849
856
  - 新增 `agent-continue`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geo-ai-search-optimization",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Install and run a Generative Engine Optimization (GEO)-first, SEO-supported Codex skill for website optimization.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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,22 +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
- import {
16
- createAgentStatePack,
17
- renderAgentStatePackMarkdown,
18
- writeAgentStatePackOutput
19
- } from "./agent-state-pack.js";
20
12
  import { createAgentExecutor, renderAgentExecutorMarkdown, writeAgentExecutorOutput } from "./agent-executor.js";
21
13
  import { createAgentHandoff, renderAgentHandoffMarkdown, writeAgentHandoffOutput } from "./agent-handoff.js";
22
14
  import {
@@ -26,12 +18,6 @@ import {
26
18
  } from "./agent-progress-tracker.js";
27
19
  import { createAgentCheckpoint, renderAgentCheckpointMarkdown, writeAgentCheckpointOutput } from "./agent-checkpoint.js";
28
20
  import { createAgentDecisionLog, renderAgentDecisionLogMarkdown, writeAgentDecisionLogOutput } from "./agent-decision-log.js";
29
- import {
30
- createAgentOrchestrator,
31
- renderAgentOrchestratorMarkdown,
32
- writeAgentOrchestratorOutput
33
- } from "./agent-orchestrator.js";
34
- import { createAgentResume, renderAgentResumeMarkdown, writeAgentResumeOutput } from "./agent-resume.js";
35
21
  import {
36
22
  createAgentPlaybookPack,
37
23
  renderAgentPlaybookPackMarkdown,
@@ -40,8 +26,6 @@ import {
40
26
  import { createAgentRetrospective, renderAgentRetrospectiveMarkdown, writeAgentRetrospectiveOutput } from "./agent-retrospective.js";
41
27
  import { createAgentStatusBoard, renderAgentStatusBoardMarkdown, writeAgentStatusBoardOutput } from "./agent-status-board.js";
42
28
  import { createAgentRunbook, renderAgentRunbookMarkdown, writeAgentRunbookOutput } from "./agent-runbook.js";
43
- import { createAgentSession, renderAgentSessionMarkdown, writeAgentSessionOutput } from "./agent-session.js";
44
- import { createAutoFlow, renderAutoFlowMarkdown, writeAutoFlowOutput } from "./auto-flow.js";
45
29
  import {
46
30
  createCompletionReport,
47
31
  renderCompletionReportMarkdown,
@@ -96,12 +80,7 @@ function printHelp() {
96
80
  "Usage:",
97
81
  " geo-ai-search-optimization",
98
82
  " geo-ai-search-optimization install [--target <dir>] [--json]",
99
- " geo-ai-search-optimization agent-orchestrator <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
100
- " geo-ai-search-optimization agent-resume <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
101
- " geo-ai-search-optimization agent-continue <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
102
- " 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>]",
103
- " geo-ai-search-optimization auto-flow <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
104
- " geo-ai-search-optimization agent-session <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
83
+ ...FLOW_HELP_LINES,
105
84
  " geo-ai-search-optimization agent-runbook <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--format <markdown|json>] [--out <file>]",
106
85
  " geo-ai-search-optimization agent-executor <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--format <markdown|json>] [--out <file>]",
107
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>]",
@@ -148,29 +127,6 @@ function printHelp() {
148
127
  );
149
128
  }
150
129
 
151
- function getFlagValue(args, flagName) {
152
- const index = args.indexOf(flagName);
153
- if (index === -1) {
154
- return null;
155
- }
156
- if (index === args.length - 1) {
157
- throw new Error(`${flagName} requires a value`);
158
- }
159
- return args[index + 1];
160
- }
161
-
162
- function hasFlag(args, ...flagNames) {
163
- return flagNames.some((flagName) => args.includes(flagName));
164
- }
165
-
166
- function parsePositiveInteger(value, flagName) {
167
- const parsed = Number.parseInt(value, 10);
168
- if (!Number.isInteger(parsed) || parsed <= 0) {
169
- throw new Error(`${flagName} must be a positive integer`);
170
- }
171
- return parsed;
172
- }
173
-
174
130
  async function handleInstall(args) {
175
131
  const targetDir = getFlagValue(args, "--target");
176
132
  const outputJson = hasFlag(args, "--json");
@@ -181,157 +137,6 @@ async function handleInstall(args) {
181
137
  }
182
138
  }
183
139
 
184
- async function handleAutoFlow(args) {
185
- const input = args.find((value) => !value.startsWith("-"));
186
- if (!input) {
187
- throw new Error("auto-flow 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
188
- }
189
-
190
- const flow = await createAutoFlow(input, {
191
- intent: getFlagValue(args, "--intent")
192
- });
193
- const outputJson = hasFlag(args, "--json");
194
- const renderedOutput = outputJson ? `${JSON.stringify(flow, null, 2)}\n` : renderAutoFlowMarkdown(flow);
195
-
196
- const outputPath = getFlagValue(args, "--out");
197
- if (outputPath) {
198
- const resolvedOutputPath = await writeAutoFlowOutput(outputPath, renderedOutput);
199
- process.stdout.write(`已保存 auto-flow 结果:${resolvedOutputPath}\n`);
200
- return;
201
- }
202
-
203
- process.stdout.write(renderedOutput);
204
- }
205
-
206
- async function handleAgentOrchestrator(args) {
207
- const input = args.find((value) => !value.startsWith("-"));
208
- if (!input) {
209
- throw new Error("agent-orchestrator 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
210
- }
211
-
212
- const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
213
- const orchestrator = await createAgentOrchestrator(input, {
214
- intent: getFlagValue(args, "--intent"),
215
- format
216
- });
217
- const outputJson = orchestrator.format === "json";
218
- const renderedOutput = outputJson
219
- ? `${JSON.stringify(orchestrator, null, 2)}\n`
220
- : renderAgentOrchestratorMarkdown(orchestrator);
221
-
222
- const outputPath = getFlagValue(args, "--out");
223
- if (outputPath) {
224
- const resolvedOutputPath = await writeAgentOrchestratorOutput(outputPath, renderedOutput);
225
- process.stdout.write(`已保存 agent-orchestrator 结果:${resolvedOutputPath}\n`);
226
- return;
227
- }
228
-
229
- process.stdout.write(renderedOutput);
230
- }
231
-
232
- async function handleAgentResume(args) {
233
- const input = args.find((value) => !value.startsWith("-"));
234
- if (!input) {
235
- throw new Error("agent-resume 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
236
- }
237
-
238
- const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
239
- const resume = await createAgentResume(input, {
240
- intent: getFlagValue(args, "--intent"),
241
- format
242
- });
243
- const outputJson = resume.format === "json";
244
- const renderedOutput = outputJson ? `${JSON.stringify(resume, null, 2)}\n` : renderAgentResumeMarkdown(resume);
245
-
246
- const outputPath = getFlagValue(args, "--out");
247
- if (outputPath) {
248
- const resolvedOutputPath = await writeAgentResumeOutput(outputPath, renderedOutput);
249
- process.stdout.write(`已保存 agent-resume 结果:${resolvedOutputPath}\n`);
250
- return;
251
- }
252
-
253
- process.stdout.write(renderedOutput);
254
- }
255
-
256
- async function handleAgentContinue(args) {
257
- const input = args.find((value) => !value.startsWith("-"));
258
- if (!input) {
259
- throw new Error("agent-continue 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
260
- }
261
-
262
- const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
263
- const artifact = await createAgentContinue(input, {
264
- intent: getFlagValue(args, "--intent"),
265
- format
266
- });
267
- const outputJson = artifact.format === "json";
268
- const renderedOutput = outputJson
269
- ? `${JSON.stringify(artifact, null, 2)}\n`
270
- : renderAgentContinueMarkdown(artifact);
271
-
272
- const outputPath = getFlagValue(args, "--out");
273
- if (outputPath) {
274
- const resolvedOutputPath = await writeAgentContinueOutput(outputPath, renderedOutput);
275
- process.stdout.write(`已保存 agent-continue 结果:${resolvedOutputPath}\n`);
276
- return;
277
- }
278
-
279
- process.stdout.write(renderedOutput);
280
- }
281
-
282
- async function handleAgentStatePack(args) {
283
- const input = args.find((value) => !value.startsWith("-"));
284
- if (!input) {
285
- throw new Error("agent-state-pack 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
286
- }
287
-
288
- const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
289
- const artifact = await createAgentStatePack(input, {
290
- intent: getFlagValue(args, "--intent"),
291
- format,
292
- currentTaskId: getFlagValue(args, "--current"),
293
- completedPacketIds: getFlagValue(args, "--completed"),
294
- blockedReasons: getFlagValue(args, "--blocked")
295
- });
296
- const outputJson = artifact.format === "json";
297
- const renderedOutput = outputJson
298
- ? `${JSON.stringify(artifact, null, 2)}\n`
299
- : renderAgentStatePackMarkdown(artifact);
300
-
301
- const outputPath = getFlagValue(args, "--out");
302
- if (outputPath) {
303
- const resolvedOutputPath = await writeAgentStatePackOutput(outputPath, renderedOutput);
304
- process.stdout.write(`已保存 agent-state-pack 结果:${resolvedOutputPath}\n`);
305
- return;
306
- }
307
-
308
- process.stdout.write(renderedOutput);
309
- }
310
-
311
- async function handleAgentSession(args) {
312
- const input = args.find((value) => !value.startsWith("-"));
313
- if (!input) {
314
- throw new Error("agent-session 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
315
- }
316
-
317
- const session = await createAgentSession(input, {
318
- intent: getFlagValue(args, "--intent")
319
- });
320
- const outputJson = hasFlag(args, "--json");
321
- const renderedOutput = outputJson
322
- ? `${JSON.stringify(session, null, 2)}\n`
323
- : renderAgentSessionMarkdown(session);
324
-
325
- const outputPath = getFlagValue(args, "--out");
326
- if (outputPath) {
327
- const resolvedOutputPath = await writeAgentSessionOutput(outputPath, renderedOutput);
328
- process.stdout.write(`已保存 agent-session 结果:${resolvedOutputPath}\n`);
329
- return;
330
- }
331
-
332
- process.stdout.write(renderedOutput);
333
- }
334
-
335
140
  async function handleAgentRunbook(args) {
336
141
  const input = args.find((value) => !value.startsWith("-"));
337
142
  if (!input) {
@@ -1103,6 +908,7 @@ async function handleRoadmap(args) {
1103
908
 
1104
909
  export async function runCli(args = []) {
1105
910
  const [command = "install", ...rest] = args;
911
+ const flowHandler = FLOW_COMMAND_HANDLERS[command];
1106
912
 
1107
913
  if (command === "help" || command === "--help" || command === "-h") {
1108
914
  printHelp();
@@ -1119,33 +925,8 @@ export async function runCli(args = []) {
1119
925
  return;
1120
926
  }
1121
927
 
1122
- if (command === "auto-flow") {
1123
- await handleAutoFlow(rest);
1124
- return;
1125
- }
1126
-
1127
- if (command === "agent-orchestrator") {
1128
- await handleAgentOrchestrator(rest);
1129
- return;
1130
- }
1131
-
1132
- if (command === "agent-resume") {
1133
- await handleAgentResume(rest);
1134
- return;
1135
- }
1136
-
1137
- if (command === "agent-continue") {
1138
- await handleAgentContinue(rest);
1139
- return;
1140
- }
1141
-
1142
- if (command === "agent-state-pack") {
1143
- await handleAgentStatePack(rest);
1144
- return;
1145
- }
1146
-
1147
- if (command === "agent-session") {
1148
- await handleAgentSession(rest);
928
+ if (flowHandler) {
929
+ await flowHandler(rest);
1149
930
  return;
1150
931
  }
1151
932