@synergenius/flow-weaver 0.17.0 → 0.17.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.
Files changed (123) hide show
  1. package/dist/api/index.d.ts +4 -1
  2. package/dist/api/index.js +4 -1
  3. package/dist/api/templates.js +2 -2
  4. package/dist/api/validate.d.ts +2 -2
  5. package/dist/api/validate.js +6 -6
  6. package/dist/api/validation-registry.d.ts +10 -0
  7. package/dist/api/validation-registry.js +10 -0
  8. package/dist/ast/types.d.ts +91 -4
  9. package/dist/built-in-nodes/invoke-workflow.d.ts +1 -1
  10. package/dist/built-in-nodes/invoke-workflow.js +1 -1
  11. package/dist/chevrotain-parser/connect-parser.js +25 -7
  12. package/dist/cli/commands/compile.d.ts +5 -9
  13. package/dist/cli/commands/compile.js +21 -14
  14. package/dist/cli/commands/dev.d.ts +2 -13
  15. package/dist/cli/commands/dev.js +10 -204
  16. package/dist/cli/commands/doctor.js +6 -3
  17. package/dist/cli/commands/export.d.ts +8 -17
  18. package/dist/cli/commands/export.js +8 -17
  19. package/dist/cli/commands/init-personas.d.ts +17 -6
  20. package/dist/cli/commands/init-personas.js +73 -24
  21. package/dist/cli/commands/init.d.ts +5 -2
  22. package/dist/cli/commands/init.js +73 -42
  23. package/dist/cli/commands/mcp-setup.d.ts +7 -0
  24. package/dist/cli/commands/mcp-setup.js +16 -1
  25. package/dist/cli/flow-weaver.mjs +71002 -70385
  26. package/dist/cli/index.d.ts +1 -0
  27. package/dist/cli/index.js +9 -7
  28. package/dist/cli/templates/index.d.ts +20 -1
  29. package/dist/cli/templates/index.js +66 -15
  30. package/dist/cli/templates/nodes/human-approval.js +2 -3
  31. package/dist/cli/templates/nodes/rag-retriever.js +1 -1
  32. package/dist/constants.d.ts +7 -0
  33. package/dist/constants.js +13 -3
  34. package/dist/context/index.js +13 -3
  35. package/dist/deployment/config/loader.js +2 -1
  36. package/dist/deployment/core/adapters.d.ts +1 -25
  37. package/dist/deployment/core/adapters.js +0 -95
  38. package/dist/deployment/core/formatters.d.ts +0 -15
  39. package/dist/deployment/core/formatters.js +0 -24
  40. package/dist/deployment/index.d.ts +7 -5
  41. package/dist/deployment/index.js +8 -5
  42. package/dist/deployment/types.d.ts +2 -45
  43. package/dist/diagram/html-viewer.js +65 -32
  44. package/dist/diagram/renderer.js +9 -6
  45. package/dist/diagram/theme.js +4 -0
  46. package/dist/diagram/types.d.ts +2 -0
  47. package/dist/doc-metadata/extractors/annotations.js +5 -5
  48. package/dist/doc-metadata/extractors/cli-commands.js +1 -1
  49. package/dist/doc-metadata/extractors/mcp-tools.js +1 -2
  50. package/dist/docs/index.d.ts +28 -1
  51. package/dist/docs/index.js +95 -28
  52. package/dist/export/index.d.ts +2 -3
  53. package/dist/{deployment/targets/cicd-base.d.ts → extensions/cicd/base-target.d.ts} +35 -36
  54. package/dist/{deployment/targets/cicd-base.js → extensions/cicd/base-target.js} +97 -57
  55. package/dist/{validation/cicd-detection.d.ts → extensions/cicd/detection.d.ts} +2 -2
  56. package/dist/{validation/cicd-detection.js → extensions/cicd/detection.js} +13 -1
  57. package/dist/extensions/cicd/docs/cicd.md +395 -0
  58. package/dist/extensions/cicd/index.d.ts +10 -0
  59. package/dist/extensions/cicd/index.js +10 -0
  60. package/dist/extensions/cicd/register.d.ts +11 -0
  61. package/dist/extensions/cicd/register.js +62 -0
  62. package/dist/extensions/cicd/rules.d.ts +30 -0
  63. package/dist/{validation/cicd-rules.js → extensions/cicd/rules.js} +60 -56
  64. package/dist/extensions/cicd/tag-handler.d.ts +14 -0
  65. package/dist/extensions/cicd/tag-handler.js +488 -0
  66. package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-docker.d.ts +1 -1
  67. package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-matrix.d.ts +1 -1
  68. package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-multi-env.d.ts +1 -1
  69. package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-test-deploy.d.ts +1 -1
  70. package/dist/extensions/index.d.ts +12 -0
  71. package/dist/extensions/index.js +12 -0
  72. package/dist/extensions/inngest/dev-mode.d.ts +9 -0
  73. package/dist/extensions/inngest/dev-mode.js +213 -0
  74. package/dist/{generator/inngest.d.ts → extensions/inngest/generator.d.ts} +2 -2
  75. package/dist/{generator/inngest.js → extensions/inngest/generator.js} +4 -4
  76. package/dist/extensions/inngest/index.d.ts +2 -0
  77. package/dist/extensions/inngest/index.js +2 -0
  78. package/dist/extensions/inngest/register.d.ts +6 -0
  79. package/dist/extensions/inngest/register.js +23 -0
  80. package/dist/extensions/inngest/templates/ai-agent-durable.d.ts +8 -0
  81. package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-agent-durable.js +8 -8
  82. package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-pipeline-durable.d.ts +2 -2
  83. package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-pipeline-durable.js +7 -7
  84. package/dist/generated-version.d.ts +1 -1
  85. package/dist/generated-version.js +1 -1
  86. package/dist/generator/compile-target-registry.d.ts +20 -0
  87. package/dist/generator/compile-target-registry.js +20 -0
  88. package/dist/generator/dev-mode-registry.d.ts +27 -0
  89. package/dist/generator/dev-mode-registry.js +20 -0
  90. package/dist/index.d.ts +4 -0
  91. package/dist/index.js +3 -0
  92. package/dist/jsdoc-parser.d.ts +12 -114
  93. package/dist/jsdoc-parser.js +57 -362
  94. package/dist/marketplace/index.d.ts +2 -2
  95. package/dist/marketplace/index.js +1 -1
  96. package/dist/marketplace/registry.d.ts +39 -1
  97. package/dist/marketplace/registry.js +77 -0
  98. package/dist/marketplace/types.d.ts +76 -3
  99. package/dist/mcp/server.d.ts +1 -0
  100. package/dist/mcp/server.js +2 -0
  101. package/dist/mcp/tools-export.js +3 -3
  102. package/dist/mcp/tools-query.js +17 -11
  103. package/dist/mcp/tools-template.js +1 -1
  104. package/dist/parser/tag-registry.d.ts +47 -0
  105. package/dist/parser/tag-registry.js +57 -0
  106. package/dist/parser.d.ts +3 -0
  107. package/dist/parser.js +10 -23
  108. package/dist/validation/rule-registry.d.ts +36 -0
  109. package/dist/validation/rule-registry.js +37 -0
  110. package/dist/validator.js +3 -3
  111. package/docs/reference/concepts.md +2 -1
  112. package/docs/reference/deployment.md +21 -0
  113. package/docs/reference/jsdoc-grammar.md +242 -1
  114. package/docs/reference/scaffold.md +0 -6
  115. package/package.json +9 -1
  116. package/dist/cli/templates/workflows/ai-agent-durable.d.ts +0 -8
  117. package/dist/export/templates.d.ts +0 -24
  118. package/dist/export/templates.js +0 -186
  119. package/dist/validation/cicd-rules.d.ts +0 -62
  120. /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-docker.js +0 -0
  121. /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-matrix.js +0 -0
  122. /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-multi-env.js +0 -0
  123. /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-test-deploy.js +0 -0
