@fieldwangai/agentflow 0.1.149 → 0.1.154
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 +20 -33
- package/README.zh-CN.md +14 -34
- package/agents/agentflow-node-executor-code.md +13 -3
- package/agents/agentflow-node-executor-planning.md +13 -3
- package/agents/agentflow-node-executor-requirement.md +13 -3
- package/agents/agentflow-node-executor-test.md +13 -3
- package/agents/agentflow-node-executor-ui.md +13 -3
- package/agents/agentflow-node-executor.md +13 -3
- package/agents/en/agentflow-node-executor.md +13 -3
- package/agents/zh/agentflow-node-executor.md +13 -3
- package/bin/agentflow.mjs +3 -3
- package/bin/lib/admin-builtin-pipelines.mjs +3 -2
- package/bin/lib/agent-runners.mjs +0 -929
- package/bin/lib/auth.mjs +2 -1
- package/bin/lib/catalog-agents.mjs +2 -1
- package/bin/lib/catalog-flows.mjs +167 -88
- package/bin/lib/composer-agent.mjs +3 -793
- package/bin/lib/composer-skill-router.mjs +3 -323
- package/bin/lib/exec-buffered.mjs +32 -0
- package/bin/lib/flow-dsl/cli.mjs +276 -0
- package/bin/lib/flow-dsl/codegen.mjs +358 -0
- package/bin/lib/flow-dsl/defs.mjs +103 -0
- package/bin/lib/flow-dsl/index.mjs +77 -0
- package/bin/lib/flow-dsl/ir.mjs +305 -0
- package/bin/lib/flow-dsl/layout.mjs +115 -0
- package/bin/lib/flow-dsl/legacy-yaml.mjs +268 -0
- package/bin/lib/flow-dsl/lint.mjs +241 -0
- package/bin/lib/flow-dsl/packages.mjs +251 -0
- package/bin/lib/flow-dsl/parser.mjs +444 -0
- package/bin/lib/flow-import.mjs +96 -26
- package/bin/lib/flow-write.mjs +48 -12
- package/bin/lib/help.mjs +10 -30
- package/bin/lib/html-escape.mjs +19 -0
- package/bin/lib/http-util.mjs +49 -0
- package/bin/lib/legacy-flow-execution.mjs +43 -0
- package/bin/lib/locales/en.json +1 -1
- package/bin/lib/locales/zh.json +1 -1
- package/bin/lib/main.mjs +153 -283
- package/bin/lib/marketplace.mjs +206 -61
- package/bin/lib/model-config.mjs +10 -0
- package/bin/lib/node-package-archive.mjs +240 -0
- package/bin/lib/node-package-bootstrap.mjs +72 -0
- package/bin/lib/node-package-manifest.mjs +174 -0
- package/bin/lib/paths.mjs +42 -19
- package/bin/lib/prd-workflow-routes.mjs +2949 -0
- package/bin/lib/prd-workflow-server.mjs +4884 -0
- package/bin/lib/run-events.mjs +0 -66
- package/bin/lib/schedule-config.mjs +4 -4
- package/bin/lib/skill-runtime.mjs +35 -0
- package/bin/lib/startup-storage-migrations.mjs +274 -0
- package/bin/lib/ui-server.mjs +1106 -18013
- package/bin/lib/user-env.mjs +16 -0
- package/bin/lib/workspace-auto-layout.mjs +234 -0
- package/bin/lib/workspace-flow-store.mjs +478 -0
- package/bin/lib/workspace-graph-merge.mjs +41 -34
- package/bin/lib/workspace-preview.mjs +74 -0
- package/bin/lib/workspace-routes.mjs +3088 -0
- package/bin/lib/workspace-server.mjs +6199 -0
- package/bin/lib/workspace-state.mjs +331 -0
- package/bin/lib/workspace.mjs +2 -1
- package/builtin/nodes/agent_subAgent.md +1 -0
- package/builtin/nodes/control_agent_toBool.md +2 -0
- package/builtin/nodes/control_anyOne.md +2 -0
- package/builtin/nodes/control_cancelled.md +2 -0
- package/builtin/nodes/control_cd_workspace.md +5 -11
- package/builtin/nodes/control_delay.md +2 -0
- package/builtin/nodes/control_end.md +2 -0
- package/builtin/nodes/control_if.md +1 -0
- package/builtin/nodes/control_interval_loop.md +2 -0
- package/builtin/nodes/control_load_mcp.md +24 -0
- package/builtin/nodes/control_load_skills.md +8 -23
- package/builtin/nodes/control_start.md +2 -0
- package/builtin/nodes/control_toBool.md +2 -0
- package/builtin/nodes/control_user_workspace.md +2 -0
- package/builtin/nodes/control_wait_until.md +2 -0
- package/builtin/nodes/display_ascii.md +1 -0
- package/builtin/nodes/display_chart.md +1 -0
- package/builtin/nodes/display_html.md +1 -0
- package/builtin/nodes/display_image.md +1 -0
- package/builtin/nodes/display_markdown.md +1 -0
- package/builtin/nodes/display_mermaid.md +1 -0
- package/builtin/nodes/display_react_app.md +1 -0
- package/builtin/nodes/display_table.md +1 -0
- package/builtin/nodes/provide_bool.md +1 -0
- package/builtin/nodes/provide_file.md +1 -0
- package/builtin/nodes/provide_password.md +1 -0
- package/builtin/nodes/provide_str.md +1 -0
- package/builtin/nodes/tool_display_share_link.md +1 -0
- package/builtin/nodes/tool_get_env.md +2 -0
- package/builtin/nodes/tool_git_checkout.md +1 -0
- package/builtin/nodes/tool_git_worktree_load.md +1 -0
- package/builtin/nodes/tool_git_worktree_unload.md +1 -0
- package/builtin/nodes/tool_gitlab_create_mr.md +1 -0
- package/builtin/nodes/tool_jenkins_build.md +2 -0
- package/builtin/nodes/tool_load_key.md +2 -0
- package/builtin/nodes/tool_nodejs.md +17 -19
- package/builtin/nodes/tool_print.md +2 -0
- package/builtin/nodes/tool_save_key.md +2 -0
- package/builtin/nodes/tool_set_run_env.md +1 -0
- package/builtin/nodes/tool_user_ask.md +2 -0
- package/builtin/nodes/tool_user_check.md +2 -0
- package/builtin/nodes/tool_wecom_send_app_markdown.md +1 -0
- package/builtin/nodes/tool_wecom_send_group_markdown.md +1 -0
- package/builtin/nodes/workspace_one_click_task.md +44 -0
- package/builtin/nodes/workspace_run.md +16 -0
- package/builtin/nodes/workspace_scheduled_run.md +16 -0
- package/builtin/pipelines/module-migrate/scripts/gate.mjs +37 -0
- package/builtin/pipelines/module-migrate/scripts/static-check.mjs +82 -0
- package/builtin/pipelines/module-migrate/workspace.flow.js +172 -0
- package/builtin/pipelines/module-migrate/workspace.layout.json +134 -0
- package/builtin/pipelines/new/scripts/lint-flow.mjs +38 -0
- package/builtin/pipelines/new/workspace.flow.js +91 -0
- package/builtin/pipelines/new/workspace.layout.json +70 -0
- package/builtin/web-ui/dist/assets/{WorkflowAssistantThread-DPbR2UaN.js → WorkflowAssistantThread-CKClwj96.js} +1 -1
- package/builtin/web-ui/dist/assets/index-BZ5KqLur.js +870 -0
- package/builtin/web-ui/dist/assets/index-CEXmmwM2.css +1 -0
- package/builtin/web-ui/dist/index.html +2 -2
- package/package.json +2 -1
- package/reference/flow-control-capabilities.md +77 -158
- package/reference/flow-layout.md +1 -1
- package/reference/flow-prompt-handler-check.md +2 -2
- package/skills/agentflow-author-flow/SKILL.md +8 -47
- package/skills/agentflow-cli/SKILL.md +158 -25
- package/skills/agentflow-cli/agents/openai.yaml +2 -2
- package/skills/agentflow-cli/scripts/agentflow-cli.mjs +668 -18
- package/skills/agentflow-cli/scripts/agentflow-runtime.mjs +97 -0
- package/skills/agentflow-flow-add-instances/SKILL.md +7 -248
- package/skills/agentflow-flow-dsl/SKILL.md +206 -0
- package/skills/agentflow-flow-dsl/agents/openai.yaml +4 -0
- package/skills/agentflow-flow-dsl/references/node-calls.md +39 -0
- package/skills/agentflow-flow-edit-node-fields/SKILL.md +4 -73
- package/skills/agentflow-flow-recipes/SKILL.md +7 -18
- package/skills/agentflow-flow-recipes/references/recipes.md +97 -43
- package/skills/agentflow-flow-sync-ui/SKILL.md +3 -54
- package/skills/agentflow-node-dsl/SKILL.md +212 -0
- package/skills/agentflow-node-dsl/agents/openai.yaml +4 -0
- package/skills/agentflow-node-reference/SKILL.md +5 -4
- package/skills/agentflow-node-reference/references/builtin-nodes.md +166 -115
- package/skills/agentflow-placeholder-reference/SKILL.md +2 -2
- package/skills/agentflow-runtime-reference/SKILL.md +2 -2
- package/skills/agentflow-runtime-reference/references/runtime.md +1 -1
- package/skills/agentflow-workspace-ascii/SKILL.md +9 -16
- package/skills/agentflow-workspace-graph/SKILL.md +62 -48
- package/skills/agentflow-workspace-html/SKILL.md +7 -2
- package/skills/agentflow-workspace-image/SKILL.md +6 -2
- package/skills/agentflow-workspace-markdown/SKILL.md +14 -21
- package/skills/agentflow-workspace-mermaid/SKILL.md +8 -16
- package/bin/lib/api-runner.mjs +0 -387
- package/bin/lib/apply.mjs +0 -903
- package/bin/lib/composer-flow-instances.mjs +0 -68
- package/bin/lib/composer-flow-skeleton.mjs +0 -334
- package/bin/lib/composer-flow-validate.mjs +0 -47
- package/bin/lib/composer-model-router.mjs +0 -185
- package/bin/lib/composer-node-schema.mjs +0 -303
- package/bin/lib/composer-planner.mjs +0 -751
- package/bin/lib/composer-script-ops.mjs +0 -233
- package/bin/lib/flow-static-preview.mjs +0 -104
- package/bin/lib/hub-login.mjs +0 -54
- package/bin/lib/hub-publish.mjs +0 -159
- package/bin/lib/hub-remote.mjs +0 -189
- package/bin/lib/hub.mjs +0 -299
- package/bin/lib/jenkins.mjs +0 -380
- package/bin/lib/node-execute.mjs +0 -539
- package/bin/lib/normalize-node-tool-command.mjs +0 -97
- package/bin/lib/runtime-context.mjs +0 -243
- package/bin/lib/scheduler.mjs +0 -601
- package/bin/lib/ui-print.mjs +0 -94
- package/bin/pipeline/build-node-prompt.mjs +0 -271
- package/bin/pipeline/check-cache.mjs +0 -191
- package/bin/pipeline/check-flow.mjs +0 -543
- package/bin/pipeline/collect-nodes.mjs +0 -212
- package/bin/pipeline/compute-cache-md5.mjs +0 -177
- package/bin/pipeline/ensure-run-dir.mjs +0 -71
- package/bin/pipeline/gc.mjs +0 -129
- package/bin/pipeline/get-env.mjs +0 -59
- package/bin/pipeline/get-resolved-values.mjs +0 -344
- package/bin/pipeline/load-key.mjs +0 -62
- package/bin/pipeline/parse-flow.mjs +0 -708
- package/bin/pipeline/post-process-control-if.mjs +0 -23
- package/bin/pipeline/post-process-node.mjs +0 -490
- package/bin/pipeline/pre-process-node.mjs +0 -1430
- package/bin/pipeline/resolve-inputs.mjs +0 -201
- package/bin/pipeline/run-tool-nodejs.mjs +0 -167
- package/bin/pipeline/save-key.mjs +0 -93
- package/bin/pipeline/snapshot-prior-round.mjs +0 -70
- package/bin/pipeline/validate-for-ui.mjs +0 -234
- package/bin/pipeline/validate-script-output.mjs +0 -130
- package/bin/pipeline/write-result.mjs +0 -182
- package/builtin/pipelines/module-migrate/flow.yaml +0 -819
- package/builtin/pipelines/new/flow.yaml +0 -545
- package/builtin/pipelines/new/scripts/check-flow.mjs +0 -9
- package/builtin/pipelines/new/scripts/collect-nodes.mjs +0 -211
- package/builtin/web-ui/dist/assets/index-BSCpd5la.js +0 -889
- package/builtin/web-ui/dist/assets/index-DZ328oSo.css +0 -1
- package/skills/agentflow-node-authoring/SKILL.md +0 -57
package/bin/lib/main.mjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
4
|
import chalk from "chalk";
|
|
6
|
-
import { apply, replay, resume } from "./apply.mjs";
|
|
7
5
|
import {
|
|
8
6
|
addRoleJson,
|
|
9
7
|
copyBuiltinAgentJson,
|
|
@@ -20,22 +18,17 @@ import {
|
|
|
20
18
|
readFlowJson,
|
|
21
19
|
readNodeJson,
|
|
22
20
|
} from "./catalog-flows.mjs";
|
|
23
|
-
import { writeFlowYaml } from "./flow-write.mjs";
|
|
24
21
|
import { printHelp } from "./help.mjs";
|
|
25
22
|
import { LOG_LEVELS, log, setLogLevel, setMachineReadable } from "./log.mjs";
|
|
26
23
|
import { updateModelLists } from "./model-lists.mjs";
|
|
27
|
-
import {
|
|
24
|
+
import { LEGACY_PIPELINES_DIR, PIPELINES_DIR, USER_AGENTFLOW_PIPELINES_LABEL } from "./paths.mjs";
|
|
28
25
|
import { isValidUuid, runNodeScript } from "./pipeline-scripts.mjs";
|
|
29
26
|
import { Table } from "./table.mjs";
|
|
30
27
|
import { ensureReference, findFlowNameByUuid, getFlowDir, listRunsWithLogs } from "./workspace.mjs";
|
|
31
28
|
import { startUiServer } from "./ui-server.mjs";
|
|
32
|
-
import {
|
|
33
|
-
import { hubPublish } from "./hub-publish.mjs";
|
|
34
|
-
import { hubListRemote, hubDownload } from "./hub-remote.mjs";
|
|
35
|
-
import { cancelScheduledRun, listScheduleStatuses, startScheduler } from "./scheduler.mjs";
|
|
36
|
-
import { installFlowDependency, listMarketplacePackages, publishNodePackage } from "./marketplace.mjs";
|
|
29
|
+
import { listMarketplacePackages, publishNodePackage } from "./marketplace.mjs";
|
|
37
30
|
import { startMcpServer } from "./mcp-server.mjs";
|
|
38
|
-
import {
|
|
31
|
+
import { LEGACY_FLOW_EXECUTION_DISABLED, LEGACY_FLOW_EXECUTION_MESSAGE } from "./legacy-flow-execution.mjs";
|
|
39
32
|
|
|
40
33
|
async function readStdin() {
|
|
41
34
|
const chunks = [];
|
|
@@ -43,6 +36,31 @@ async function readStdin() {
|
|
|
43
36
|
return Buffer.concat(chunks).toString("utf8");
|
|
44
37
|
}
|
|
45
38
|
|
|
39
|
+
/**
|
|
40
|
+
* 把 yaml 迁移的损耗清单打到 stderr。
|
|
41
|
+
*
|
|
42
|
+
* 迁移唯一的卖点就是「丢了什么当场说清楚」,所以这段在成功和拒绝两种结局下都要打——
|
|
43
|
+
* `--allow-loss` 迁过去了不代表没丢东西,只代表用户认了。
|
|
44
|
+
*/
|
|
45
|
+
function writeMigrationLoss(result) {
|
|
46
|
+
for (const r of result.remapped || []) {
|
|
47
|
+
process.stderr.write(`${chalk.cyan("换词")} ${r.id}: ${r.from} -> ${r.to}\n`);
|
|
48
|
+
for (const rn of r.renamedSlots || []) process.stderr.write(` 槽位 ${rn}\n`);
|
|
49
|
+
for (const f of r.droppedFields || []) {
|
|
50
|
+
// 原文照打——新节点装不下,用户得能直接捡走贴到别处
|
|
51
|
+
process.stderr.write(` ${chalk.yellow("丢")} ${f.field}: ${JSON.stringify(f.text)}\n`);
|
|
52
|
+
}
|
|
53
|
+
if (r.caveat) process.stderr.write(` ${chalk.yellow("!")} ${r.caveat}\n`);
|
|
54
|
+
}
|
|
55
|
+
for (const d of result.dropped || []) {
|
|
56
|
+
process.stderr.write(`${chalk.red("丢节点")} ${d.id} (${d.definitionId}):${d.reason}\n`);
|
|
57
|
+
}
|
|
58
|
+
for (const e of result.droppedEdges || []) {
|
|
59
|
+
process.stderr.write(`${chalk.red("丢边")} ${e.source} -> ${e.target}:${e.reason}\n`);
|
|
60
|
+
}
|
|
61
|
+
for (const w of result.warnings || []) process.stderr.write(`${chalk.yellow("warn")} ${w}\n`);
|
|
62
|
+
}
|
|
63
|
+
|
|
46
64
|
export async function main() {
|
|
47
65
|
const argv = process.argv.slice(2);
|
|
48
66
|
let workspaceRoot = process.cwd();
|
|
@@ -60,54 +78,26 @@ export async function main() {
|
|
|
60
78
|
printHelp();
|
|
61
79
|
process.exit(0);
|
|
62
80
|
}
|
|
63
|
-
|
|
64
|
-
if (dryRun) argv.splice(argv.indexOf("--dry-run"), 1);
|
|
81
|
+
if (argv.includes("--dry-run")) argv.splice(argv.indexOf("--dry-run"), 1);
|
|
65
82
|
if (argv.includes("--debug")) {
|
|
66
83
|
setLogLevel(LOG_LEVELS.debug);
|
|
67
84
|
argv.splice(argv.indexOf("--debug"), 1);
|
|
68
85
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
argv.splice(argv.indexOf("--no-force"), 1);
|
|
73
|
-
}
|
|
74
|
-
if (argv.includes("--force")) {
|
|
75
|
-
force = true;
|
|
76
|
-
argv.splice(argv.indexOf("--force"), 1);
|
|
77
|
-
}
|
|
78
|
-
if (argv.includes("--yolo")) {
|
|
79
|
-
force = true;
|
|
80
|
-
argv.splice(argv.indexOf("--yolo"), 1);
|
|
81
|
-
}
|
|
82
|
-
let parallel = false;
|
|
83
|
-
if (argv.includes("--parallel")) {
|
|
84
|
-
parallel = true;
|
|
85
|
-
argv.splice(argv.indexOf("--parallel"), 1);
|
|
86
|
-
}
|
|
87
|
-
if (argv.includes("--no-parallel")) {
|
|
88
|
-
parallel = false;
|
|
89
|
-
argv.splice(argv.indexOf("--no-parallel"), 1);
|
|
86
|
+
// 以下开关只服务已下线的 Start/End 执行,保留解析以免旧脚本把它们当成子命令。
|
|
87
|
+
for (const legacyFlag of ["--no-force", "--force", "--yolo", "--parallel", "--no-parallel"]) {
|
|
88
|
+
while (argv.includes(legacyFlag)) argv.splice(argv.indexOf(legacyFlag), 1);
|
|
90
89
|
}
|
|
91
90
|
if (argv.includes("--machine-readable")) {
|
|
92
91
|
setMachineReadable(true);
|
|
93
92
|
argv.splice(argv.indexOf("--machine-readable"), 1);
|
|
94
93
|
}
|
|
95
94
|
const jsonMode = argv.includes("--json");
|
|
96
|
-
const cliInputs = {};
|
|
97
95
|
while (argv.includes("--input")) {
|
|
98
96
|
const idx = argv.indexOf("--input");
|
|
99
97
|
const pair = argv[idx + 1];
|
|
100
98
|
if (!pair || !pair.includes("=")) {
|
|
101
99
|
throw new Error("Invalid --input format. Use: --input name=value");
|
|
102
100
|
}
|
|
103
|
-
const eqIdx = pair.indexOf("=");
|
|
104
|
-
const name = pair.slice(0, eqIdx);
|
|
105
|
-
const value = pair.slice(eqIdx + 1);
|
|
106
|
-
if (value.startsWith("file:")) {
|
|
107
|
-
cliInputs[name] = { type: "file", path: value.slice(5) };
|
|
108
|
-
} else {
|
|
109
|
-
cliInputs[name] = { type: "str", value };
|
|
110
|
-
}
|
|
111
101
|
argv.splice(idx, 2);
|
|
112
102
|
}
|
|
113
103
|
const sub = shift();
|
|
@@ -128,7 +118,6 @@ export async function main() {
|
|
|
128
118
|
"list-flows",
|
|
129
119
|
"list-nodes",
|
|
130
120
|
"read-flow",
|
|
131
|
-
"write-flow",
|
|
132
121
|
"read-node",
|
|
133
122
|
"copy-builtin",
|
|
134
123
|
"list-agents",
|
|
@@ -139,12 +128,8 @@ export async function main() {
|
|
|
139
128
|
if (jsonMode && jsonOnlySubs.includes(sub)) {
|
|
140
129
|
argv.splice(argv.indexOf("--json"), 1);
|
|
141
130
|
}
|
|
142
|
-
let agentModel = process.env.CURSOR_AGENT_MODEL || null;
|
|
143
131
|
const modelIdx = argv.indexOf("--model");
|
|
144
|
-
if (modelIdx >= 0 && argv[modelIdx + 1])
|
|
145
|
-
agentModel = argv[modelIdx + 1];
|
|
146
|
-
argv.splice(modelIdx, 2);
|
|
147
|
-
}
|
|
132
|
+
if (modelIdx >= 0 && argv[modelIdx + 1]) argv.splice(modelIdx, 2);
|
|
148
133
|
if (sub === "list-flows" && jsonMode) {
|
|
149
134
|
const list = listFlowsJson(workspaceRoot);
|
|
150
135
|
process.stdout.write(JSON.stringify(list) + "\n");
|
|
@@ -242,19 +227,7 @@ export async function main() {
|
|
|
242
227
|
else throw new Error(result.error || "publish-node failed");
|
|
243
228
|
process.exit(result.ok ? 0 : 1);
|
|
244
229
|
}
|
|
245
|
-
|
|
246
|
-
const flowId = shift();
|
|
247
|
-
const spec = shift();
|
|
248
|
-
if (!flowId || !spec) throw new Error("Usage: agentflow marketplace install-node <flow> <nodeSpec> [--json]");
|
|
249
|
-
const flowDir = getFlowDir(workspaceRoot, flowId);
|
|
250
|
-
if (!flowDir) throw new Error(`Flow not found: ${flowId}`);
|
|
251
|
-
const result = installFlowDependency(workspaceRoot, flowDir, spec);
|
|
252
|
-
if (jsonMode) process.stdout.write(JSON.stringify(result) + "\n");
|
|
253
|
-
else if (result.ok) process.stdout.write(`Installed ${result.definitionId} into ${flowId}\n`);
|
|
254
|
-
else throw new Error(result.error || "install-node failed");
|
|
255
|
-
process.exit(result.ok ? 0 : 1);
|
|
256
|
-
}
|
|
257
|
-
throw new Error("Usage: agentflow marketplace <list|publish-node|install-node> [--json]");
|
|
230
|
+
throw new Error("Usage: agentflow marketplace <list|publish-node> [--json]");
|
|
258
231
|
}
|
|
259
232
|
if (sub === "copy-builtin" && jsonMode) {
|
|
260
233
|
const flowId = shift();
|
|
@@ -320,101 +293,105 @@ export async function main() {
|
|
|
320
293
|
process.stdout.write(JSON.stringify(result) + "\n");
|
|
321
294
|
process.exit(result.success ? 0 : 1);
|
|
322
295
|
}
|
|
323
|
-
if (sub === "
|
|
324
|
-
let flowSource = "user";
|
|
325
|
-
const flowSourceIdx = argv.indexOf("--flow-source");
|
|
326
|
-
if (flowSourceIdx >= 0 && argv[flowSourceIdx + 1]) {
|
|
327
|
-
flowSource = argv[flowSourceIdx + 1];
|
|
328
|
-
argv.splice(flowSourceIdx, 2);
|
|
329
|
-
}
|
|
330
|
-
if (flowSource === "builtin") {
|
|
331
|
-
process.stderr.write(
|
|
332
|
-
"agentflow: --flow-source builtin 已弃用(包内 builtin 不可写);已按 workspace 写入 .workspace/agentflow/pipelines。\n",
|
|
333
|
-
);
|
|
334
|
-
flowSource = "workspace";
|
|
335
|
-
}
|
|
336
|
-
if (flowSource !== "user" && flowSource !== "workspace") {
|
|
337
|
-
process.stdout.write(
|
|
338
|
-
JSON.stringify({ success: false, error: "Invalid --flow-source (use user or workspace)" }) + "\n",
|
|
339
|
-
);
|
|
340
|
-
process.exit(1);
|
|
341
|
-
}
|
|
342
|
-
const flowId = argv.find((a) => !a.startsWith("--"));
|
|
343
|
-
if (!flowId) {
|
|
344
|
-
process.stdout.write(JSON.stringify({ success: false, error: "Missing flowId" }) + "\n");
|
|
345
|
-
process.exit(1);
|
|
346
|
-
}
|
|
347
|
-
const flowYaml = await readStdin();
|
|
348
|
-
const result = writeFlowYaml(workspaceRoot, flowId, flowSource, flowYaml);
|
|
349
|
-
process.stdout.write(JSON.stringify(result.success ? { success: true } : result) + "\n");
|
|
350
|
-
process.exit(result.success ? 0 : 1);
|
|
351
|
-
}
|
|
352
|
-
if (sub === "flow" && argv[0] === "preview") {
|
|
296
|
+
if (sub === "flow" && argv[0] === "dsl") {
|
|
353
297
|
shift();
|
|
298
|
+
const action = shift();
|
|
354
299
|
const target = shift();
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
300
|
+
const usage = "Usage: agentflow flow dsl <export|import|lint|layout|migrate> <FlowName|dir> [--out <dir>] [--allow-loss] [--all]";
|
|
301
|
+
if (!action || !target) throw new Error(usage);
|
|
302
|
+
let outDir = "";
|
|
303
|
+
const outIdx = argv.indexOf("--out");
|
|
304
|
+
if (outIdx >= 0 && argv[outIdx + 1]) {
|
|
305
|
+
outDir = path.resolve(workspaceRoot, argv[outIdx + 1]);
|
|
306
|
+
argv.splice(outIdx, 2);
|
|
307
|
+
}
|
|
308
|
+
// 不叫 --force:那个名字在上面被当成已下线执行栈的遗留开关提前吃掉了
|
|
309
|
+
const lossIdx = argv.indexOf("--allow-loss");
|
|
310
|
+
const force = lossIdx >= 0;
|
|
311
|
+
if (force) argv.splice(lossIdx, 1);
|
|
312
|
+
const allIdx = argv.indexOf("--all");
|
|
313
|
+
const all = allIdx >= 0;
|
|
314
|
+
if (all) argv.splice(allIdx, 1);
|
|
315
|
+
if (argv.length > 0) throw new Error(`Unknown flow dsl option: ${argv[0]}`);
|
|
316
|
+
if (all && action !== "layout") throw new Error("--all 只用于 flow dsl layout");
|
|
365
317
|
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
marketplaceScope: "all",
|
|
389
|
-
});
|
|
390
|
-
const result = writeStaticFlowPreview({
|
|
391
|
-
flowId,
|
|
392
|
-
flowPath: previewFlowPath,
|
|
393
|
-
nodeCatalog,
|
|
394
|
-
outputPath,
|
|
395
|
-
distDir: path.join(path.dirname(path.dirname(path.dirname(fileURLToPath(import.meta.url)))), "builtin", "web-ui", "dist"),
|
|
396
|
-
});
|
|
397
|
-
const url = pathToFileURL(result.outputPath).href;
|
|
398
|
-
process.stderr.write(`AgentFlow static preview: ${result.outputPath}\nSource: ${previewFlowPath}\n`);
|
|
399
|
-
if (!noOpen) {
|
|
400
|
-
if (process.platform === "win32") {
|
|
401
|
-
const child = spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" });
|
|
402
|
-
child.unref();
|
|
403
|
-
} else if (process.platform === "darwin") {
|
|
404
|
-
const child = spawn("open", [url], { detached: true, stdio: "ignore" });
|
|
405
|
-
child.unref();
|
|
318
|
+
const direct = path.resolve(workspaceRoot, target);
|
|
319
|
+
const dir = fs.existsSync(direct) && fs.statSync(direct).isDirectory()
|
|
320
|
+
? direct
|
|
321
|
+
: getFlowDir(workspaceRoot, target);
|
|
322
|
+
if (!dir || !fs.existsSync(dir)) throw new Error(`Flow not found: ${target}`);
|
|
323
|
+
|
|
324
|
+
const { exportFlowDsl, importFlowDsl, layoutWorkspaceFlowDir, lintFlowDir, migrateFlowDirToDsl } = await import("./flow-dsl/cli.mjs");
|
|
325
|
+
|
|
326
|
+
if (action === "migrate") {
|
|
327
|
+
const result = migrateFlowDirToDsl(dir, { force, marketplaceRoot: workspaceRoot });
|
|
328
|
+
if (jsonMode) { process.stdout.write(JSON.stringify(result) + "\n"); return; }
|
|
329
|
+
if (result.format === "empty") process.stderr.write(`${chalk.yellow("skip")} ${dir}:没有图\n`);
|
|
330
|
+
else if (!result.migrated && result.format === "dsl") process.stderr.write(`${chalk.green("ok")} ${dir}:已经是代码形态\n`);
|
|
331
|
+
else if (result.migrated) {
|
|
332
|
+
process.stderr.write(`${chalk.green("ok")} ${dir} -> workspace.flow.js(来自 ${result.source})\n`);
|
|
333
|
+
for (const rel of result.externals) process.stderr.write(` ${rel}\n`);
|
|
334
|
+
} else if (result.leftYaml) {
|
|
335
|
+
// 够不着代码形态,但已经离开 yaml——图从此读得出、画得出、跑得动
|
|
336
|
+
process.stderr.write(`${chalk.green("ok")} ${dir} -> workspace.graph.json(来自 flow.yaml)\n`);
|
|
337
|
+
process.stderr.write(` ${chalk.dim(`还差一步到代码:${result.degradedReason}`)}\n`);
|
|
338
|
+
} else if (result.format === "yaml") {
|
|
339
|
+
process.stderr.write(`${chalk.red("keep")} ${dir}:${result.degradedReason}\n`);
|
|
406
340
|
} else {
|
|
407
|
-
|
|
408
|
-
|
|
341
|
+
process.stderr.write(`${chalk.red("keep")} ${dir}:${result.degradedReason},保留 workspace.graph.json\n`);
|
|
342
|
+
process.exitCode = 1;
|
|
409
343
|
}
|
|
344
|
+
// 损耗清单在成功和拒绝两种结局下都要打出来——`--allow-loss` 迁过去了不代表没丢东西
|
|
345
|
+
writeMigrationLoss(result);
|
|
346
|
+
if (result.format === "yaml" && !result.migrated) process.exitCode = 1;
|
|
347
|
+
return;
|
|
410
348
|
}
|
|
411
|
-
|
|
349
|
+
|
|
350
|
+
if (action === "export") {
|
|
351
|
+
const result = exportFlowDsl(dir, outDir);
|
|
352
|
+
if (jsonMode) { process.stdout.write(JSON.stringify(result) + "\n"); return; }
|
|
353
|
+
else {
|
|
354
|
+
process.stderr.write(`Exported to ${result.outDir}\n`);
|
|
355
|
+
for (const rel of result.written) process.stderr.write(` ${rel}\n`);
|
|
356
|
+
}
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (action === "import") {
|
|
360
|
+
const result = importFlowDsl(dir, outDir);
|
|
361
|
+
if (jsonMode) { process.stdout.write(JSON.stringify(result) + "\n"); return; }
|
|
362
|
+
else {
|
|
363
|
+
process.stderr.write(`Wrote ${result.graphPath}\n ${result.nodeCount} 节点 / ${result.edgeCount} 边\n`);
|
|
364
|
+
for (const w of result.warnings) process.stderr.write(` warning: ${w}\n`);
|
|
365
|
+
}
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (action === "lint") {
|
|
369
|
+
const result = lintFlowDir(dir, { workspaceRoot });
|
|
370
|
+
if (jsonMode) process.stdout.write(JSON.stringify({ errors: result.errors, warnings: result.warnings }) + "\n");
|
|
371
|
+
else {
|
|
372
|
+
for (const e of result.errors) process.stderr.write(`${chalk.red("error")} ${e}\n`);
|
|
373
|
+
for (const w of result.warnings) process.stderr.write(`${chalk.yellow("warn")} ${w}\n`);
|
|
374
|
+
if (!result.errors.length) process.stderr.write(`${chalk.green("ok")} lint 通过\n`);
|
|
375
|
+
}
|
|
376
|
+
if (result.errors.length) process.exitCode = 1;
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
if (action === "layout") {
|
|
380
|
+
const result = layoutWorkspaceFlowDir(dir, { all, workspaceRoot });
|
|
381
|
+
if (jsonMode) process.stdout.write(JSON.stringify(result) + "\n");
|
|
382
|
+
else process.stderr.write(`${chalk.green("ok")} ${result.positioned}/${result.nodeCount} 个节点已${all ? "重新" : "补充"}排版\n ${result.layoutPath}\n`);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
throw new Error(usage);
|
|
386
|
+
}
|
|
387
|
+
if (sub === "flow") {
|
|
388
|
+
// `flow preview` 曾经在这儿。它把 flow.yaml 原文塞进页面,代码化流程没有 yaml 可塞;
|
|
389
|
+
// Web 的 /api/workspace/preview 接的是图对象,本来就通用,所以删掉而不是重写。
|
|
390
|
+
throw new Error("Usage: agentflow flow dsl <export|import|lint|layout|migrate> <FlowName|dir> [--out <dir>] [--all]");
|
|
412
391
|
}
|
|
413
392
|
if (sub === "ui") {
|
|
414
393
|
let port = 8765;
|
|
415
394
|
let host = process.env.AGENTFLOW_UI_HOST || "127.0.0.1";
|
|
416
|
-
let schedulerEnabled = false;
|
|
417
|
-
let schedulerPollMs;
|
|
418
395
|
let hideCommunityLinks = /^(1|true|yes|on)$/i.test(String(process.env.AGENTFLOW_HIDE_COMMUNITY_LINKS || ""));
|
|
419
396
|
const portIdx = argv.indexOf("--port");
|
|
420
397
|
if (portIdx >= 0 && argv[portIdx + 1]) {
|
|
@@ -426,19 +403,6 @@ export async function main() {
|
|
|
426
403
|
host = argv[hostIdx + 1];
|
|
427
404
|
argv.splice(hostIdx, 2);
|
|
428
405
|
}
|
|
429
|
-
if (argv.includes("--scheduler")) {
|
|
430
|
-
schedulerEnabled = true;
|
|
431
|
-
argv.splice(argv.indexOf("--scheduler"), 1);
|
|
432
|
-
}
|
|
433
|
-
if (argv.includes("--no-scheduler")) {
|
|
434
|
-
schedulerEnabled = false;
|
|
435
|
-
argv.splice(argv.indexOf("--no-scheduler"), 1);
|
|
436
|
-
}
|
|
437
|
-
const schedulerPollIdx = argv.indexOf("--scheduler-poll-ms");
|
|
438
|
-
if (schedulerPollIdx >= 0 && argv[schedulerPollIdx + 1]) {
|
|
439
|
-
schedulerPollMs = parseInt(argv[schedulerPollIdx + 1], 10);
|
|
440
|
-
argv.splice(schedulerPollIdx, 2);
|
|
441
|
-
}
|
|
442
406
|
const noOpen = argv.includes("--no-open");
|
|
443
407
|
if (noOpen) argv.splice(argv.indexOf("--no-open"), 1);
|
|
444
408
|
if (argv.includes("--hide-community-links")) {
|
|
@@ -452,11 +416,6 @@ export async function main() {
|
|
|
452
416
|
throw new Error("Invalid --host");
|
|
453
417
|
}
|
|
454
418
|
await startUiServer({ workspaceRoot, port, host, hideCommunityLinks });
|
|
455
|
-
if (schedulerEnabled) {
|
|
456
|
-
startScheduler(workspaceRoot, { pollMs: schedulerPollMs }).catch((e) => {
|
|
457
|
-
log.error("Scheduler failed: " + ((e && e.message) || String(e)));
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
419
|
const browserHost = host === "0.0.0.0" || host === "::" ? "127.0.0.1" : host;
|
|
461
420
|
const url = "http://" + (browserHost.includes(":") ? `[${browserHost}]` : browserHost) + ":" + port;
|
|
462
421
|
process.stderr.write("AgentFlow UI: " + url + (browserHost === host ? "" : ` (listening on ${host}:${port})`) + "\n");
|
|
@@ -474,127 +433,12 @@ export async function main() {
|
|
|
474
433
|
}
|
|
475
434
|
await new Promise(() => {});
|
|
476
435
|
}
|
|
477
|
-
if (sub === "scheduler") {
|
|
478
|
-
const action = shift();
|
|
479
|
-
if (action === "start") {
|
|
480
|
-
let pollMs;
|
|
481
|
-
const pollIdx = argv.indexOf("--poll-ms");
|
|
482
|
-
if (pollIdx >= 0 && argv[pollIdx + 1]) {
|
|
483
|
-
pollMs = parseInt(argv[pollIdx + 1], 10);
|
|
484
|
-
argv.splice(pollIdx, 2);
|
|
485
|
-
}
|
|
486
|
-
const once = argv.includes("--once");
|
|
487
|
-
if (once) argv.splice(argv.indexOf("--once"), 1);
|
|
488
|
-
await startScheduler(workspaceRoot, { pollMs, once });
|
|
489
|
-
process.exit(0);
|
|
490
|
-
}
|
|
491
|
-
if (action === "status") {
|
|
492
|
-
if (jsonMode) {
|
|
493
|
-
process.stdout.write(JSON.stringify({ schedules: listScheduleStatuses(workspaceRoot) }) + "\n");
|
|
494
|
-
process.exit(0);
|
|
495
|
-
}
|
|
496
|
-
const rows = listScheduleStatuses(workspaceRoot);
|
|
497
|
-
const table = new Table({ head: ["flow", "source", "enabled", "cron", "timezone", "next", "running", "waiting", "lastRun", "error"], style: { head: [] } });
|
|
498
|
-
for (const r of rows) {
|
|
499
|
-
table.push([
|
|
500
|
-
r.flowId,
|
|
501
|
-
r.flowSource,
|
|
502
|
-
r.enabled ? "yes" : "no",
|
|
503
|
-
r.cron || "",
|
|
504
|
-
r.timezone || "",
|
|
505
|
-
r.nextRunAt || "",
|
|
506
|
-
r.running ? "yes" : "no",
|
|
507
|
-
String(r.waiting || 0),
|
|
508
|
-
r.lastRunUuid || "",
|
|
509
|
-
r.lastError || "",
|
|
510
|
-
]);
|
|
511
|
-
}
|
|
512
|
-
process.stdout.write(table.toString() + "\n");
|
|
513
|
-
process.exit(0);
|
|
514
|
-
}
|
|
515
|
-
if (action === "cancel") {
|
|
516
|
-
const flowId = shift();
|
|
517
|
-
const uuid = shift();
|
|
518
|
-
if (!flowId || !uuid) throw new Error("Usage: agentflow scheduler cancel <flow> <uuid> [--json]");
|
|
519
|
-
const result = cancelScheduledRun(workspaceRoot, flowId, uuid);
|
|
520
|
-
if (jsonMode) {
|
|
521
|
-
process.stdout.write(JSON.stringify(result) + "\n");
|
|
522
|
-
} else if (result.ok) {
|
|
523
|
-
process.stdout.write(`Cancelled ${flowId}/${uuid}; updated waits: ${result.updatedWaits}\n`);
|
|
524
|
-
} else {
|
|
525
|
-
throw new Error(result.error || "cancel failed");
|
|
526
|
-
}
|
|
527
|
-
process.exit(result.ok ? 0 : 1);
|
|
528
|
-
}
|
|
529
|
-
throw new Error("Usage: agentflow scheduler <start|status|cancel> [--once] [--poll-ms <ms>] [--json]");
|
|
530
|
-
}
|
|
531
436
|
// ──── Hub commands ────
|
|
532
|
-
if (sub === "login") {
|
|
533
|
-
await hubLogin(argv);
|
|
534
|
-
process.exit(0);
|
|
535
|
-
}
|
|
536
|
-
if (sub === "logout") {
|
|
537
|
-
hubLogout();
|
|
538
|
-
process.exit(0);
|
|
539
|
-
}
|
|
540
|
-
if (sub === "publish") {
|
|
541
|
-
await hubPublish(workspaceRoot, argv);
|
|
542
|
-
process.exit(0);
|
|
543
|
-
}
|
|
544
|
-
if (sub === "list-remote") {
|
|
545
|
-
await hubListRemote(argv);
|
|
546
|
-
process.exit(0);
|
|
547
|
-
}
|
|
548
|
-
if (sub === "download") {
|
|
549
|
-
await hubDownload(argv);
|
|
550
|
-
process.exit(0);
|
|
551
|
-
}
|
|
552
437
|
// ──── Local commands ────
|
|
553
438
|
if (sub === "list") {
|
|
554
439
|
listPipelines(workspaceRoot);
|
|
555
|
-
} else if (sub === "apply") {
|
|
556
|
-
|
|
557
|
-
if (aiMode) {
|
|
558
|
-
argv.shift();
|
|
559
|
-
const step = argv.shift();
|
|
560
|
-
if (!step || !APPLY_AI_STEPS.includes(step)) {
|
|
561
|
-
throw new Error(
|
|
562
|
-
"Missing or invalid step. Usage: agentflow apply -ai <step> <args...>. Steps: " + APPLY_AI_STEPS.join(", "),
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
if (argv.length === 0) {
|
|
566
|
-
throw new Error("Missing args for step " + step + ". Example: agentflow apply -ai ensure-run-dir <workspaceRoot> [uuid] <flowName>");
|
|
567
|
-
}
|
|
568
|
-
const stepWorkspaceRoot = path.resolve(argv[0]);
|
|
569
|
-
ensureReference(stepWorkspaceRoot);
|
|
570
|
-
const scriptName = step + ".mjs";
|
|
571
|
-
const result = runNodeScript(stepWorkspaceRoot, scriptName, argv, { captureStdout: false });
|
|
572
|
-
process.exit(result.status ?? 0);
|
|
573
|
-
}
|
|
574
|
-
const first = shift();
|
|
575
|
-
if (!first) throw new Error("Missing FlowName or uuid. Usage: agentflow apply <FlowName> [uuid] | agentflow apply <uuid>");
|
|
576
|
-
let flowName, uuidArg;
|
|
577
|
-
if (isValidUuid(first)) {
|
|
578
|
-
flowName = findFlowNameByUuid(workspaceRoot, first);
|
|
579
|
-
if (!flowName) throw new Error("No run found for uuid " + first + ". Run apply with FlowName first (e.g. agentflow apply <FlowName>).");
|
|
580
|
-
uuidArg = first;
|
|
581
|
-
} else {
|
|
582
|
-
flowName = first;
|
|
583
|
-
uuidArg = isValidUuid(argv[0]) ? shift() : undefined;
|
|
584
|
-
}
|
|
585
|
-
await apply(workspaceRoot, flowName, uuidArg, dryRun, agentModel, force, parallel, cliInputs);
|
|
586
|
-
} else if (sub === "resume") {
|
|
587
|
-
const flowName = shift();
|
|
588
|
-
const uuidArg = shift();
|
|
589
|
-
if (!flowName || !uuidArg) throw new Error("Usage: agentflow resume <FlowName> <uuid> [instanceId]");
|
|
590
|
-
const instanceIdOpt = argv.length > 0 && !argv[0].startsWith("--") ? shift() : undefined;
|
|
591
|
-
await resume(workspaceRoot, flowName, uuidArg, instanceIdOpt, agentModel, force, parallel);
|
|
592
|
-
} else if (sub === "replay") {
|
|
593
|
-
const a = shift(),
|
|
594
|
-
b = shift(),
|
|
595
|
-
c = shift();
|
|
596
|
-
if (!a || !b) throw new Error("Usage: agentflow replay <uuid> <instanceId> or agentflow replay <flowName> <uuid> <instanceId>");
|
|
597
|
-
await replay(workspaceRoot, a, b, c, agentModel, force);
|
|
440
|
+
} else if (sub === "apply" || sub === "resume" || sub === "replay") {
|
|
441
|
+
throw new Error(LEGACY_FLOW_EXECUTION_MESSAGE);
|
|
598
442
|
} else if (sub === "run-status") {
|
|
599
443
|
const flowName = shift();
|
|
600
444
|
const uuidArg = shift();
|
|
@@ -659,6 +503,33 @@ export async function main() {
|
|
|
659
503
|
", or builtin)",
|
|
660
504
|
);
|
|
661
505
|
}
|
|
506
|
+
// Workspace 图归 flow dsl lint 管。validate-flow.mjs 校验的是 flow.yaml,而 Workspace
|
|
507
|
+
// 流程的 flow.yaml 只是个空壳,让它去校验只会得到「必须包含 instances 且至少一个节点」
|
|
508
|
+
// 这种必然失败的结论。
|
|
509
|
+
const { lintWorkspaceFlowDir } = await import("./flow-dsl/cli.mjs");
|
|
510
|
+
const workspaceLint = lintWorkspaceFlowDir(flowDir);
|
|
511
|
+
if (workspaceLint.format !== "empty") {
|
|
512
|
+
if (wantJson || process.stdout.isTTY !== true) {
|
|
513
|
+
process.stdout.write(JSON.stringify({
|
|
514
|
+
ok: workspaceLint.errors.length === 0,
|
|
515
|
+
target: "workspace",
|
|
516
|
+
errors: workspaceLint.errors,
|
|
517
|
+
warnings: workspaceLint.warnings,
|
|
518
|
+
}) + "\n");
|
|
519
|
+
} else {
|
|
520
|
+
process.stdout.write(`\n${chalk.bold("校验: ")}${flowName} ${
|
|
521
|
+
workspaceLint.errors.length ? chalk.red("✗ 未通过") : chalk.green("✓ 通过")
|
|
522
|
+
}\n`);
|
|
523
|
+
for (const e of workspaceLint.errors) process.stdout.write(`${chalk.red(" • ")}${e}\n`);
|
|
524
|
+
for (const w of workspaceLint.warnings) process.stdout.write(`${chalk.yellow(" ! ")}${w}\n`);
|
|
525
|
+
if (workspaceLint.format === "json") {
|
|
526
|
+
process.stdout.write(chalk.dim(" (这张图还是 workspace.graph.json;跑 agentflow flow dsl migrate 转成代码)\n"));
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
process.exit(workspaceLint.errors.length ? 1 : 0);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
|
|
662
533
|
const args = [workspaceRoot, flowName, flowDir];
|
|
663
534
|
if (uuidArg) args.push(uuidArg);
|
|
664
535
|
const result = runNodeScript(workspaceRoot, "validate-flow.mjs", args, { captureStdout: true });
|
|
@@ -720,7 +591,6 @@ export async function main() {
|
|
|
720
591
|
} else if (
|
|
721
592
|
sub === "list-flows" ||
|
|
722
593
|
sub === "read-flow" ||
|
|
723
|
-
sub === "write-flow" ||
|
|
724
594
|
sub === "read-node" ||
|
|
725
595
|
sub === "copy-builtin" ||
|
|
726
596
|
sub === "copy-builtin-agent" ||
|
|
@@ -732,7 +602,7 @@ export async function main() {
|
|
|
732
602
|
throw new Error(
|
|
733
603
|
"Unknown command: " +
|
|
734
604
|
sub +
|
|
735
|
-
". Use
|
|
605
|
+
". Use list, ui, validate, run-status, extract-thinking, flow, marketplace, mcp.",
|
|
736
606
|
);
|
|
737
607
|
}
|
|
738
608
|
}
|