@flowweave-ai/cli 0.1.0 → 0.1.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
@@ -10,18 +10,18 @@ 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 <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`。
18
18
 
19
19
  `api`、`upload`、`ws` 是完整契约入口:任意当前或未来的 REST、multipart、WebSocket 原子接口均可直接调用,不需要等待 CLI 发布。`ws` 使用 Node 原生 WebSocket;当前公开 FlowWeave WebSocket 接口无需自定义请求头。写操作支持 `--dry-run`,并可使用 `-H 'Idempotency-Key: …'` 传入一次性幂等键。对于没有快捷命令的新接口,先运行 `flowweave openapi --paths`,再通过通用命令调用。
20
20
 
21
21
  安装页面域 skill:
22
22
 
23
23
  ```bash
24
- npx skills add ZME7777777/FlowWeave -g -y --full-depth
24
+ npx skills add ZME7777777/FlowWeave -g -y
25
25
  ```
26
26
 
27
27
  仓库尚未发布该 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> [ID] [--data JSON|--data-file FILE]
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
34
  run <list|get|start|delete|runtime|replace|cancel|complete|events> ...
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,17 @@ 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
+ throw new CliError('node-directory 支持 list|create|delete');
202
+ }
203
+
192
204
  async function capability(args) {
193
205
  const [action, id] = positional(args);
194
206
  if (action === 'list') return request('GET', '/capabilities', args);
@@ -215,7 +227,13 @@ async function environment(args) {
215
227
  const [action, id] = positional(args);
216
228
  if (['list', 'get', 'create', 'update', 'delete'].includes(action)) return crud('environment', args);
217
229
  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: {} }); }
230
+ if (action === 'publish') {
231
+ if (!id) throw new CliError('environment publish 需要 Setup Session ID');
232
+ const description = option(args, '--description');
233
+ return request('POST', `/environment-setup-sessions/${id}/publish`, args, {
234
+ body: await objectPayload(args, description === undefined ? {} : { description }),
235
+ });
236
+ }
219
237
  if (action === 'stop') { if (!id) throw new CliError('environment stop 需要 Setup Session ID'); return request('DELETE', `/environment-setup-sessions/${id}`, args); }
220
238
  if (action === 'version-delete') {
221
239
  const versionId = option(args, '--version');
@@ -225,6 +243,21 @@ async function environment(args) {
225
243
  throw new CliError('environment 支持 list|get|create|update|delete|setup|publish|stop|version-delete');
226
244
  }
227
245
 
246
+ async function credential(args) {
247
+ const [action, id] = positional(args);
248
+ if (action === 'list') return request('GET', '/website-credentials', args);
249
+ if (action === 'create') return request('POST', '/website-credentials', args);
250
+ if (action === 'delete-many') {
251
+ const ids = optionValues(args, '--id');
252
+ if (!ids.length) throw new CliError('credential delete-many 至少需要一个 --id');
253
+ return request('DELETE', '/website-credentials', args, { body: { ids } });
254
+ }
255
+ if (!id) throw new CliError(`credential ${action || ''} 需要认证 ID`);
256
+ if (action === 'update') return request('PUT', `/website-credentials/${id}`, args);
257
+ if (action === 'delete') return request('DELETE', `/website-credentials/${id}`, args);
258
+ throw new CliError('credential 支持 list|create|update|delete|delete-many');
259
+ }
260
+
228
261
  async function flow(args) {
229
262
  const [action, id] = positional(args);
230
263
  if (['list', 'get', 'create', 'update', 'delete'].includes(action)) return crud('flow', args);
@@ -283,13 +316,34 @@ async function agent(args) {
283
316
  if (action === 'workspace') return request('GET', base, args);
284
317
  if (action === 'runtime') return request('GET', `${base}/runtime`, args);
285
318
  if (action === 'conversations') return request('GET', `${base}/conversations`, args);
319
+ if (action === 'work-directories') return request('GET', `${base}/work-directories`, args);
320
+ if (action === 'work-directory-create') {
321
+ return request('POST', `${base}/work-directories`, args);
322
+ }
323
+ if (action === 'work-directory-delete') {
324
+ if (!binding) throw new CliError('agent work-directory-delete 需要工作目录 ID');
325
+ return request('DELETE', `${base}/work-directories/${binding}`, args);
326
+ }
327
+ if (action === 'file-delete') {
328
+ const path = option(args, '--path');
329
+ if (!path) throw new CliError('agent file-delete 需要 --path <runtime-path>');
330
+ const bindingId = option(args, '--binding');
331
+ const workDirectoryId = option(args, '--work-directory');
332
+ return request('DELETE', `${base}/workspace/file`, args, {
333
+ query: [
334
+ ['path', path],
335
+ ...(bindingId ? [['binding_id', bindingId]] : []),
336
+ ...(workDirectoryId ? [['work_directory_id', workDirectoryId]] : []),
337
+ ],
338
+ });
339
+ }
286
340
  if (action === 'create') return request('POST', `${base}/conversations`, args);
287
341
  if (!binding) throw new CliError(`agent ${action || ''} 需要会话 binding ID`);
288
342
  if (action === 'conversation') return request('GET', `${base}/conversations/${binding}`, args);
289
343
  if (action === 'send') return request('POST', `${base}/conversations/${binding}/messages`, args);
290
344
  if (action === 'interrupt') return request('POST', `${base}/conversations/${binding}/interrupt`, args, { body: {} });
291
345
  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');
346
+ throw new CliError('agent 支持 default|workspace|runtime|conversations|conversation|create|send|interrupt|resume|work-directories|work-directory-create|work-directory-delete|file-delete');
293
347
  }
294
348
 
295
349
  async function upload(args) {
@@ -362,9 +416,11 @@ async function main(argv) {
362
416
  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
417
  else if (command === 'upload') result = upload(args);
364
418
  else if (command === 'ws') result = websocket(args);
365
- else if (['node', 'node-directory'].includes(command)) result = crud(command, args);
419
+ else if (command === 'node') result = crud(command, args);
420
+ else if (command === 'node-directory') result = nodeDirectory(args);
366
421
  else if (command === 'capability') result = capability(args);
367
422
  else if (command === 'environment') result = environment(args);
423
+ else if (command === 'credential') result = credential(args);
368
424
  else if (command === 'flow') result = flow(args);
369
425
  else if (command === 'run') result = run(args);
370
426
  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.0",
3
+ "version": "0.1.2",
4
4
  "description": "FlowWeave 平台命令行客户端",
5
5
  "type": "module",
6
6
  "bin": {