@@ -10,10 +10,10 @@ import input from '@inquirer/input';
10
10
  import select, { Separator } from '@inquirer/select';
11
11
  import confirm from '@inquirer/confirm';
12
12
  import { ExitPromptError } from '@inquirer/core';
13
- import { getWorkflowTemplate, workflowTemplates } from '../templates/index.js';
13
+ import { getWorkflowTemplate, getAllWorkflowTemplates } from '../templates/index.js';
14
14
  import { logger } from '../utils/logger.js';
15
15
  import { compileCommand } from './compile.js';
16
- import { runMcpSetupFromInit, CLI_TOOL_BINARY } from './mcp-setup.js';
16
+ import { runMcpSetupFromInit, CLI_TOOL_BINARY, detectCliTools } from './mcp-setup.js';
17
17
  import { PERSONA_CHOICES, PERSONA_CONFIRMATIONS, USE_CASE_CHOICES, selectTemplateForPersona, getTemplateSubChoices, printNextSteps, generateReadme, generateExampleWorkflow, generateAgentPrompt, generateEditorPrompt, generateSetupPromptFile, printCopyablePrompt, AGENT_LAUNCH_DEFAULTS, } from './init-personas.js';
18
18
  // ── Utilities ────────────────────────────────────────────────────────────────
19
19
  const PROJECT_NAME_RE = /^[a-zA-Z0-9][-a-zA-Z0-9_.]*$/;
