@tuongaz/seeflow 0.1.76 → 0.1.80

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.
Files changed (107) hide show
  1. package/README.md +40 -0
  2. package/dist/web/assets/{architectureDiagram-3BPJPVTR-CVOsL8en.js → architectureDiagram-3BPJPVTR-id0XTZQC.js} +1 -1
  3. package/dist/web/assets/{blockDiagram-GPEHLZMM-C4ln3pHP.js → blockDiagram-GPEHLZMM-Cjvfg0ZP.js} +1 -1
  4. package/dist/web/assets/{c4Diagram-AAUBKEIU-COBq_O0m.js → c4Diagram-AAUBKEIU-Dyq-0e8Q.js} +1 -1
  5. package/dist/web/assets/channel-Ajb6KiL3.js +1 -0
  6. package/dist/web/assets/{chart-DD5RfLtm.js → chart-DuTGW-Dj.js} +1 -1
  7. package/dist/web/assets/{chunk-2J33WTMH-Bdm-YMMv.js → chunk-2J33WTMH-DsD65OzD.js} +1 -1
  8. package/dist/web/assets/{chunk-4BX2VUAB-BV9NRSCp.js → chunk-4BX2VUAB-BpytKE8P.js} +1 -1
  9. package/dist/web/assets/{chunk-55IACEB6-D-Xe7eUY.js → chunk-55IACEB6-DIILAUq9.js} +1 -1
  10. package/dist/web/assets/{chunk-727SXJPM-DB6EZ4tw.js → chunk-727SXJPM-C4ih-gTo.js} +1 -1
  11. package/dist/web/assets/{chunk-AQP2D5EJ-DDlp8cdl.js → chunk-AQP2D5EJ-BsYoWdVM.js} +1 -1
  12. package/dist/web/assets/{chunk-FMBD7UC4-qmkSV1r1.js → chunk-FMBD7UC4-Db6L0z4p.js} +1 -1
  13. package/dist/web/assets/{chunk-ND2GUHAM-BFkM9OZ5.js → chunk-ND2GUHAM-BNLqZYMx.js} +1 -1
  14. package/dist/web/assets/{chunk-QZHKN3VN-Cye5hUth.js → chunk-QZHKN3VN-DL5PK45j.js} +1 -1
  15. package/dist/web/assets/classDiagram-4FO5ZUOK-Cgw6ezRo.js +1 -0
  16. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-Cgw6ezRo.js +1 -0
  17. package/dist/web/assets/{code-block-B2Jj4pwe.js → code-block-C1SJv-Al.js} +1 -1
  18. package/dist/web/assets/{cose-bilkent-S5V4N54A-B8Q15-m-.js → cose-bilkent-S5V4N54A-ChX5nR0f.js} +1 -1
  19. package/dist/web/assets/{dagre-BM42HDAG-BEYccL0v.js → dagre-BM42HDAG-BXeL3fEN.js} +1 -1
  20. package/dist/web/assets/{diagram-2AECGRRQ-BHPvhIzV.js → diagram-2AECGRRQ-B6WtmEP-.js} +1 -1
  21. package/dist/web/assets/{diagram-5GNKFQAL-Csqbxt3l.js → diagram-5GNKFQAL-SXs7ALwM.js} +1 -1
  22. package/dist/web/assets/{diagram-KO2AKTUF-BR6CIJyT.js → diagram-KO2AKTUF-D5zylPYo.js} +1 -1
  23. package/dist/web/assets/{diagram-LMA3HP47-CNtClLgB.js → diagram-LMA3HP47-CByIUlQF.js} +1 -1
  24. package/dist/web/assets/{diagram-OG6HWLK6-6C-uLOFp.js → diagram-OG6HWLK6-BH1MfUqV.js} +1 -1
  25. package/dist/web/assets/{erDiagram-TEJ5UH35-WbZOwkSY.js → erDiagram-TEJ5UH35-BOOnRFBh.js} +1 -1
  26. package/dist/web/assets/{flowDiagram-I6XJVG4X-DkXzWb1H.js → flowDiagram-I6XJVG4X-BynWDHJP.js} +1 -1
  27. package/dist/web/assets/{ganttDiagram-6RSMTGT7-CUvI4hDd.js → ganttDiagram-6RSMTGT7-Cgq_djyN.js} +1 -1
  28. package/dist/web/assets/{gitGraphDiagram-PVQCEYII-DQ5Z5DTr.js → gitGraphDiagram-PVQCEYII-ciGSgmfT.js} +1 -1
  29. package/dist/web/assets/index-DiakpHyc.js +8619 -0
  30. package/dist/web/assets/{index-DljfurDC.css → index-fl8DS9WO.css} +1 -1
  31. package/dist/web/assets/{index.es-DU_7oRoK.js → index.es-C7TtaIfa.js} +1 -1
  32. package/dist/web/assets/{infoDiagram-5YYISTIA-CVl3bX4h.js → infoDiagram-5YYISTIA-DqMb3_c-.js} +1 -1
  33. package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-CQs9MZtd.js → ishikawaDiagram-YF4QCWOH-CAO6KqQU.js} +1 -1
  34. package/dist/web/assets/{journeyDiagram-JHISSGLW-B9emRTSL.js → journeyDiagram-JHISSGLW-Di8MsLTo.js} +1 -1
  35. package/dist/web/assets/{jspdf.es.min-DO9eBtyx.js → jspdf.es.min-Cq4dY-lT.js} +3 -3
  36. package/dist/web/assets/{kanban-definition-UN3LZRKU-CU4PXBkO.js → kanban-definition-UN3LZRKU-ClOmVNcX.js} +1 -1
  37. package/dist/web/assets/{linear-Djd98ym6.js → linear-B3OKBKaT.js} +1 -1
  38. package/dist/web/assets/{markdown-Dtbihta2.js → markdown-Dg8NEx1K.js} +1 -1
  39. package/dist/web/assets/{mermaid.core--5B4uu7H.js → mermaid.core-Bw-m7bH-.js} +4 -4
  40. package/dist/web/assets/{mindmap-definition-RKZ34NQL-DBa-qOvW.js → mindmap-definition-RKZ34NQL-CUBA1zfc.js} +1 -1
  41. package/dist/web/assets/{pieDiagram-4H26LBE5-BgO03eBD.js → pieDiagram-4H26LBE5-Dux5HvSU.js} +1 -1
  42. package/dist/web/assets/{quadrantDiagram-W4KKPZXB-D5qnQqxO.js → quadrantDiagram-W4KKPZXB-DU3gQGo3.js} +1 -1
  43. package/dist/web/assets/{requirementDiagram-4Y6WPE33-CvFTU_QP.js → requirementDiagram-4Y6WPE33-CD3A_U9j.js} +1 -1
  44. package/dist/web/assets/{sankeyDiagram-5OEKKPKP-BSwt6J0r.js → sankeyDiagram-5OEKKPKP-Cd4mc26P.js} +1 -1
  45. package/dist/web/assets/{sequenceDiagram-3UESZ5HK-B6xwt7gx.js → sequenceDiagram-3UESZ5HK-Da0iOMgq.js} +1 -1
  46. package/dist/web/assets/{stateDiagram-AJRCARHV-B4aBLe9A.js → stateDiagram-AJRCARHV-P94LaOD2.js} +1 -1
  47. package/dist/web/assets/stateDiagram-v2-BHNVJYJU--JLHF28o.js +1 -0
  48. package/dist/web/assets/{time-VmDaOXzG.js → time-0JEErjjJ.js} +1 -1
  49. package/dist/web/assets/{timeline-definition-PNZ67QCA-Bp46ZbZu.js → timeline-definition-PNZ67QCA-BqAYomix.js} +1 -1
  50. package/dist/web/assets/{vennDiagram-CIIHVFJN-ObB0ozDF.js → vennDiagram-CIIHVFJN-BWuPhfIM.js} +1 -1
  51. package/dist/web/assets/{wardley-L42UT6IY-DZQGppGX.js → wardley-L42UT6IY-iiGkgUQj.js} +1 -1
  52. package/dist/web/assets/{wardleyDiagram-YWT4CUSO-B3dCDfV5.js → wardleyDiagram-YWT4CUSO-CtqzFQXL.js} +1 -1
  53. package/dist/web/assets/{xychartDiagram-2RQKCTM6-CpxmkRi4.js → xychartDiagram-2RQKCTM6-BGrOXndI.js} +1 -1
  54. package/dist/web/index.html +2 -2
  55. package/examples/component-showcase/seeflow.json +6 -0
  56. package/examples/ecommerce-platform/seeflow.json +6 -0
  57. package/examples/order-pipeline/seeflow.json +6 -0
  58. package/package.json +1 -1
  59. package/src/api.ts +739 -94
  60. package/src/cli-e2e.ts +24 -13
  61. package/src/cli-helpers.ts +26 -0
  62. package/src/cli-manifest.ts +330 -87
  63. package/src/cli-ops.ts +56 -2
  64. package/src/cli.ts +228 -81
  65. package/src/cors.ts +93 -0
  66. package/src/jq-filter.ts +253 -0
  67. package/src/mcp-shim.ts +114 -7
  68. package/src/mcp-ui.ts +126 -0
  69. package/src/mcp.ts +258 -97
  70. package/src/node-files.ts +18 -7
  71. package/src/operations.ts +68 -32
  72. package/src/project-scanner.ts +105 -0
  73. package/src/registry.ts +79 -18
  74. package/src/route-resolve.ts +41 -0
  75. package/src/schema.ts +54 -0
  76. package/src/server.ts +24 -3
  77. package/src/slugify.ts +16 -0
  78. package/dist/web/assets/channel-BpDUSI6-.js +0 -1
  79. package/dist/web/assets/classDiagram-4FO5ZUOK-po1qHJgX.js +0 -1
  80. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-po1qHJgX.js +0 -1
  81. package/dist/web/assets/index-DJa2Qm_q.js +0 -8614
  82. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-D1iGL3Mj.js +0 -1
  83. /package/examples/component-showcase/{flow.json → flows/main/flow.json} +0 -0
  84. /package/examples/component-showcase/{nodes → flows/main/nodes}/chart/spec.json +0 -0
  85. /package/examples/component-showcase/{nodes → flows/main/nodes}/counter/spec.json +0 -0
  86. /package/examples/component-showcase/{nodes → flows/main/nodes}/fetcher/actions/refresh.ts +0 -0
  87. /package/examples/component-showcase/{nodes → flows/main/nodes}/fetcher/spec.json +0 -0
  88. /package/examples/component-showcase/{nodes → flows/main/nodes}/form/spec.json +0 -0
  89. /package/examples/component-showcase/{style.json → flows/main/style.json} +0 -0
  90. /package/examples/ecommerce-platform/{flow.json → flows/main/flow.json} +0 -0
  91. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-3zFtHg6ENc/detail.md +0 -0
  92. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-5F424NWbEu/detail.md +0 -0
  93. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-CbwYqb7NfB/detail.md +0 -0
  94. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-XwygzfKPZ5/view.html +0 -0
  95. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-fkptXw7uvs/detail.md +0 -0
  96. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-kwBY8YPmYM/detail.md +0 -0
  97. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-mPqan8rFYN/detail.md +0 -0
  98. /package/examples/ecommerce-platform/{nodes → flows/main/nodes}/node-yKrg9DV5fJ/detail.md +0 -0
  99. /package/examples/ecommerce-platform/{scripts → flows/main/scripts}/play.ts +0 -0
  100. /package/examples/ecommerce-platform/{style.json → flows/main/style.json} +0 -0
  101. /package/examples/order-pipeline/{flow.json → flows/main/flow.json} +0 -0
  102. /package/examples/order-pipeline/{nodes → flows/main/nodes}/node-GXTKUcE3ye/detail.md +0 -0
  103. /package/examples/order-pipeline/{nodes → flows/main/nodes}/node-XKIyds0TDg/detail.md +0 -0
  104. /package/examples/order-pipeline/{nodes → flows/main/nodes}/node-YOYiHJpY0i/detail.md +0 -0
  105. /package/examples/order-pipeline/{nodes → flows/main/nodes}/node-zUIH7WFnhK/detail.md +0 -0
  106. /package/examples/order-pipeline/{scripts → flows/main/scripts}/play.ts +0 -0
  107. /package/examples/order-pipeline/{style.json → flows/main/style.json} +0 -0
