@flowweave-ai/cli 0.1.1 → 0.1.3

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
@@ -10,18 +10,20 @@ flowweave health --ready
10
10
 
11
11
  配置只保存基础 URL 到 `~/.config/flowweave/config.json`(可由 `FLOWWEAVE_CONFIG_PATH` 覆盖)。当前平台不需要登录。
12
12
 
13
- 页面域命令包括 `node`、`node-directory`、`capability`、`environment`、`flow`、`run`、`model` 和 `agent`。它们分别覆盖节点资产、能力仓库、终端环境、流程编排、FlowRun、大模型配置与 Agent 工作台的常用原子操作。每个命令的 JSON 请求体与在线 OpenAPI 一致;运行 `flowweave <域> --help` 查看映射。
13
+ 页面域命令包括 `node`、`node-directory`、`capability`、`environment`、`credential`、`flow`、`run`、`model` 和 `agent`。它们分别覆盖节点资产、能力仓库、终端环境、认证管理、流程编排、FlowRun、大模型配置与 Agent 工作台的常用原子操作。每个命令的 JSON 请求体与在线 OpenAPI 一致;运行 `flowweave <域> --help` 查看映射。
14
14
 
15
15
  常用命令示例:
16
16
 
17
- `flowweave node create --data-file ./node.json`、`flowweave capability import --type SKILL --file ./skill.zip`、`flowweave environment create --data '{"name":"Python"}'`、`flowweave flow create --data-file ./flow.json`、`flowweave run start --flow <flow-id> --environment-version <version-id>`。
17
+ `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 /runtime/workspace/project/report.md --path /runtime/workspace/project/output`、`flowweave run workspace-delete <run-id> --attempt <attempt-id> --path /runtime/workspace/project/result.txt`。
18
+
19
+ 节点目录批量删除、Agent Workspace 文件树删除和 FlowRun 节点工作区删除都使用 JSON 数组请求体。重复传入 `--id` 或 `--path` 即可批量选择;先读取真实资源与路径,并用 `--dry-run` 核对 DELETE URL、范围 query 和请求体。FlowRun 工作目录删除使用 `flowweave run work-directory-delete <run-id> --attempt <attempt-id> --work-directory <directory-id>`。
18
20
 
19
21
  `api`、`upload`、`ws` 是完整契约入口:任意当前或未来的 REST、multipart、WebSocket 原子接口均可直接调用,不需要等待 CLI 发布。`ws` 使用 Node 原生 WebSocket;当前公开 FlowWeave WebSocket 接口无需自定义请求头。写操作支持 `--dry-run`,并可使用 `-H 'Idempotency-Key: …'` 传入一次性幂等键。对于没有快捷命令的新接口,先运行 `flowweave openapi --paths`,再通过通用命令调用。
20
22
 
21
23
  安装页面域 skill:
22
24
 
23
25
  ```bash
24
- npx skills add ZME7777777/FlowWeave -g -y --full-depth
26
+ npx skills add ZME7777777/FlowWeave -g -y
25
27
  ```
26
28
 
27
29
  仓库尚未发布该 npm 包前,进入 `packages/cli` 后运行 `npm pack` 生成 tarball,并以 `npm install -g ./flowweave-ai-cli-*.tgz` 安装。发布到 npm registry 需要拥有 `@flowweave-ai` scope 的发布权限;本仓库不会自动发布。