@@ -37,9 +37,11 @@ export function toWorkflowName(projectName) {
37
37
  export function isNonInteractive() {
38
38
  return !process.stdin.isTTY;
39
39
  }
40
- const VALID_TEMPLATES = workflowTemplates.map((t) => t.id);
40
+ // Dynamic: includes core templates plus any registered by extensions
41
+ const VALID_TEMPLATES = getAllWorkflowTemplates().map((t) => t.id);
41
42
  const VALID_PERSONAS = ['nocode', 'vibecoder', 'lowcode', 'expert'];
42
- const VALID_USE_CASES = ['data', 'ai', 'api', 'automation', 'cicd', 'minimal'];
43
+ // Dynamic: includes core use cases plus any registered by extensions
44
+ const VALID_USE_CASES = USE_CASE_CHOICES.map((c) => c.value);
43
45
  // ── Config resolution (prompts) ──────────────────────────────────────────────
44
46
  export async function resolveInitConfig(dirArg, options) {
45
47
  const skipPrompts = options.yes || isNonInteractive();
@@ -124,18 +126,10 @@ export async function resolveInitConfig(dirArg, options) {
124
126
  { value: 'ai-react', name: 'ai-react', description: 'ReAct pattern' },
125
127
  { value: 'ai-rag', name: 'ai-rag', description: 'Retrieval-Augmented Generation' },
126
128
  { value: 'ai-chat', name: 'ai-chat', description: 'Conversational AI' },
127
- new Separator('── Durable ──'),
128
- { value: 'ai-agent-durable', name: 'ai-agent-durable', description: 'Durable agent with approval gate' },
129
- { value: 'ai-pipeline-durable', name: 'ai-pipeline-durable', description: 'Durable data pipeline' },
130
129
  new Separator('── Integration ──'),
131
130
  { value: 'webhook', name: 'webhook', description: 'HTTP webhook handler' },
132
131
  new Separator('── Utility ──'),
133
132
  { value: 'error-handler', name: 'error-handler', description: 'Error handling and recovery' },
134
- new Separator('── CI/CD ──'),
135
- { value: 'cicd-test-deploy', name: 'cicd-test-deploy', description: 'Test and deploy pipeline' },
136
- { value: 'cicd-docker', name: 'cicd-docker', description: 'Docker build and push' },
137
- { value: 'cicd-multi-env', name: 'cicd-multi-env', description: 'Multi-environment deploy' },
138
- { value: 'cicd-matrix', name: 'cicd-matrix', description: 'Matrix build strategy' },
139
133
  ],
140
134
  default: 'sequential',
141
135
  });
@@ -172,7 +166,19 @@ export async function resolveInitConfig(dirArg, options) {
172
166
  template = selection.template;
173
167
  }
174
168
  }
175
- // 4. MCP setup (nocode + vibecoder only)
169
+ // 3b. "Something else" follow-up: ask what they're building
170
+ let useCaseDescription;
171
+ if (useCase === 'minimal' && !skipPrompts && persona !== 'expert') {
172
+ useCaseDescription = await input({
173
+ message: 'Briefly describe what you want to build:',
174
+ });
175
+ if (useCaseDescription) {
176
+ useCaseDescription = useCaseDescription.trim();
177
+ }
178
+ if (!useCaseDescription)
179
+ useCaseDescription = undefined;
180
+ }
181
+ // 4. MCP setup (nocode, vibecoder, lowcode: prompt; expert: skip unless --mcp)
176
182
  let mcp;