@@ -201,59 +201,193 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
201
201
  },
202
202
  {
203
203
  name: 'flows:get',
204
- synopsis: 'seeflow flows:get <flowId>',
204
+ synopsis: 'seeflow flows:get --project <p> --flow <f>',
205
205
  description: 'Get the full merged flow definition and on-disk state for one flow.',
206
206
  category: 'flows',
207
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
208
- flags: [],
207
+ args: [],
208
+ flags: [
209
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
210
+ {
211
+ name: 'flow',
212
+ valuePlaceholder: '<f>',
213
+ description: 'Flow id within the project',
214
+ required: true,
215
+ },
216
+ ],
209
217
  outputs: { errorKinds: ['notFound', 'fileNotFound'] },
210
218
  requiresStudio: false,
211
- examples: ['seeflow flows:get abc12345'],
219
+ examples: ['seeflow flows:get --project order-pipeline --flow main'],
212
220
  },
213
221
  {
214
222
  name: 'flows:graph',
215
- synopsis: 'seeflow flows:graph <flowId>',
223
+ synopsis: 'seeflow flows:graph --project <p> --flow <f>',
216
224
  description:
217
225
  'Get nodes + connectors for one flow without inlining per-node file-backed ' +
218
226
  'content (detail.md, view.html). Cheap topology read.',
219
227
  category: 'flows',
220
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
221
- flags: [],
228
+ args: [],
229
+ flags: [
230
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
231
+ {
232
+ name: 'flow',
233
+ valuePlaceholder: '<f>',
234
+ description: 'Flow id within the project',
235
+ required: true,
236
+ },
237
+ ],
222
238
  outputs: { errorKinds: ['notFound', 'fileNotFound', 'badJson', 'badSchema'] },
223
239
  requiresStudio: false,
224
- examples: ['seeflow flows:graph abc12345'],
240
+ examples: ['seeflow flows:graph --project order-pipeline --flow main'],
225
241
  },