package/bin/flowweave.mjs CHANGED
@@ -26,13 +26,14 @@ function usage() {
26
26
 
27
27
  页面域原子操作:
28
28
  node <list|get|create|update|delete> [ID] [--data JSON|--data-file FILE]
29
- node-directory <list|create> [--data JSON|--data-file FILE]
29
+ node-directory <list|create|delete|delete-many> [ID] [--id ID ...]
30
30
  capability <list|validate|commit|import> ...
31
31
  environment <list|get|create|update|delete|setup|publish|stop|version-delete> ...
32
+ credential <list|create|update|delete|delete-many> ...
32
33
  flow <list|get|create|update|validate|delete> ...
33
- run <list|get|start|delete|runtime|replace|cancel|complete|events> ...
34
+ run <list|get|start|delete|runtime|replace|cancel|complete|events|workspace-delete|work-directory-delete> ...
34
35
  model <list|create|update|delete|discover|test|oauth-start|oauth-poll|oauth-status|oauth-revoke> ...
35
- agent <default|workspace|runtime|conversations|conversation|create|send|interrupt|resume> ...
36
+ agent <default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|file-delete> ...
36
37
 
37
38
  所有写入操作都可加 --dry-run 仅查看最终请求。运行 flowweave <命令> --help 查看该命令说明。`;
38
39
  }
@@ -130,9 +131,9 @@ function pathUrl(baseUrl, path, { raw = false, query = [] } = {}) {
130
131
  function headers(args) { return Object.fromEntries(pairs(optionValues(args, '-H').concat(optionValues(args, '--header')), ':', '--header').map(([name, value]) => [name.trim(), value.trim()])); }
131
132
  function queries(args) { return pairs(optionValues(args, '-q').concat(optionValues(args, '--query')), '=', '--query'); }
132
133
 
133
- async function request(method, path, args, { raw = false, body, form } = {}) {
134
+ async function request(method, path, args, { raw = false, body, form, query = [] } = {}) {
134
135
  const { baseUrl } = await loadConfig();
135
- const url = pathUrl(baseUrl, path, { raw, query: queries(args) });
136
+ const url = pathUrl(baseUrl, path, { raw, query: [...queries(args), ...query] });
136
137
  const requestBody = body === undefined ? await payload(args) : body;
137
138
  if (flag(args, '--dry-run')) return { method, url: url.toString(), payload: requestBody ?? form ?? null };
138
139
  const requestHeaders = { Accept: 'application/json', ...headers(args) };
@@ -189,6 +190,22 @@ async function crud(command, args) {
189
190
  return request(methods[action], id ? `${route}/${id}` : route, args);
190
191
  }
191
192
 
193
+ async function nodeDirectory(args) {
194
+ const [action, id] = positional(args);
195
+ if (action === 'list') return request('GET', '/node-directories', args);
196
+ if (action === 'create') return request('POST', '/node-directories', args);
197
+ if (action === 'delete') {
198
+ if (!id) throw new CliError('node-directory delete 必须提供目录 ID');
199
+ return request('DELETE', `/node-directories/${id}`, args);
200
+ }
201
+ if (action === 'delete-many') {
202
+ const ids = optionValues(args, '--id');
203
+ if (!ids.length) throw new CliError('node-directory delete-many 至少需要一个 --id');
204
+ return request('DELETE', '/node-directories', args, { body: { ids } });
205
+ }
206
+ throw new CliError('node-directory 支持 list|create|delete|delete-many');
207
+ }
208
+
192
209
  async function capability(args) {
193
210
  const [action, id] = positional(args);
194
211
  if (action === 'list') return request('GET', '/capabilities', args);
@@ -215,7 +232,13 @@ async function environment(args) {
215
232
  const [action, id] = positional(args);
216
233
  if (['list', 'get', 'create', 'update', 'delete'].includes(action)) return crud('environment', args);
217
234
  if (action === 'setup') { if (!id) throw new CliError('environment setup 需要环境 ID'); return request('POST', `/terminal-environments/${id}/setup-sessions`, args, { body: await objectPayload(args) }); }
218
- if (action === 'publish') { if (!id) throw new CliError('environment publish 需要 Setup Session ID'); return request('POST', `/environment-setup-sessions/${id}/publish`, args, { body: {} }); }
235
+ if (action === 'publish') {
236
+ if (!id) throw new CliError('environment publish 需要 Setup Session ID');
237
+ const description = option(args, '--description');
238
+ return request('POST', `/environment-setup-sessions/${id}/publish`, args, {
239
+ body: await objectPayload(args, description === undefined ? {} : { description }),
240
+ });
241
+ }
219
242
  if (action === 'stop') { if (!id) throw new CliError('environment stop 需要 Setup Session ID'); return request('DELETE', `/environment-setup-sessions/${id}`, args); }
220
243
  if (action === 'version-delete') {
221
244
  const versionId = option(args, '--version');
@@ -225,6 +248,21 @@ async function environment(args) {
225
248
  throw new CliError('environment 支持 list|get|create|update|delete|setup|publish|stop|version-delete');
226
249
  }
227
250
 
251
+ async function credential(args) {
252
+ const [action, id] = positional(args);
253
+ if (action === 'list') return request('GET', '/website-credentials', args);
254
+ if (action === 'create') return request('POST', '/website-credentials', args);
255
+ if (action === 'delete-many') {
256
+ const ids = optionValues(args, '--id');
257
+ if (!ids.length) throw new CliError('credential delete-many 至少需要一个 --id');
258
+ return request('DELETE', '/website-credentials', args, { body: { ids } });
259
+ }
260
+ if (!id) throw new CliError(`credential ${action || ''} 需要认证 ID`);
261
+ if (action === 'update') return request('PUT', `/website-credentials/${id}`, args);
262
+ if (action === 'delete') return request('DELETE', `/website-credentials/${id}`, args);
263
+ throw new CliError('credential 支持 list|create|update|delete|delete-many');
264
+ }
265
+
228
266
  async function flow(args) {
229
267
  const [action, id] = positional(args);
230
268
  if (['list', 'get', 'create', 'update', 'delete'].includes(action)) return crud('flow', args);
@@ -245,6 +283,30 @@ async function run(args) {
245
283
  return request('POST', `/flows/${flowId}/runs`, args, { body });
246
284
  }
247
285
  if (!id) throw new CliError(`run ${action || ''} 需要 FlowRun ID`);
286
+ if (action === 'workspace-delete') {
287
+ const attemptId = option(args, '--attempt');
288
+ const paths = optionValues(args, '--path');
289
+ if (!attemptId || !paths.length) {
290
+ throw new CliError('run workspace-delete 需要 FlowRun ID、--attempt 和至少一个 --path');
291
+ }
292
+ const bindingId = option(args, '--binding');
293
+ const workDirectoryId = option(args, '--work-directory');
294
+ return request('DELETE', `/flow-runs/${id}/node-attempts/${attemptId}/agent-sessions/workspace/entries`, args, {
295
+ body: { paths },
296
+ query: [
297
+ ...(bindingId ? [['binding_id', bindingId]] : []),
298
+ ...(workDirectoryId ? [['work_directory_id', workDirectoryId]] : []),
299
+ ],
300
+ });
301
+ }
302
+ if (action === 'work-directory-delete') {
303
+ const attemptId = option(args, '--attempt');
304
+ const workDirectoryId = option(args, '--work-directory');
305
+ if (!attemptId || !workDirectoryId) {
306
+ throw new CliError('run work-directory-delete 需要 FlowRun ID、--attempt 和 --work-directory');
307
+ }
308
+ return request('DELETE', `/flow-runs/${id}/node-attempts/${attemptId}/agent-sessions/work-directories/${workDirectoryId}`, args);
309
+ }
248
310
  if (action === 'get') return request('GET', `/flow-runs/${id}`, args);
249
311
  if (action === 'delete') return request('DELETE', `/flow-runs/${id}`, args);
250
312
  if (action === 'runtime') return request('GET', `/flow-runs/${id}/runtime`, args);
@@ -252,7 +314,7 @@ async function run(args) {
252
314
  if (action === 'cancel') return request('POST', `/flow-runs/${id}/cancel`, args, { body: {} });
253
315
  if (action === 'complete') return request('POST', `/flow-runs/${id}/complete`, args, { body: {} });
254
316
  if (action === 'events') return request('GET', `/flow-runs/${id}/events`, args);
255
- throw new CliError('run 支持 list|get|start|delete|runtime|replace|cancel|complete|events');
317
+ throw new CliError('run 支持 list|get|start|delete|runtime|replace|cancel|complete|events|workspace-delete|work-directory-delete');
256
318
  }
257
319
 
258
320
  async function model(args) {
@@ -283,13 +345,34 @@ async function agent(args) {
283
345
  if (action === 'workspace') return request('GET', base, args);
284
346
  if (action === 'runtime') return request('GET', `${base}/runtime`, args);
285
347
  if (action === 'conversations') return request('GET', `${base}/conversations`, args);
348
+ if (action === 'work-directories') return request('GET', `${base}/work-directories`, args);
349
+ if (action === 'work-directory-create') {
350
+ return request('POST', `${base}/work-directories`, args);
351
+ }
352
+ if (action === 'work-directory-delete') {
353
+ if (!binding) throw new CliError('agent work-directory-delete 需要工作目录 ID');
354
+ return request('DELETE', `${base}/work-directories/${binding}`, args);
355
+ }
356
+ if (action === 'file-delete') {
357
+ const paths = optionValues(args, '--path');
358
+ if (!paths.length) throw new CliError('agent file-delete 至少需要一个 --path <runtime-path>');
359
+ const bindingId = option(args, '--binding');
360
+ const workDirectoryId = option(args, '--work-directory');
361
+ return request('DELETE', `${base}/workspace/entries`, args, {
362
+ body: { paths },
363
+ query: [
364
+ ...(bindingId ? [['binding_id', bindingId]] : []),
365
+ ...(workDirectoryId ? [['work_directory_id', workDirectoryId]] : []),
366
+ ],
367
+ });
368
+ }
286
369
  if (action === 'create') return request('POST', `${base}/conversations`, args);
287
370
  if (!binding) throw new CliError(`agent ${action || ''} 需要会话 binding ID`);
288
371
  if (action === 'conversation') return request('GET', `${base}/conversations/${binding}`, args);
289
372
  if (action === 'send') return request('POST', `${base}/conversations/${binding}/messages`, args);
290
373
  if (action === 'interrupt') return request('POST', `${base}/conversations/${binding}/interrupt`, args, { body: {} });
291
374
  if (action === 'resume') return request('POST', `${base}/conversations/${binding}/resume`, args, { body: {} });
292
- throw new CliError('agent 支持 default|workspace|runtime|conversations|conversation|create|send|interrupt|resume');
375
+ throw new CliError('agent 支持 default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|file-delete');
293
376
  }
294
377
 
295
378
  async function upload(args) {
@@ -362,9 +445,11 @@ async function main(argv) {
362
445
  else if (command === 'api') { const [method, path] = positional(args); if (!method || !path) throw new CliError('api 用法:api <method> <PATH>'); result = request(method.toUpperCase(), path, args, { raw: flag(args, '--raw') }); }
363
446
  else if (command === 'upload') result = upload(args);
364
447
  else if (command === 'ws') result = websocket(args);
365
- else if (['node', 'node-directory'].includes(command)) result = crud(command, args);
448
+ else if (command === 'node') result = crud(command, args);
449
+ else if (command === 'node-directory') result = nodeDirectory(args);
366
450
  else if (command === 'capability') result = capability(args);
367
451
  else if (command === 'environment') result = environment(args);
452
+ else if (command === 'credential') result = credential(args);
368
453
  else if (command === 'flow') result = flow(args);
369
454
  else if (command === 'run') result = run(args);
370
455
  else if (command === 'model') result = model(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowweave-ai/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "FlowWeave 平台命令行客户端",
5
5
  "type": "module",
6
6
  "bin": {