177
183
  if (options.mcp !== undefined) {
178
184
  mcp = options.mcp;
@@ -180,7 +186,7 @@ export async function resolveInitConfig(dirArg, options) {
180
186
  else if (skipPrompts) {
181
187
  mcp = false;
182
188
  }
183
- else if (persona === 'nocode' || persona === 'vibecoder') {
189
+ else if (persona === 'nocode' || persona === 'vibecoder' || persona === 'lowcode') {
184
190
  mcp = await confirm({
185
191
  message: 'Set up AI editor integration? (Claude Code, Cursor, VS Code, etc.)',
186
192
  default: true,
@@ -242,6 +248,7 @@ export async function resolveInitConfig(dirArg, options) {
242
248
  force,
243
249
  persona,
244
250
  useCase,
251
+ useCaseDescription,
245
252
  mcp,
246
253
  };
247
254
  }
@@ -415,7 +422,7 @@ export function runGitInit(targetDir) {
415
422
  * Returns true if a CLI agent was spawned (init should exit and let the agent take over).
416
423
  */
417
424
  export async function handleAgentHandoff(opts) {
418
- const { projectName, persona, template, targetDir, cliTools, guiTools, filesCreated } = opts;
425
+ const { projectName, persona, template, targetDir, cliTools, guiTools, filesCreated, useCaseDescription } = opts;
419
426
  // Step 1: If CLI agent available, offer to launch it
420
427
  if (cliTools.length > 0) {
421
428
  const toolId = cliTools[0]; // Prefer first (claude > codex)
@@ -427,7 +434,7 @@ export async function handleAgentHandoff(opts) {
427
434
  default: launchDefault,
428
435
  });
429
436
  if (shouldLaunch && binary) {
430
- const prompt = generateAgentPrompt(projectName, persona, template);
437
+ const prompt = generateAgentPrompt(projectName, persona, template, useCaseDescription);
431
438
  logger.newline();
432
439
  logger.log(` ${logger.dim(`Starting ${displayName}...`)}`);
433
440
  logger.newline();
@@ -456,12 +463,12 @@ export async function handleAgentHandoff(opts) {
456
463
  });
457
464
  if (promptAction === 'skip')
458
465
  return false;
459
- const editorPrompt = generateEditorPrompt(projectName, persona, template);
466
+ const editorPrompt = generateEditorPrompt(projectName, persona, template, useCaseDescription);
460
467
  if (promptAction === 'terminal' || promptAction === 'both') {
461
468
  printCopyablePrompt(editorPrompt);
462
469
  }
463
470
  if (promptAction === 'file' || promptAction === 'both') {
464
- const setupContent = generateSetupPromptFile(projectName, persona, template, filesCreated);
471
+ const setupContent = generateSetupPromptFile(projectName, persona, template, filesCreated, useCaseDescription);
465
472
  const setupPath = path.join(targetDir, 'PROJECT_SETUP.md');
466
473
  fs.writeFileSync(setupPath, setupContent, 'utf8');
467
474
  // Add to .gitignore
@@ -526,18 +533,27 @@ export async function initCommand(dirArg, options) {
526
533
  let mcpConfigured;
527
534
  let mcpResult;
528
535
  if (config.mcp && !options.json) {
529
- const spinner = logger.spinner('Configuring AI editors...');
536
+ const spinner = logger.spinner('Detecting AI editors...');
530
537
  try {
531
538
  mcpResult = await runMcpSetupFromInit();
532
539
  mcpConfigured = mcpResult.configured;
533
- if (mcpResult.configured.length > 0) {
534
- spinner.stop(`${mcpResult.configured.join(', ')} configured`);
540
+ spinner.stop();
541
+ // Per-tool status lines
542
+ for (const t of mcpResult.detected) {
543
+ if (!t.detected)
544
+ continue;
545
+ const wasConfigured = mcpConfigured.includes(t.displayName);
546
+ if (wasConfigured) {
547
+ logger.success(`${t.displayName} configured`);
548
+ }
535
549
  }
536
- else if (mcpResult.failed.length > 0) {
537
- spinner.fail('MCP setup failed');
550
+ if (mcpResult.failed.length > 0) {
551
+ for (const name of mcpResult.failed) {
552
+ logger.warn(`${name} failed to configure`);
553
+ }
538
554
  }
539
- else {
540
- spinner.stop('No AI editors detected');
555
+ if (mcpResult.detected.every((t) => !t.detected)) {
556
+ logger.log(` ${logger.dim('No AI editors detected')}`);
541
557
  }
542
558
  }
543
559
  catch {
@@ -604,25 +620,39 @@ export async function initCommand(dirArg, options) {
604
620
  // Persona-specific rich output
605
621
  const relDir = path.relative(process.cwd(), config.targetDir);
606
622
  const displayDir = !relDir || relDir === '.' ? null : relDir.startsWith('../../') ? config.targetDir : relDir;
607
- // Agent handoff: offer to launch CLI agent or generate prompt for GUI editors
623
+ // Agent handoff: offer to launch CLI agent or generate prompt for GUI editors.
624
+ // Decoupled from MCP: even if MCP wasn't run, check for available CLI tools.
608
625
  const skipAgent = options.agent === false || options.yes || isNonInteractive();
609
- if (mcpConfigured && mcpConfigured.length > 0 && !skipAgent) {
610
- try {
611
- agentLaunched = await handleAgentHandoff({
612
- projectName: config.projectName,
613
- persona: config.persona,
614
- template: config.template,
615
- targetDir: config.targetDir,
616
- cliTools: mcpCliTools,
617
- guiTools: mcpGuiTools,
618
- filesCreated,
619
- });
620
- report.agentLaunched = agentLaunched;
626
+ if (!skipAgent) {
627
+ // If MCP didn't run or found no CLI tools, do a quick binary check
628
+ if (mcpCliTools.length === 0) {
629
+ try {
630
+ mcpCliTools = await detectCliTools();
631
+ }
632
+ catch {
633
+ // Non-fatal
634
+ }
621
635
  }
622
- catch (err) {
623
- if (err instanceof ExitPromptError)
624
- return;
625
- // Non-fatal: just skip agent handoff
636
+ const hasTools = mcpCliTools.length > 0 || mcpGuiTools.length > 0;
637
+ if (hasTools) {
638
+ try {
639
+ agentLaunched = await handleAgentHandoff({
640
+ projectName: config.projectName,
641
+ persona: config.persona,
642
+ template: config.template,
643
+ targetDir: config.targetDir,
644
+ cliTools: mcpCliTools,
645
+ guiTools: mcpGuiTools,
646
+ filesCreated,
647
+ useCaseDescription: config.useCaseDescription,
648
+ });
649
+ report.agentLaunched = agentLaunched;
650
+ }
651
+ catch (err) {
652
+ if (err instanceof ExitPromptError)
653
+ return;
654
+ // Non-fatal: just skip agent handoff
655
+ }
626
656
  }
627
657
  }
628
658
  // If an agent was spawned, it takes over. Print minimal output.
@@ -639,6 +669,7 @@ export async function initCommand(dirArg, options) {
639
669
  workflowFile,
640
670
  mcpConfigured,
641
671
  agentLaunched,
672
+ compiled: compileResult?.success,
642
673
  });
643
674
  }
644
675
  catch (err) {
@@ -47,6 +47,8 @@ export declare function detectTools(deps: McpSetupDeps): Promise<DetectedTool[]>
47
47
  export interface McpSetupFromInitResult {
48
48
  configured: string[];
49
49
  failed: string[];
50
+ /** Full detection results for each tool (used by init for transparent feedback) */
51
+ detected: DetectedTool[];
50
52
  /** Tool IDs that can be spawned as interactive CLI sessions (e.g. claude, codex) */
51
53
  cliTools: ToolId[];
52
54
  /** Tool IDs that are GUI-only editors (e.g. cursor, vscode, windsurf) */
@@ -57,6 +59,11 @@ export interface McpSetupFromInitResult {
57
59
  * Used by the init command after the user has already consented.
58
60
  */
59
61
  export declare function runMcpSetupFromInit(deps?: McpSetupDeps): Promise<McpSetupFromInitResult>;
62
+ /**
63
+ * Check which CLI agent tools are available on PATH.
64
+ * Lightweight: only runs `which` for known CLI binaries.
65
+ */
66
+ export declare function detectCliTools(deps?: McpSetupDeps): Promise<ToolId[]>;
60
67
  export declare function mcpSetupCommand(options: McpSetupOptions, deps?: McpSetupDeps): Promise<void>;
61
68
  export {};
62
69
  //# sourceMappingURL=mcp-setup.d.ts.map
@@ -303,7 +303,22 @@ export async function runMcpSetupFromInit(deps) {
303
303
  .map((t) => t.id);
304
304
  const cliTools = allConfiguredIds.filter((id) => CLI_TOOL_IDS.has(id));
305
305
  const guiTools = allConfiguredIds.filter((id) => !CLI_TOOL_IDS.has(id));
306
- return { configured, failed, cliTools, guiTools };
306
+ return { configured, failed, detected, cliTools, guiTools };
307
+ }
308
+ // ── Quick CLI tool detection (no config, just binary check) ──────────────────
309
+ /**
310
+ * Check which CLI agent tools are available on PATH.
311
+ * Lightweight: only runs `which` for known CLI binaries.
312
+ */
313
+ export async function detectCliTools(deps) {
314
+ const d = deps ?? defaultDeps();
315
+ const results = [];
316
+ for (const [id, binary] of Object.entries(CLI_TOOL_BINARY)) {
317
+ if (binary && await binaryExists(binary, d)) {
318
+ results.push(id);
319
+ }
320
+ }
321
+ return results;
307
322
  }
308
323
  // ── Command ──────────────────────────────────────────────────────────────────
309
324
  export async function mcpSetupCommand(options, deps) {