226
242
  {
227
243
  name: 'flows:delete',
228
- synopsis: 'seeflow flows:delete <flowId>',
229
- description: 'Unregister a flow from the studio (the on-disk file is left untouched).',
244
+ synopsis: 'seeflow flows:delete --project <p> --flow <f> [--new-default <other>]',
245
+ description:
246
+ 'Delete a flow from a project. Removes the `flows/<flow>/` folder, updates ' +
247
+ '`seeflow.json`, and drops the registry entry. Refuses to delete the last flow ' +
248
+ 'in a project or the project default without --new-default.',
230
249
  category: 'flows',
231
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
232
- flags: [],
233
- outputs: { okExample: { ok: true }, errorKinds: ['notFound'] },
250
+ args: [],
251
+ flags: [
252
+ {
253
+ name: 'project',
254
+ valuePlaceholder: '<p>',
255
+ description: 'Project slug',
256
+ required: true,
257
+ },
258
+ {
259
+ name: 'flow',
260
+ valuePlaceholder: '<f>',
261
+ description: 'Flow id within the project',
262
+ required: true,
263
+ },
264
+ {
265
+ name: 'new-default',
266
+ valuePlaceholder: '<other>',
267
+ description: 'Required when deleting the project default — names the flow that takes over',
268
+ },
269
+ ],
270
+ outputs: {
271
+ okExample: { ok: true },
272
+ errorKinds: ['notFound'],
273
+ },
234
274
  requiresStudio: false,
235
- examples: ['seeflow flows:delete abc12345'],
275
+ examples: [
276
+ 'seeflow flows:delete --project order-pipeline --flow retry',
277
+ 'seeflow flows:delete --project order-pipeline --flow main --new-default retry',
278
+ ],
279
+ },
280
+ {
281
+ name: 'flows:create',
282
+ synopsis: 'seeflow flows:create --project <p> --flow <id> --name <n> [--icon <i>]',
283
+ description:
284
+ 'Create a new flow within an existing project. Writes ' +
285
+ '`<repoPath>/flows/<id>/flow.json` with an empty envelope and appends the ' +
286
+ 'new entry to the project manifest atomically.',
287
+ category: 'flows',
288
+ args: [],
289
+ flags: [
290
+ {
291
+ name: 'project',
292
+ valuePlaceholder: '<p>',
293
+ description: 'Project slug',
294
+ required: true,
295
+ },
296
+ {
297
+ name: 'flow',
298
+ valuePlaceholder: '<id>',
299
+ description: 'New flow id (lowercase alphanumeric + dashes)',
300
+ required: true,
301
+ },
302
+ {
303
+ name: 'name',
304
+ valuePlaceholder: '<n>',
305
+ description: 'Human-readable flow name',
306
+ required: true,
307
+ },
308
+ {
309
+ name: 'icon',
310
+ valuePlaceholder: '<i>',
311
+ description: 'Optional icon name shown next to the flow in the switcher',
312
+ },
313
+ ],
314
+ outputs: {
315
+ okExample: { id: 'abc12345', slug: 'order-pipeline/retry', flowSlug: 'retry' },
316
+ errorKinds: ['notFound'],
317
+ },
318
+ requiresStudio: false,
319
+ examples: [
320
+ 'seeflow flows:create --project order-pipeline --flow retry --name "Retry"',
321
+ 'seeflow flows:create --project order-pipeline --flow retry --name "Retry" --icon refresh',
322
+ ],
323
+ },
324
+ {
325
+ name: 'flows:rename',
326
+ synopsis:
327
+ 'seeflow flows:rename --project <p> --flow <id> [--new-id <x>] [--name <n>] [--icon <i>]',
328
+ description:
329
+ "Rename a flow's id, name, and/or icon. Changing --new-id moves the on-disk " +
330
+ '`flows/<id>/` folder atomically and rewrites the manifest (including ' +
331
+ '`defaultFlow` if it pointed at the renamed flow). Updating only --name / ' +
332
+ '--icon edits the manifest in place without touching the filesystem layout.',
333
+ category: 'flows',
334
+ args: [],
335
+ flags: [
336
+ {
337
+ name: 'project',
338
+ valuePlaceholder: '<p>',
339
+ description: 'Project slug',
340
+ required: true,
341
+ },
342
+ {
343
+ name: 'flow',
344
+ valuePlaceholder: '<id>',
345
+ description: 'Current flow id within the project',
346
+ required: true,
347
+ },
348
+ { name: 'new-id', valuePlaceholder: '<x>', description: 'New flow id (renames the folder)' },
349
+ { name: 'name', valuePlaceholder: '<n>', description: 'New human-readable name' },
350
+ { name: 'icon', valuePlaceholder: '<i>', description: 'New icon name' },
351
+ ],
352
+ outputs: {
353
+ okExample: { id: 'abc12345', slug: 'order-pipeline/retry-v2', flowSlug: 'retry-v2' },
354
+ errorKinds: ['notFound'],
355
+ },
356
+ requiresStudio: false,
357
+ examples: [
358
+ 'seeflow flows:rename --project order-pipeline --flow retry --new-id retry-v2',
359
+ 'seeflow flows:rename --project order-pipeline --flow main --name "Primary"',
360
+ ],
236
361
  },
