@flowweave-ai/cli 0.4.0 → 0.5.0
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 +5 -1
- package/bin/flowweave.mjs +122 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@ flowweave health --ready
|
|
|
13
13
|
|
|
14
14
|
页面域命令包括 `node`、`node-directory`、`capability`、`event-trigger`、`environment`、`credential`、`flow`、`run`、`schedule`、`model` 和 `agent`。它们分别覆盖节点资产、能力仓库、运行事件触发器、终端环境、网站认证条目、流程编排、FlowRun、周期调度、大模型配置与 Agent 工作台的常用原子操作。`credential` 管理网站凭据,不等于 `auth` 用户登录。每个命令的 JSON 请求体与在线 OpenAPI 一致;运行 `flowweave <域> --help` 查看映射。
|
|
15
15
|
|
|
16
|
+
工作区浏览支持按需详情、增量目录、受授权的 Git 历史/提交/Diff 与创建普通文件或目录:使用 `agent workspace-details [--full-index]|workspace-directory|workspace-git-repositories|workspace-git-log|workspace-git-commit|workspace-git-diff|workspace-entry-create` 处理顶层 Agent Workspace;在 FlowRun 节点范围内使用对应的 `run workspace-* <run-id> --attempt <attempt-id>`。`--full-index` 只在用户确实需要完整索引时使用,默认优先按目录读取。Git 操作只接受由工作区 API 返回的 `repository_path`、commit 和文件路径,不能从本地或显示名称猜测。`agent hydration|head` 与 `run hydration|head` 读取会话原生状态;它们不修改 Conversation。
|
|
17
|
+
|
|
18
|
+
连续自动记录的可移植初始配置使用 `run automatic-config-export <parent-run-id> --data-file ./.tmp/export.json` 和 `run automatic-config-import <parent-run-id> --data-file ./.tmp/import.json`。导出只接受已读取的连续记录 ID;导入会创建记录,先 dry-run 审阅格式版本、起始节点与节点计划。遇到明确的原生完成动作未投影时,才可在读取当前 Attempt 后使用 `run reconcile-runtime-completion <attempt-id> --data '{"expected_state_version": 3}'`;该操作必须携带当前状态版本,不能用来猜测或强制完成运行。
|
|
19
|
+
|
|
16
20
|
常用命令示例:
|
|
17
21
|
|
|
18
22
|
`flowweave node-directory delete-many --id <directory-id> --id <directory-id> --dry-run`、`flowweave credential delete-many --id <credential-id> --id <credential-id>`、`flowweave environment publish <setup-session-id> --description '升级 Python 依赖'`、`flowweave agent file-delete <workspace-id> --path <workspace-api-returned-path>`、`flowweave run workspace-delete <run-id> --attempt <attempt-id> --path <attempt-workspace-api-returned-path>`。
|
|
@@ -21,7 +25,7 @@ flowweave health --ready
|
|
|
21
25
|
|
|
22
26
|
读取 FlowRun 中的记录使用 `flowweave run node <run-id> --node <node-run-id>`;只有用户明确要求时才能执行 `node-copy` 或 `node-delete`。暂停或恢复 Runtime 前,必须先读取 `run runtime`,将返回的 `generation` 与 session `row_version` 写入 `expected_generation`、`expected_session_row_version` 后传给 `run pause` 或 `run resume`。供应商上游余额/用量使用 `flowweave model usage <provider-id>`,它可能依赖该供应商的有效 API 凭据。
|
|
23
27
|
|
|
24
|
-
周期任务使用 `schedule list/templates/occurrences/create/pause/resume/trigger/delete`。先用 `schedule templates` 读取可作为冻结母版的已就绪连续运行记录;创建请求必须使用在线 `FlowRunScheduleWrite` schema:只提交任务名称、母版 `source_flow_run_id` 和五段 `cron_expression`,节点、环境、输入和启动提示词均来自该记录的冻结母版。`schedule occurrences <schedule-id> --page 1 --page-size 10` 按需读取该调度的执行历史及其 FlowRun/NodeRun,而不预加载所有记录。暂停或恢复前从 `schedule list` 读取当前 `row_version`,再传入 `--expected-row-version`。手动触发会新增一次 occurrence,不会改写既有运行;删除生成的 FlowRun
|
|
28
|
+
周期任务使用 `schedule list/templates/occurrences/create/pause/resume/trigger/delete`。先用 `schedule templates` 读取可作为冻结母版的已就绪连续运行记录;创建请求必须使用在线 `FlowRunScheduleWrite` schema:只提交任务名称、母版 `source_flow_run_id` 和五段 `cron_expression`,节点、环境、输入和启动提示词均来自该记录的冻结母版。`schedule occurrences <schedule-id> --page 1 --page-size 10` 按需读取该调度的执行历史及其 FlowRun/NodeRun,而不预加载所有记录。暂停或恢复前从 `schedule list` 读取当前 `row_version`,再传入 `--expected-row-version`。手动触发会新增一次 occurrence,不会改写既有运行;删除生成的 FlowRun 不会删除调度,而有生成记录的调度删除会被平台拒绝。环境发布现在会返回 `202`:发布后读取对应 Environment,等待新版本进入 `READY`,不要重复提交同一 Setup Session。
|
|
25
29
|
|
|
26
30
|
能力命令还支持受治理的 OpenHands Plugin Marketplace:`capability marketplace` 读取服务端固定到完整 commit 的公开目录;使用返回的 `source`、`commit`、`repo_path` 与插件名称调用 `capability marketplace-resolve --data-file ./marketplace-plugin.json`,随后读取 `capability plugin-resolution <resolution-id>`,并以当前 `state_version` 调用 `capability plugin-publish <resolution-id> --data '{"expected_state_version": 1}'`。自定义受信任 Marketplace 可先用 `capability marketplace-preview --data-file ./marketplace.json` 审阅目录。Agent Definition 只能以 UTF-8 `.md`/`.markdown` 的 OpenHands YAML frontmatter + Markdown 正文通过 `capability validate|import --type AGENT_DEFINITION --file <file>` 导入。Hook 使用受控表单参数:`capability validate --type HOOK --file ./hook.md --hook-name <name> --hook-event <event> --hook-mode <PROMPT|SCRIPT>`;可选 `--hook-description` 与工具事件的 `--hook-matcher` 会被编译为 OpenHands 原生 `hook_config`,不能提交任意 Hook JSON。
|
|
27
31
|
|
package/bin/flowweave.mjs
CHANGED
|
@@ -37,10 +37,10 @@ function usage() {
|
|
|
37
37
|
environment <list|get|create|update|delete|setup|publish|stop|version-delete> ...
|
|
38
38
|
credential <list|create|update|delete|delete-many> ...
|
|
39
39
|
flow <list|get|create|update|validate|delete> ...
|
|
40
|
-
run <list|get|start|delete|runtime|replace|pause|resume|cancel|complete|events|node|node-copy|node-delete|workspace-delete|work-directory-delete> ...
|
|
40
|
+
run <list|get|start|delete|runtime|replace|pause|resume|cancel|complete|events|node|node-copy|node-delete|workspace-details|workspace-directory|workspace-git-repositories|workspace-git-log|workspace-git-commit|workspace-git-diff|workspace-entry-create|workspace-delete|work-directory-delete|hydration|head|automatic-config-export|automatic-config-import|reconcile-runtime-completion> ...
|
|
41
41
|
schedule <list|templates|occurrences|create|pause|resume|trigger|delete> ...
|
|
42
42
|
model <list|create|update|delete|discover|usage|test|oauth-start|oauth-poll|oauth-status|oauth-revoke> ...
|
|
43
|
-
agent <default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|file-delete> ...
|
|
43
|
+
agent <default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|workspace-details|workspace-directory|workspace-git-repositories|workspace-git-log|workspace-git-commit|workspace-git-diff|workspace-entry-create|file-delete|hydration|head> ...
|
|
44
44
|
|
|
45
45
|
所有写入操作都可加 --dry-run 仅查看最终请求。运行 flowweave <命令> --help 查看该命令说明。`;
|
|
46
46
|
}
|
|
@@ -453,6 +453,56 @@ async function flow(args) {
|
|
|
453
453
|
throw new CliError('flow 支持 list|get|create|update|validate|delete');
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
function workspaceScope(args) {
|
|
457
|
+
const bindingId = option(args, '--binding');
|
|
458
|
+
const workDirectoryId = option(args, '--work-directory');
|
|
459
|
+
return [
|
|
460
|
+
...(bindingId ? [['binding_id', bindingId]] : []),
|
|
461
|
+
...(workDirectoryId ? [['work_directory_id', workDirectoryId]] : []),
|
|
462
|
+
];
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function workspaceDirectoryQuery(args) {
|
|
466
|
+
const parentPath = option(args, '--parent-path');
|
|
467
|
+
const cursor = option(args, '--cursor');
|
|
468
|
+
const limit = option(args, '--limit');
|
|
469
|
+
const query = workspaceScope(args);
|
|
470
|
+
if (parentPath) query.push(['parent_path', parentPath]);
|
|
471
|
+
if (cursor) query.push(['cursor', cursor]);
|
|
472
|
+
if (limit !== undefined) {
|
|
473
|
+
const value = Number(limit);
|
|
474
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > 250) {
|
|
475
|
+
throw new CliError('workspace-directory 的 --limit 必须为 1 到 250 的整数');
|
|
476
|
+
}
|
|
477
|
+
query.push(['limit', String(value)]);
|
|
478
|
+
}
|
|
479
|
+
return query;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function workspaceDetailsQuery(args) {
|
|
483
|
+
return [
|
|
484
|
+
...workspaceScope(args),
|
|
485
|
+
...(flag(args, '--full-index') ? [['full_index', 'true']] : []),
|
|
486
|
+
];
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function workspaceGitQuery(args, { commit = false, path = false } = {}) {
|
|
490
|
+
const repositoryPath = option(args, '--repository-path');
|
|
491
|
+
if (!repositoryPath) throw new CliError('工作区 Git 操作需要 --repository-path');
|
|
492
|
+
const query = [['repository_path', repositoryPath], ...workspaceScope(args)];
|
|
493
|
+
if (commit) {
|
|
494
|
+
const value = option(args, '--commit');
|
|
495
|
+
if (!value) throw new CliError('工作区 Git 提交操作需要 --commit');
|
|
496
|
+
query.push(['commit', value]);
|
|
497
|
+
}
|
|
498
|
+
if (path) {
|
|
499
|
+
const value = option(args, '--path');
|
|
500
|
+
if (!value) throw new CliError('工作区 Git Diff 操作需要 --path');
|
|
501
|
+
query.push(['path', value]);
|
|
502
|
+
}
|
|
503
|
+
return query;
|
|
504
|
+
}
|
|
505
|
+
|
|
456
506
|
async function run(args) {
|
|
457
507
|
const [action, id] = positional(args);
|
|
458
508
|
if (action === 'list') return request('GET', '/flow-runs', args);
|
|
@@ -465,7 +515,17 @@ async function run(args) {
|
|
|
465
515
|
});
|
|
466
516
|
return request('POST', `/flows/${flowId}/runs`, args, { body });
|
|
467
517
|
}
|
|
518
|
+
if (action === 'reconcile-runtime-completion') {
|
|
519
|
+
if (!id) throw new CliError('run reconcile-runtime-completion 需要 Attempt ID');
|
|
520
|
+
return request('POST', `/node-attempts/${id}/reconcile-runtime-completion`, args, { body: await objectPayload(args) });
|
|
521
|
+
}
|
|
468
522
|
if (!id) throw new CliError(`run ${action || ''} 需要 FlowRun ID`);
|
|
523
|
+
if (action === 'automatic-config-export') {
|
|
524
|
+
return request('POST', `/flow-runs/${id}/automatic-runs/config-exports`, args, { body: await objectPayload(args) });
|
|
525
|
+
}
|
|
526
|
+
if (action === 'automatic-config-import') {
|
|
527
|
+
return request('POST', `/flow-runs/${id}/automatic-runs/config-imports`, args, { body: await objectPayload(args) });
|
|
528
|
+
}
|
|
469
529
|
if (action === 'node' || action === 'node-copy' || action === 'node-delete') {
|
|
470
530
|
const nodeRunId = option(args, '--node');
|
|
471
531
|
if (!nodeRunId) throw new CliError(`run ${action} 需要 --node <node-run-id>`);
|
|
@@ -474,20 +534,48 @@ async function run(args) {
|
|
|
474
534
|
if (action === 'node-copy') return request('POST', `${path}/copy`, args, { body: await objectPayload(args) });
|
|
475
535
|
return request('DELETE', path, args);
|
|
476
536
|
}
|
|
537
|
+
const attemptId = option(args, '--attempt');
|
|
538
|
+
const workspaceBase = attemptId
|
|
539
|
+
? `/flow-runs/${id}/node-attempts/${attemptId}/agent-sessions`
|
|
540
|
+
: null;
|
|
541
|
+
if (['workspace-details', 'workspace-directory', 'workspace-git-repositories', 'workspace-git-log', 'workspace-git-commit', 'workspace-git-diff', 'workspace-entry-create'].includes(action)) {
|
|
542
|
+
if (!workspaceBase) throw new CliError(`run ${action} 需要 --attempt <attempt-id>`);
|
|
543
|
+
if (action === 'workspace-details') {
|
|
544
|
+
return request('GET', `${workspaceBase}/workspace`, args, { query: workspaceDetailsQuery(args) });
|
|
545
|
+
}
|
|
546
|
+
if (action === 'workspace-directory') {
|
|
547
|
+
return request('GET', `${workspaceBase}/workspace/directory`, args, { query: workspaceDirectoryQuery(args) });
|
|
548
|
+
}
|
|
549
|
+
if (action === 'workspace-git-repositories') {
|
|
550
|
+
return request('GET', `${workspaceBase}/workspace/git/repositories`, args, { query: workspaceScope(args) });
|
|
551
|
+
}
|
|
552
|
+
if (action === 'workspace-git-log') {
|
|
553
|
+
return request('GET', `${workspaceBase}/workspace/git/log`, args, { query: workspaceGitQuery(args) });
|
|
554
|
+
}
|
|
555
|
+
if (action === 'workspace-git-commit') {
|
|
556
|
+
return request('GET', `${workspaceBase}/workspace/git/commit`, args, { query: workspaceGitQuery(args, { commit: true }) });
|
|
557
|
+
}
|
|
558
|
+
if (action === 'workspace-git-diff') {
|
|
559
|
+
return request('GET', `${workspaceBase}/workspace/git/diff`, args, { query: workspaceGitQuery(args, { commit: true, path: true }) });
|
|
560
|
+
}
|
|
561
|
+
if (action === 'workspace-entry-create') {
|
|
562
|
+
return request('POST', `${workspaceBase}/workspace/entries`, args, { body: await objectPayload(args), query: workspaceScope(args) });
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (action === 'hydration' || action === 'head') {
|
|
566
|
+
if (!workspaceBase) throw new CliError(`run ${action} 需要 --attempt <attempt-id>`);
|
|
567
|
+
const bindingId = option(args, '--binding');
|
|
568
|
+
if (!bindingId) throw new CliError(`run ${action} 需要 --binding <binding-id>`);
|
|
569
|
+
return request('GET', `${workspaceBase}/${bindingId}/${action}`, args);
|
|
570
|
+
}
|
|
477
571
|
if (action === 'workspace-delete') {
|
|
478
|
-
const attemptId = option(args, '--attempt');
|
|
479
572
|
const paths = optionValues(args, '--path');
|
|
480
573
|
if (!attemptId || !paths.length) {
|
|
481
574
|
throw new CliError('run workspace-delete 需要 FlowRun ID、--attempt 和至少一个 --path');
|
|
482
575
|
}
|
|
483
|
-
const bindingId = option(args, '--binding');
|
|
484
|
-
const workDirectoryId = option(args, '--work-directory');
|
|
485
576
|
return request('DELETE', `/flow-runs/${id}/node-attempts/${attemptId}/agent-sessions/workspace/entries`, args, {
|
|
486
577
|
body: { paths },
|
|
487
|
-
query:
|
|
488
|
-
...(bindingId ? [['binding_id', bindingId]] : []),
|
|
489
|
-
...(workDirectoryId ? [['work_directory_id', workDirectoryId]] : []),
|
|
490
|
-
],
|
|
578
|
+
query: workspaceScope(args),
|
|
491
579
|
});
|
|
492
580
|
}
|
|
493
581
|
if (action === 'work-directory-delete') {
|
|
@@ -512,7 +600,7 @@ async function run(args) {
|
|
|
512
600
|
if (action === 'cancel') return request('POST', `/flow-runs/${id}/cancel`, args, { body: {} });
|
|
513
601
|
if (action === 'complete') return request('POST', `/flow-runs/${id}/complete`, args, { body: {} });
|
|
514
602
|
if (action === 'events') return request('GET', `/flow-runs/${id}/events`, args);
|
|
515
|
-
throw new CliError('run 支持 list|get|start|delete|runtime|replace|pause|resume|cancel|complete|events|node|node-copy|node-delete|workspace-delete|work-directory-delete');
|
|
603
|
+
throw new CliError('run 支持 list|get|start|delete|runtime|replace|pause|resume|cancel|complete|events|node|node-copy|node-delete|workspace-details|workspace-directory|workspace-git-repositories|workspace-git-log|workspace-git-commit|workspace-git-diff|workspace-entry-create|workspace-delete|work-directory-delete|hydration|head|automatic-config-export|automatic-config-import|reconcile-runtime-completion');
|
|
516
604
|
}
|
|
517
605
|
|
|
518
606
|
async function schedule(args) {
|
|
@@ -597,26 +685,43 @@ async function agent(args) {
|
|
|
597
685
|
if (!binding) throw new CliError('agent work-directory-delete 需要工作目录 ID');
|
|
598
686
|
return request('DELETE', `${base}/work-directories/${binding}`, args);
|
|
599
687
|
}
|
|
688
|
+
if (action === 'workspace-details') {
|
|
689
|
+
return request('GET', `${base}/workspace`, args, { query: workspaceDetailsQuery(args) });
|
|
690
|
+
}
|
|
691
|
+
if (action === 'workspace-directory') {
|
|
692
|
+
return request('GET', `${base}/workspace/directory`, args, { query: workspaceDirectoryQuery(args) });
|
|
693
|
+
}
|
|
694
|
+
if (action === 'workspace-git-repositories') {
|
|
695
|
+
return request('GET', `${base}/workspace/git/repositories`, args, { query: workspaceScope(args) });
|
|
696
|
+
}
|
|
697
|
+
if (action === 'workspace-git-log') {
|
|
698
|
+
return request('GET', `${base}/workspace/git/log`, args, { query: workspaceGitQuery(args) });
|
|
699
|
+
}
|
|
700
|
+
if (action === 'workspace-git-commit') {
|
|
701
|
+
return request('GET', `${base}/workspace/git/commit`, args, { query: workspaceGitQuery(args, { commit: true }) });
|
|
702
|
+
}
|
|
703
|
+
if (action === 'workspace-git-diff') {
|
|
704
|
+
return request('GET', `${base}/workspace/git/diff`, args, { query: workspaceGitQuery(args, { commit: true, path: true }) });
|
|
705
|
+
}
|
|
706
|
+
if (action === 'workspace-entry-create') {
|
|
707
|
+
return request('POST', `${base}/workspace/entries`, args, { body: await objectPayload(args), query: workspaceScope(args) });
|
|
708
|
+
}
|
|
600
709
|
if (action === 'file-delete') {
|
|
601
710
|
const paths = optionValues(args, '--path');
|
|
602
711
|
if (!paths.length) throw new CliError('agent file-delete 至少需要一个 --path <runtime-path>');
|
|
603
|
-
const bindingId = option(args, '--binding');
|
|
604
|
-
const workDirectoryId = option(args, '--work-directory');
|
|
605
712
|
return request('DELETE', `${base}/workspace/entries`, args, {
|
|
606
713
|
body: { paths },
|
|
607
|
-
query:
|
|
608
|
-
...(bindingId ? [['binding_id', bindingId]] : []),
|
|
609
|
-
...(workDirectoryId ? [['work_directory_id', workDirectoryId]] : []),
|
|
610
|
-
],
|
|
714
|
+
query: workspaceScope(args),
|
|
611
715
|
});
|
|
612
716
|
}
|
|
613
717
|
if (action === 'create') return request('POST', `${base}/conversations`, args);
|
|
614
718
|
if (!binding) throw new CliError(`agent ${action || ''} 需要会话 binding ID`);
|
|
615
719
|
if (action === 'conversation') return request('GET', `${base}/conversations/${binding}`, args);
|
|
720
|
+
if (action === 'hydration' || action === 'head') return request('GET', `${base}/conversations/${binding}/${action}`, args);
|
|
616
721
|
if (action === 'send') return request('POST', `${base}/conversations/${binding}/messages`, args);
|
|
617
722
|
if (action === 'interrupt') return request('POST', `${base}/conversations/${binding}/interrupt`, args, { body: {} });
|
|
618
723
|
if (action === 'resume') return request('POST', `${base}/conversations/${binding}/resume`, args, { body: {} });
|
|
619
|
-
throw new CliError('agent 支持 default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|file-delete');
|
|
724
|
+
throw new CliError('agent 支持 default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|workspace-details|workspace-directory|workspace-git-repositories|workspace-git-log|workspace-git-commit|workspace-git-diff|workspace-entry-create|file-delete|hydration|head');
|
|
620
725
|
}
|
|
621
726
|
|
|
622
727
|
async function upload(args) {
|