237
362
  {
238
363
  name: 'flows:layout',
239
- synopsis: 'seeflow flows:layout <flowId> [--json | --file | --stdin]',
364
+ synopsis: 'seeflow flows:layout --project <p> --flow <f> [--json | --file | --stdin]',
240
365
  description:
241
366
  'Compute an ELK layout for the flow and write style.json next to flow.json. ' +
242
367
  'Body is optional — `{ options? }` shape. Empty body uses defaults.',
243
368
  category: 'flows',
244
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
245
- flags: BODY_FLAGS,
369
+ args: [],
370
+ flags: [
371
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
372
+ {
373
+ name: 'flow',
374
+ valuePlaceholder: '<f>',
375
+ description: 'Flow id within the project',
376
+ required: true,
377
+ },
378
+ ...BODY_FLAGS,
379
+ ],
246
380
  body: { example: { options: { 'elk.direction': 'RIGHT' } } },
247
381
  outputs: {
248
382
  okExample: { ok: true },
249
383
  errorKinds: ['flowNotFound', 'fileNotFound', 'badJson', 'badSchema', 'writeFailed'],
250
384
  },
251
385
  requiresStudio: false,
252
- examples: ['seeflow flows:layout abc12345'],
386
+ examples: ['seeflow flows:layout --project order-pipeline --flow main'],
253
387
  },
254
388
  {
255
389
  name: 'flow:add-bulk',
256
- synopsis: 'seeflow flow:add-bulk <flowId> [--json | --file | --stdin]',
390
+ synopsis: 'seeflow flow:add-bulk --project <p> --flow <f> [--json | --file | --stdin]',
257
391
  description:
258
392
  'Add up to 100 nodes + 100 connectors atomically. Body shape: ' +
259
393
  '`{ nodes?: Node[], connectors?: Connector[] }` (at least one non-empty). ' +
@@ -261,8 +395,17 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
261
395
  'is re-validated post-merge so a dangling source/target — or any per-item ' +
262
396
  'schema failure — rolls back both arrays together and emits no broadcast.',
263
397
  category: 'flows',
264
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
265
- flags: BODY_FLAGS,
398
+ args: [],
399
+ flags: [
400
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
401
+ {
402
+ name: 'flow',
403
+ valuePlaceholder: '<f>',
404
+ description: 'Flow id within the project',
405
+ required: true,
406
+ },
407
+ ...BODY_FLAGS,
408
+ ],
266
409
  body: { schemaRef: 'FlowBulkBody' },
267
410
  outputs: {
268
411
  okExample: {
@@ -281,29 +424,35 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
281
424
  },
282
425
  requiresStudio: false,
283
426
  examples: [
284
- 'seeflow flow:add-bulk abc12345 --json \'{"nodes":[{"id":"a","type":"rectangle","data":{}}],"connectors":[]}\'',
285
- 'seeflow flow:add-bulk abc12345 --file batch.json',
427
+ 'seeflow flow:add-bulk --project order-pipeline --flow main --json \'{"nodes":[{"id":"a","type":"rectangle","data":{}}],"connectors":[]}\'',
428
+ 'seeflow flow:add-bulk --project order-pipeline --flow main --file batch.json',
286
429
  ],
287
430
  },
288
431
  {
289
432
  name: 'flows:play',
290
- synopsis: 'seeflow flows:play <flowId> <nodeId> [--no-start]',
433
+ synopsis: 'seeflow flows:play --project <p> --flow <f> <nodeId> [--no-start]',
291
434
  description:
292
435
  "Trigger the node's playAction on the studio and wait for the spawn-level " +
293
436
  'result. The studio also broadcasts node:running/done/error events on the ' +
294
437
  "flow's SSE stream — subscribe separately if you want live progress. " +
295
438
  'Requires a running studio.',
296
439
  category: 'live',
297
- args: [
298
- { name: 'flowId', required: true, description: 'Flow id or slug' },
299
- { name: 'nodeId', required: true, description: 'Node id in the flow' },
440
+ args: [{ name: 'nodeId', required: true, description: 'Node id in the flow' }],
441
+ flags: [
442
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
443
+ {
444
+ name: 'flow',
445
+ valuePlaceholder: '<f>',
446
+ description: 'Flow id within the project',
447
+ required: true,
448
+ },
449
+ { name: 'no-start', description: 'Fail if the studio is not already running' },
300
450
  ],
301
- flags: [{ name: 'no-start', description: 'Fail if the studio is not already running' }],
302
451
  outputs: {
303
452
  okExample: { runId: 'run-9b3', status: 200, body: { ok: true } },
304
453
  },
305
454
  requiresStudio: true,
306
- examples: ['seeflow flows:play abc12345 api-checkout'],
455
+ examples: ['seeflow flows:play --project order-pipeline --flow main api-checkout'],
307
456
  },
308
457
  // ---- project -----------------------------------------------------------
309
458
  {
@@ -342,11 +491,20 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
342
491
  // ---- nodes -------------------------------------------------------------
343
492
  {
344
493
  name: 'nodes:add',
345
- synopsis: 'seeflow nodes:add <flowId> [--json | --file | --stdin]',
494
+ synopsis: 'seeflow nodes:add --project <p> --flow <f> [--json | --file | --stdin]',
346
495
  description: 'Add a single node to a flow. Body is the node object (auto-id if omitted).',
347
496
  category: 'nodes',
348
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
349
- flags: BODY_FLAGS,
497
+ args: [],
498
+ flags: [
499
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
500
+ {
501
+ name: 'flow',
502
+ valuePlaceholder: '<f>',
503
+ description: 'Flow id within the project',
504
+ required: true,
505
+ },
506
+ ...BODY_FLAGS,
507
+ ],
350
508
  body: {
351
509
  example: {
352
510
  type: 'rectangle',
@@ -358,34 +516,47 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
358
516
  errorKinds: ['flowNotFound', 'fileNotFound', 'badJson', 'badSchema', 'writeFailed'],
359
517
  },
360
518
  requiresStudio: false,
361
- examples: ['seeflow nodes:add abc12345 --json \'{"type":"rectangle","data":{}}\''],
519
+ examples: [
520
+ 'seeflow nodes:add --project order-pipeline --flow main --json \'{"type":"rectangle","data":{}}\'',
521
+ ],
362
522
  },
363
523
  {
364
524
  name: 'nodes:get',
365
- synopsis: 'seeflow nodes:get <flowId> <nodeId>',
525
+ synopsis: 'seeflow nodes:get --project <p> --flow <f> <nodeId>',
366
526
  description:
367
527
  'Get one node with its file-backed content (detail.md, view.html) inlined. ' +
368
528
  'Use after flows:graph to drill in.',
369
529
  category: 'nodes',
370
- args: [
371
- { name: 'flowId', required: true, description: 'Flow id or slug' },
372
- { name: 'nodeId', required: true, description: 'Node id in the flow' },
530
+ args: [{ name: 'nodeId', required: true, description: 'Node id in the flow' }],
531
+ flags: [
532
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
533
+ {
534
+ name: 'flow',
535
+ valuePlaceholder: '<f>',
536
+ description: 'Flow id within the project',
537
+ required: true,
538
+ },
373
539
  ],
374
- flags: [],
375
540
  outputs: { errorKinds: ['notFound', 'fileNotFound', 'unknownNode', 'badJson', 'badSchema'] },
376
541
  requiresStudio: false,
377
- examples: ['seeflow nodes:get abc12345 api-checkout'],
542
+ examples: ['seeflow nodes:get --project order-pipeline --flow main api-checkout'],
378
543
  },
379
544
  {
380
545
  name: 'nodes:patch',
381
- synopsis: 'seeflow nodes:patch <flowId> <nodeId> [--json | --file | --stdin]',
546
+ synopsis: 'seeflow nodes:patch --project <p> --flow <f> <nodeId> [--json | --file | --stdin]',
382
547
  description: 'Patch fields on an existing node. Validates the partial against NodePatchBody.',
383
548
  category: 'nodes',
384
- args: [
385
- { name: 'flowId', required: true, description: 'Flow id or slug' },
386
- { name: 'nodeId', required: true, description: 'Node id in the flow' },
549
+ args: [{ name: 'nodeId', required: true, description: 'Node id in the flow' }],
550
+ flags: [
551
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
552
+ {
553
+ name: 'flow',
554
+ valuePlaceholder: '<f>',
555
+ description: 'Flow id within the project',
556
+ required: true,
557
+ },
558
+ ...BODY_FLAGS,
387
559
  ],
388
- flags: BODY_FLAGS,
389
560
  body: { schemaRef: 'NodePatchBody' },
390
561
  outputs: {
391
562
  errorKinds: [
@@ -398,18 +569,24 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
398
569
  ],
399
570
  },
400
571
  requiresStudio: false,
401
- examples: ['seeflow nodes:patch abc12345 api-checkout --json \'{"data":{"name":"renamed"}}\''],
572
+ examples: [
573
+ 'seeflow nodes:patch --project order-pipeline --flow main api-checkout --json \'{"data":{"name":"renamed"}}\'',
574
+ ],
402
575
  },
403
576
  {
404
577
  name: 'nodes:move',
405
- synopsis: 'seeflow nodes:move <flowId> <nodeId> --x <n> --y <n>',
578
+ synopsis: 'seeflow nodes:move --project <p> --flow <f> <nodeId> --x <n> --y <n>',
406
579
  description: 'Set the node position in style.json (does not touch flow.json).',
407
580
  category: 'nodes',
408
- args: [
409
- { name: 'flowId', required: true, description: 'Flow id or slug' },
410
- { name: 'nodeId', required: true, description: 'Node id in the flow' },
411
- ],
581
+ args: [{ name: 'nodeId', required: true, description: 'Node id in the flow' }],
412
582
  flags: [
583
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
584
+ {
585
+ name: 'flow',
586
+ valuePlaceholder: '<f>',
587
+ description: 'Flow id within the project',
588
+ required: true,
589
+ },
413
590
  { name: 'x', valuePlaceholder: '<n>', description: 'X coordinate', required: true },
414
591
  { name: 'y', valuePlaceholder: '<n>', description: 'Y coordinate', required: true },
415
592
  ],
@@ -425,19 +602,25 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
425
602
  ],
426
603
  },
427
604
  requiresStudio: false,
428
- examples: ['seeflow nodes:move abc12345 api-checkout --x 250 --y 320'],
605
+ examples: [
606
+ 'seeflow nodes:move --project order-pipeline --flow main api-checkout --x 250 --y 320',
607
+ ],
429
608
  },
430
609
  {
431
610
  name: 'nodes:reorder',
432
611
  synopsis:
433
- 'seeflow nodes:reorder <flowId> <nodeId> --op forward|backward|toFront|toBack|toIndex [--index <n>]',
612
+ 'seeflow nodes:reorder --project <p> --flow <f> <nodeId> --op forward|backward|toFront|toBack|toIndex [--index <n>]',
434
613
  description: "Reorder a node's z-position within the flow.",
435
614
  category: 'nodes',
436
- args: [
437
- { name: 'flowId', required: true, description: 'Flow id or slug' },
438
- { name: 'nodeId', required: true, description: 'Node id in the flow' },
439
- ],
615
+ args: [{ name: 'nodeId', required: true, description: 'Node id in the flow' }],
440
616
  flags: [
617
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
618
+ {
619
+ name: 'flow',
620
+ valuePlaceholder: '<f>',
621
+ description: 'Flow id within the project',
622
+ required: true,
623
+ },
441
624
  {
442
625
  name: 'op',
443
626
  valuePlaceholder: '<op>',
@@ -459,20 +642,25 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
459
642
  },
460
643
  requiresStudio: false,
461
644
  examples: [
462
- 'seeflow nodes:reorder abc12345 api-checkout --op forward',
463
- 'seeflow nodes:reorder abc12345 api-checkout --op toIndex --index 0',
645
+ 'seeflow nodes:reorder --project order-pipeline --flow main api-checkout --op forward',
646
+ 'seeflow nodes:reorder --project order-pipeline --flow main api-checkout --op toIndex --index 0',
464
647
  ],
465
648
  },
466
649
  {
467
650
  name: 'nodes:delete',
468
- synopsis: 'seeflow nodes:delete <flowId> <nodeId>',
651
+ synopsis: 'seeflow nodes:delete --project <p> --flow <f> <nodeId>',
469
652
  description: 'Delete a node and any connectors that reference it.',
470
653
  category: 'nodes',
471
- args: [
472
- { name: 'flowId', required: true, description: 'Flow id or slug' },
473
- { name: 'nodeId', required: true, description: 'Node id in the flow' },
654
+ args: [{ name: 'nodeId', required: true, description: 'Node id in the flow' }],
655
+ flags: [
656
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
657
+ {
658
+ name: 'flow',
659
+ valuePlaceholder: '<f>',
660
+ description: 'Flow id within the project',
661
+ required: true,
662
+ },
474
663
  ],
475
- flags: [],
476
664
  outputs: {
477
665
  okExample: { ok: true, removedConnectors: 0 },
478
666
  errorKinds: [
@@ -485,18 +673,27 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
485
673
  ],
486
674
  },
487
675
  requiresStudio: false,
488
- examples: ['seeflow nodes:delete abc12345 api-checkout'],
676
+ examples: ['seeflow nodes:delete --project order-pipeline --flow main api-checkout'],
489
677
  },
490
678
  // ---- connectors --------------------------------------------------------
491
679
  {
492
680
  name: 'connectors:add',
493
- synopsis: 'seeflow connectors:add <flowId> [--json | --file | --stdin]',
681
+ synopsis: 'seeflow connectors:add --project <p> --flow <f> [--json | --file | --stdin]',
494
682
  description:
495
683
  'Add a connector. Body is the connector object — `source` and `target` are ' +
496
684
  'the connected node ids (strings). Auto-generates an id when absent.',
497
685
  category: 'connectors',
498
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
499
- flags: BODY_FLAGS,
686
+ args: [],
687
+ flags: [
688
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
689
+ {
690
+ name: 'flow',
691
+ valuePlaceholder: '<f>',
692
+ description: 'Flow id within the project',
693
+ required: true,
694
+ },
695
+ ...BODY_FLAGS,
696
+ ],
500
697
  body: {
501
698
  example: { source: 'a', target: 'b' },
502
699
  },
@@ -505,18 +702,27 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
505
702
  errorKinds: ['flowNotFound', 'fileNotFound', 'badJson', 'badSchema', 'writeFailed'],
506
703
  },
507
704
  requiresStudio: false,
508
- examples: ['seeflow connectors:add abc12345 --json \'{"source":"a","target":"b"}\''],
705
+ examples: [
706
+ 'seeflow connectors:add --project order-pipeline --flow main --json \'{"source":"a","target":"b"}\'',
707
+ ],
509
708
  },
510
709
  {
511
710
  name: 'connectors:patch',
512
- synopsis: 'seeflow connectors:patch <flowId> <connectorId> [--json | --file | --stdin]',
711
+ synopsis:
712
+ 'seeflow connectors:patch --project <p> --flow <f> <connectorId> [--json | --file | --stdin]',
513
713
  description: 'Patch fields on an existing connector.',
514
714
  category: 'connectors',
515
- args: [
516
- { name: 'flowId', required: true, description: 'Flow id or slug' },
517
- { name: 'connectorId', required: true, description: 'Connector id in the flow' },
715
+ args: [{ name: 'connectorId', required: true, description: 'Connector id in the flow' }],
716
+ flags: [
717
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
718
+ {
719
+ name: 'flow',
720
+ valuePlaceholder: '<f>',
721
+ description: 'Flow id within the project',
722
+ required: true,
723
+ },
724
+ ...BODY_FLAGS,
518
725
  ],
519
- flags: BODY_FLAGS,
520
726
  body: { schemaRef: 'ConnectorPatchBody' },
521
727
  outputs: {
522
728
  errorKinds: [
@@ -529,18 +735,25 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
529
735
  ],
530
736
  },
531
737
  requiresStudio: false,
532
- examples: ['seeflow connectors:patch abc12345 conn-1 --json \'{"label":"new"}\''],
738
+ examples: [
739
+ 'seeflow connectors:patch --project order-pipeline --flow main conn-1 --json \'{"label":"new"}\'',
740
+ ],
533
741
  },
534
742
  {
535
743
  name: 'connectors:delete',
536
- synopsis: 'seeflow connectors:delete <flowId> <connectorId>',
744
+ synopsis: 'seeflow connectors:delete --project <p> --flow <f> <connectorId>',
537
745
  description: 'Delete a connector.',
538
746
  category: 'connectors',
539
- args: [
540
- { name: 'flowId', required: true, description: 'Flow id or slug' },
541
- { name: 'connectorId', required: true, description: 'Connector id in the flow' },
747
+ args: [{ name: 'connectorId', required: true, description: 'Connector id in the flow' }],
748
+ flags: [
749
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
750
+ {
751
+ name: 'flow',
752
+ valuePlaceholder: '<f>',
753
+ description: 'Flow id within the project',
754
+ required: true,
755
+ },
542
756
  ],
543
- flags: [],
544
757
  outputs: {
545
758
  okExample: { ok: true },
546
759
  errorKinds: [
@@ -553,7 +766,7 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
553
766
  ],
554
767
  },
555
768
  requiresStudio: false,
556
- examples: ['seeflow connectors:delete abc12345 conn-1'],
769
+ examples: ['seeflow connectors:delete --project order-pipeline --flow main conn-1'],
557
770
  },
558
771
  // ---- validate ----------------------------------------------------------
559
772
  {
@@ -610,7 +823,7 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
610
823
  },
611
824
  {
612
825
  name: 'schema',
613
- synopsis: 'seeflow schema [<category>]',
826
+ synopsis: 'seeflow schema [<category>] [--jq <filter>]',
614
827
  description:
615
828
  'Introspect the SeeFlow flow.json / style.json / spec.json schemas at ' +
616
829
  'runtime. Call without arguments to list the six categories (flow, node, ' +
@@ -620,7 +833,15 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
620
833
  "all 13 flat variants (including type:'component', whose `spec` field " +
621
834
  'lives in a sidecar — drill into `componentSpec` for that shape). Use ' +
622
835
  'this before authoring any flow.json / spec.json write — never memorise ' +
623
- 'field shapes.',
836
+ 'field shapes.\n\n' +
837
+ 'Pass --jq <filter> to extract a slice of the response with a jq path ' +
838
+ 'expression. Supported subset: identity (`.`), field access ' +
839
+ '(`.foo.bar`), bracket access (`.["foo"]`, `.[3]`, negative indices ' +
840
+ 'allowed), iteration (`.foo[]`), optional `?` (e.g. `.foo?` to suppress ' +
841
+ 'type errors), and pipe (`|`). Single-output filters return the value ' +
842
+ 'under `{ result: <value> }`; multi-output filters (from `[]` or `|`) ' +
843
+ 'return `{ result: [<v1>, <v2>, ...] }`. Bad filters exit with code 2 ' +
844
+ 'and `code:"badJq"`.',
624
845
  category: 'meta',
625
846
  args: [
626
847
  {
@@ -629,10 +850,19 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
629
850
  description: 'One of: flow, node, connector, action, componentSpec, style',
630
851
  },
631
852
  ],
632
- flags: [],
853
+ flags: [
854
+ {
855
+ name: 'jq',
856
+ valuePlaceholder: '<filter>',
857
+ description:
858
+ 'Apply a jq path-subset filter to the response payload. Examples: ' +
859
+ '`.schemas.rectangle`, `.schemas.image.properties.data.properties.path`, ' +
860
+ '`.schemas[]`, `.notes[0]`.',
861
+ },
862
+ ],
633
863
  outputs: {
634
864
  okExample: { categories: [{ name: 'flow', description: 'Top-level flow.json envelope.' }] },
635
- errorKinds: ['notFound'],
865
+ errorKinds: ['notFound', 'badJq'],
636
866
  },
637
867
  requiresStudio: false,
638
868
  examples: [
@@ -640,12 +870,15 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
640
870
  'seeflow schema node',
641
871
  'seeflow schema connector',
642
872
  'seeflow schema componentSpec',
873
+ 'seeflow schema node --jq .schemas.rectangle',
874
+ "seeflow schema node --jq '.schemas.image.properties.data.properties.path'",
875
+ "seeflow schema node --jq '.schemas[]'",
643
876
  ],
644
877
  },
645
878
  // ---- live --------------------------------------------------------------
646
879
  {
647
880
  name: 'e2e',
648
- synopsis: 'seeflow e2e <flowId> [--skip-nodes a,b] [--no-start]',
881
+ synopsis: 'seeflow e2e --project <p> --flow <f> [--skip-nodes a,b] [--no-start]',
649
882
  description:
650
883
  'End-to-end validate a registered flow. Walks every node with a playAction ' +
651
884
  "in flow.json order, POSTs each play, then drains the flow's SSE stream " +
@@ -653,8 +886,15 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
653
886
  'when finished; exits non-zero if any play failed, any statusAction failed ' +
654
887
  'to report, or the 120s ceiling was exceeded. Requires a running studio.',
655
888
  category: 'live',
656
- args: [{ name: 'flowId', required: true, description: 'Flow id or slug' }],
889
+ args: [],
657
890
  flags: [
891
+ { name: 'project', valuePlaceholder: '<p>', description: 'Project slug', required: true },
892
+ {
893
+ name: 'flow',
894
+ valuePlaceholder: '<f>',
895
+ description: 'Flow id within the project',
896
+ required: true,
897
+ },
658
898
  {
659
899
  name: 'skip-nodes',
660
900
  valuePlaceholder: '<a,b>',
@@ -671,7 +911,10 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
671
911
  },
672
912
  },
673
913
  requiresStudio: true,
674
- examples: ['seeflow e2e abc12345', 'seeflow e2e abc12345 --skip-nodes flaky-1,flaky-2'],
914
+ examples: [
915
+ 'seeflow e2e --project order-pipeline --flow main',
916
+ 'seeflow e2e --project order-pipeline --flow main --skip-nodes flaky-1,flaky-2',
917
+ ],
675
918
  },
676
919
  {
677
920
  name: 'emit',