@synergenius/flow-weaver 0.17.4 → 0.17.6

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.
@@ -37,7 +37,7 @@ export { type ParseResult, parseWorkflow } from './parse.js';
37
37
  export { transformWorkflow } from './transform.js';
38
38
  export { type ValidationResult, validateWorkflow } from './validate.js';
39
39
  export { validationRuleRegistry } from './validation-registry.js';
40
- export * from './manipulation.js';
40
+ export * from './manipulation/index.js';
41
41
  export { withValidation, withMinimalValidation, withoutValidation, type RemoveOptions, type NodeFilter, type OperationResult, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeTypeExists, assertNodeExists, assertNodeNotExists, } from './helpers.js';
42
42
  export * from './query.js';
43
43
  export * from './builder.js';
package/dist/api/index.js CHANGED
@@ -36,7 +36,7 @@ export { parseWorkflow } from './parse.js';
36
36
  export { transformWorkflow } from './transform.js';
37
37
  export { validateWorkflow } from './validate.js';
38
38
  export { validationRuleRegistry } from './validation-registry.js';
39
- export * from './manipulation.js';
39
+ export * from './manipulation/index.js';
40
40
  export { withValidation, withMinimalValidation, withoutValidation, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeTypeExists, assertNodeExists, assertNodeNotExists, } from './helpers.js';
41
41
  export * from './query.js';
42
42
  export * from './builder.js';
@@ -24,7 +24,7 @@
24
24
  * - `withMinimalValidation(workflow)` - Skip expensive checks
25
25
  * - `withoutValidation(workflow)` - No validation (use with caution)
26
26
  */
27
- export { withoutValidation, type RemoveOptions, type NodeFilter, type OperationResult, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeExists, assertNodeNotExists, } from "./validation.js";
27
+ export { withoutValidation, type RemoveOptions, type NodeFilter, type OperationResult, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeExists, assertNodeNotExists, } from "../helpers.js";
28
28
  export { cloneWorkflow, setWorkflowDescription, setWorkflowMetadata, setOutputFileType, renameWorkflow, setWorkflowPorts, } from "./workflow.js";
29
29
  export { addNodeType, removeNodeType, updateNodeType, getNodeType, hasNodeType, listNodeTypes, renameNodeType, replaceNodeTypes, } from "./node-types.js";
30
30
  export { addNode, removeNode, renameNode, updateNode, addNodes, removeNodes, setNodeConfig, setNodePosition, setNodeMinimized, setNodeSize, setNodeLabel, } from "./nodes.js";
@@ -25,7 +25,7 @@
25
25
  * - `withoutValidation(workflow)` - No validation (use with caution)
26
26
  */
27
27
  // Re-export validation utilities
28
- export { withoutValidation, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeExists, assertNodeNotExists, } from "./validation.js";
28
+ export { withoutValidation, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeExists, assertNodeNotExists, } from "../helpers.js";
29
29
  // Re-export workflow-level operations
30
30
  export { cloneWorkflow, setWorkflowDescription, setWorkflowMetadata, setOutputFileType, renameWorkflow, setWorkflowPorts, } from "./workflow.js";
31
31
  // Re-export node type operations
@@ -321,23 +321,6 @@ export type TPortConfig = {
321
321
  type: 'all' | 'any' | 'expression';
322
322
  expression?: string;
323
323
  };
324
- /**
325
- * Legacy field - use `constant` instead
326
- * @deprecated Use `constant` with type and value instead
327
- */
328
- evaluateConstantAs?: {
329
- type: string;
330
- expression?: string;
331
- value?: TSerializableValue;
332
- };
333
- /**
334
- * Legacy field - use `executionSignal` instead
335
- * @deprecated Use `executionSignal` with type and expression instead
336
- */
337
- evaluateExecutionSignalAs?: {
338
- type: string;
339
- expression?: string;
340
- };
341
324
  };
342
325
  /**
343
326
  * Instance-specific configuration that can override node type defaults
@@ -397,15 +380,9 @@ export type TNodeInstanceAST = {
397
380
  sourceLocation?: TSourceLocation;
398
381
  /** Reserved for plugin extensibility */
399
382
  metadata?: TNodeMetadata;
400
- /**
401
- * CI/CD job group this node belongs to (from [job: "name"] attribute).
402
- * @deprecated Use `deploy?.['cicd']?.job` instead. Kept for backwards compatibility.
403
- */
383
+ /** CI/CD job group this node belongs to (from [job: "name"] attribute). */
404
384
  job?: string;
405
- /**
406
- * CI/CD environment for this node's job (from [environment: "name"] attribute).
407
- * @deprecated Use `deploy?.['cicd']?.environment` instead. Kept for backwards compatibility.
408
- */
385
+ /** CI/CD environment for this node's job (from [environment: "name"] attribute). */
409
386
  environment?: string;
410
387
  /** Per-target deploy config contributed by packs (e.g., deploy['cicd'].job) */
411
388
  deploy?: Record<string, Record<string, unknown>>;
@@ -454,10 +431,7 @@ export type TWorkflowOptions = {
454
431
  limit: number;
455
432
  period?: string;
456
433
  };
457
- /**
458
- * CI/CD pipeline configuration from @secret, @cache, @artifact, etc.
459
- * @deprecated Use `deploy?.['cicd']` instead. Kept for backwards compatibility.
460
- */
434
+ /** CI/CD pipeline configuration from @secret, @cache, @artifact, etc. */
461
435
  cicd?: TCICDOptions;
462
436
  /** Target-specific config (e.g., deploy['github-actions'].runner) */
463
437
  deploy?: Record<string, Record<string, unknown>>;
@@ -148,11 +148,8 @@ export function parseTriggerLine(input, warnings) {
148
148
  parserInstance.input = lexResult.tokens;
149
149
  const cst = parserInstance.triggerLine();
150
150
  if (parserInstance.errors.length > 0) {
151
- const firstError = parserInstance.errors[0];
152
- const truncatedInput = input.length > 60 ? input.substring(0, 60) + '...' : input;
153
- warnings.push(`Failed to parse trigger line: "${truncatedInput}"\n` +
154
- ` Error: ${firstError.message}\n` +
155
- ` Expected format: @trigger event="name" or @trigger cron="expr"`);
151
+ // Don't warn here — return null so domain-specific handlers (e.g. CI/CD)
152
+ // get a chance to parse the trigger. The caller can warn if nothing handles it.
156
153
  return null;
157
154
  }
158
155
  const result = visitorInstance.visit(cst);
@@ -33,7 +33,7 @@ export async function migrateCommand(globPattern, options = {}) {
33
33
  const filePath = path.resolve(file);
34
34
  try {
35
35
  const sourceCode = fs.readFileSync(filePath, 'utf8');
36
- // Parse with current parser (backward-compatible — adds defaults for missing fields)
36
+ // Parse with current parser (adds defaults for missing fields)
37
37
  const parseResult = await parseWorkflow(filePath);
38
38
  if (parseResult.errors.length > 0) {
39
39
  logger.error(` ${file}: parse errors — skipping`);
@@ -17051,13 +17051,6 @@ function parseTriggerLine(input, warnings) {
17051
17051
  parserInstance8.input = lexResult.tokens;
17052
17052
  const cst = parserInstance8.triggerLine();
17053
17053
  if (parserInstance8.errors.length > 0) {
17054
- const firstError = parserInstance8.errors[0];
17055
- const truncatedInput = input.length > 60 ? input.substring(0, 60) + "..." : input;
17056
- warnings.push(
17057
- `Failed to parse trigger line: "${truncatedInput}"
17058
- Error: ${firstError.message}
17059
- Expected format: @trigger event="name" or @trigger cron="expr"`
17060
- );
17061
17054
  return null;
17062
17055
  }
17063
17056
  const result = visitorInstance8.visit(cst);
@@ -17574,54 +17567,6 @@ var init_grammar_diagrams = __esm({
17574
17567
  }
17575
17568
  });
17576
17569
 
17577
- // src/extensions/cicd/detection.ts
17578
- function isCICDWorkflow(ast) {
17579
- const cicd = ast.options?.cicd;
17580
- if (cicd) {
17581
- if (cicd.secrets && cicd.secrets.length > 0) return true;
17582
- if (cicd.runner) return true;
17583
- if (cicd.caches && cicd.caches.length > 0) return true;
17584
- if (cicd.artifacts && cicd.artifacts.length > 0) return true;
17585
- if (cicd.environments && cicd.environments.length > 0) return true;
17586
- if (cicd.matrix) return true;
17587
- if (cicd.services && cicd.services.length > 0) return true;
17588
- if (cicd.concurrency) return true;
17589
- if (cicd.triggers && cicd.triggers.length > 0) return true;
17590
- if (cicd.jobs && cicd.jobs.length > 0) return true;
17591
- if (cicd.variables && Object.keys(cicd.variables).length > 0) return true;
17592
- if (cicd.beforeScript && cicd.beforeScript.length > 0) return true;
17593
- if (cicd.tags && cicd.tags.length > 0) return true;
17594
- if (cicd.includes && cicd.includes.length > 0) return true;
17595
- if (cicd.stages && cicd.stages.length > 0) return true;
17596
- }
17597
- if (ast.instances.some((inst) => inst.job)) return true;
17598
- return false;
17599
- }
17600
- function getJobNames(ast) {
17601
- const jobs = /* @__PURE__ */ new Set();
17602
- for (const inst of ast.instances) {
17603
- if (inst.job) jobs.add(inst.job);
17604
- }
17605
- return Array.from(jobs);
17606
- }
17607
- function getDeclaredSecrets(ast) {
17608
- return (ast.options?.cicd?.secrets || []).map((s) => s.name);
17609
- }
17610
- function getReferencedSecrets(ast) {
17611
- const secrets = /* @__PURE__ */ new Set();
17612
- for (const conn of ast.connections) {
17613
- if (conn.from.node.startsWith("secret:")) {
17614
- secrets.add(conn.from.node.substring(7));
17615
- }
17616
- }
17617
- return Array.from(secrets);
17618
- }
17619
- var init_detection = __esm({
17620
- "src/extensions/cicd/detection.ts"() {
17621
- "use strict";
17622
- }
17623
- });
17624
-
17625
17570
  // src/generator/compile-target-registry.ts
17626
17571
  var CompileTargetRegistry, compileTargetRegistry;
17627
17572
  var init_compile_target_registry = __esm({
@@ -25614,7 +25559,7 @@ var VERSION2;
25614
25559
  var init_generated_version = __esm({
25615
25560
  "src/generated-version.ts"() {
25616
25561
  "use strict";
25617
- VERSION2 = "0.17.4";
25562
+ VERSION2 = "0.17.6";
25618
25563
  }
25619
25564
  });
25620
25565
 
@@ -35966,6 +35911,12 @@ var init_jsdoc_parser = __esm({
35966
35911
  const comment = (tag.getCommentText() || "").trim();
35967
35912
  const result = parseTriggerLine(`@trigger ${comment}`, warnings);
35968
35913
  if (result) {
35914
+ const cicdKeywords = ["push", "pull_request", "dispatch", "tag", "schedule"];
35915
+ if (result.event && cicdKeywords.includes(result.event)) {
35916
+ warnings.push(
35917
+ `@trigger event="${result.event}" is treated as an Inngest event trigger, not a CI/CD trigger. For CI/CD, use: @trigger ${result.event}`
35918
+ );
35919
+ }
35969
35920
  config2.trigger = config2.trigger || {};
35970
35921
  if (result.event) config2.trigger.event = result.event;
35971
35922
  if (result.cron) config2.trigger.cron = result.cron;
@@ -36680,7 +36631,8 @@ var init_parser2 = __esm({
36680
36631
  nodeTypes.push(...inferredNodeTypes);
36681
36632
  const workflows = this.extractWorkflows(sourceFile, nodeTypes, filePath, errors2, warnings);
36682
36633
  const patterns = this.extractPatterns(sourceFile, nodeTypes, filePath, errors2, warnings);
36683
- const result = { workflows, nodeTypes, patterns, errors: errors2, warnings };
36634
+ const dedupedWarnings = [...new Set(warnings)];
36635
+ const result = { workflows, nodeTypes, patterns, errors: errors2, warnings: dedupedWarnings };
36684
36636
  this.project.removeSourceFile(sourceFile);
36685
36637
  if (!externalNodeTypes?.length) {
36686
36638
  this.parseCache.set(filePath, {
@@ -36720,12 +36672,13 @@ var init_parser2 = __esm({
36720
36672
  const workflows = this.extractWorkflows(sourceFile, nodeTypes, virtualPath, errors2, warnings);
36721
36673
  const patterns = this.extractPatterns(sourceFile, nodeTypes, virtualPath, errors2, warnings);
36722
36674
  this.project.removeSourceFile(sourceFile);
36675
+ const dedupedWarnings = [...new Set(warnings)];
36723
36676
  return {
36724
36677
  workflows,
36725
36678
  nodeTypes,
36726
36679
  patterns,
36727
36680
  errors: errors2,
36728
- warnings
36681
+ warnings: dedupedWarnings
36729
36682
  };
36730
36683
  }
36731
36684
  clearCache() {
@@ -42008,14 +41961,6 @@ var init_helpers2 = __esm({
42008
41961
  }
42009
41962
  });
42010
41963
 
42011
- // src/api/manipulation/validation.ts
42012
- var init_validation = __esm({
42013
- "src/api/manipulation/validation.ts"() {
42014
- "use strict";
42015
- init_helpers2();
42016
- }
42017
- });
42018
-
42019
41964
  // src/api/manipulation/workflow.ts
42020
41965
  var init_workflow = __esm({
42021
41966
  "src/api/manipulation/workflow.ts"() {
@@ -42395,7 +42340,7 @@ var init_scopes = __esm({
42395
42340
  var init_manipulation = __esm({
42396
42341
  "src/api/manipulation/index.ts"() {
42397
42342
  "use strict";
42398
- init_validation();
42343
+ init_helpers2();
42399
42344
  init_workflow();
42400
42345
  init_node_types();
42401
42346
  init_nodes();
@@ -42405,14 +42350,6 @@ var init_manipulation = __esm({
42405
42350
  }
42406
42351
  });
42407
42352
 
42408
- // src/api/manipulation.ts
42409
- var init_manipulation2 = __esm({
42410
- "src/api/manipulation.ts"() {
42411
- "use strict";
42412
- init_manipulation();
42413
- }
42414
- });
42415
-
42416
42353
  // src/api/query.ts
42417
42354
  function getMainFlowConnections(ast) {
42418
42355
  return ast.connections.filter((conn) => {
@@ -42988,7 +42925,7 @@ var init_api6 = __esm({
42988
42925
  init_transform();
42989
42926
  init_validate();
42990
42927
  init_validation_registry();
42991
- init_manipulation2();
42928
+ init_manipulation();
42992
42929
  init_helpers2();
42993
42930
  init_query();
42994
42931
  init_builder();
@@ -71354,7 +71291,7 @@ export const functionRegistry = {
71354
71291
  instances = /* @__PURE__ */ new Map();
71355
71292
  /**
71356
71293
  * Register a target factory. The target is only instantiated on first use.
71357
- * Also accepts a pre-instantiated target for backwards compatibility.
71294
+ * Also accepts a pre-instantiated target.
71358
71295
  */
71359
71296
  register(nameOrTarget, factory) {
71360
71297
  if (typeof nameOrTarget === "string") {
@@ -71393,355 +71330,6 @@ export const functionRegistry = {
71393
71330
  }
71394
71331
  });
71395
71332
 
71396
- // src/extensions/cicd/base-target.ts
71397
- var NODE_ACTION_MAP, BaseCICDTarget;
71398
- var init_base_target = __esm({
71399
- "src/extensions/cicd/base-target.ts"() {
71400
- "use strict";
71401
- init_base();
71402
- NODE_ACTION_MAP = {
71403
- checkout: {
71404
- githubAction: "actions/checkout@v4",
71405
- gitlabScript: ['echo "Checkout handled by GitLab CI runner"'],
71406
- label: "Checkout code"
71407
- },
71408
- "setup-node": {
71409
- githubAction: "actions/setup-node@v4",
71410
- githubWith: { "node-version": "20" },
71411
- gitlabImage: "node:20",
71412
- label: "Setup Node.js"
71413
- },
71414
- "setup-python": {
71415
- githubAction: "actions/setup-python@v5",
71416
- githubWith: { "python-version": "3.12" },
71417
- gitlabImage: "python:3.12",
71418
- label: "Setup Python"
71419
- },
71420
- "npm-install": {
71421
- githubAction: void 0,
71422
- gitlabScript: ["npm ci"],
71423
- label: "Install dependencies"
71424
- },
71425
- "npm-test": {
71426
- githubAction: void 0,
71427
- gitlabScript: ["npm test"],
71428
- label: "Run tests"
71429
- },
71430
- "npm-build": {
71431
- githubAction: void 0,
71432
- gitlabScript: ["npm run build"],
71433
- label: "Build"
71434
- },
71435
- "docker-build": {
71436
- githubAction: "docker/build-push-action@v6",
71437
- githubWith: { push: "false" },
71438
- gitlabScript: ["docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA ."],
71439
- label: "Build Docker image"
71440
- },
71441
- "docker-push": {
71442
- githubAction: "docker/build-push-action@v6",
71443
- githubWith: { push: "true" },
71444
- gitlabScript: ["docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"],
71445
- label: "Push Docker image"
71446
- },
71447
- "docker-login": {
71448
- githubAction: "docker/login-action@v3",
71449
- gitlabScript: ['echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY'],
71450
- label: "Docker login"
71451
- },
71452
- "shell-command": {
71453
- githubAction: void 0,
71454
- gitlabScript: ['echo "TODO: Add shell command"'],
71455
- label: "Run command"
71456
- },
71457
- "deploy-ssh": {
71458
- githubAction: void 0,
71459
- gitlabScript: ['echo "TODO: Configure SSH deployment"'],
71460
- label: "Deploy via SSH"
71461
- },
71462
- "deploy-s3": {
71463
- githubAction: "aws-actions/configure-aws-credentials@v4",
71464
- gitlabScript: ["aws s3 sync dist/ s3://$S3_BUCKET/"],
71465
- label: "Deploy to S3"
71466
- },
71467
- "slack-notify": {
71468
- githubAction: "slackapi/slack-github-action@v1",
71469
- gitlabScript: [`curl -X POST -H 'Content-type: application/json' --data '{"text":"Pipeline complete"}' $SLACK_WEBHOOK_URL`],
71470
- label: "Send Slack notification"
71471
- },
71472
- "health-check": {
71473
- githubAction: void 0,
71474
- gitlabScript: ["curl --retry 10 --retry-delay 5 --retry-all-errors $HEALTH_CHECK_URL"],
71475
- label: "Health check"
71476
- },
71477
- "wait-for-url": {
71478
- githubAction: void 0,
71479
- gitlabScript: ["for i in $(seq 1 30); do curl -sf $WAIT_URL && exit 0; sleep 10; done; exit 1"],
71480
- label: "Wait for URL"
71481
- }
71482
- };
71483
- BaseCICDTarget = class extends BaseExportTarget {
71484
- async generateMultiWorkflow(_workflows, _options) {
71485
- throw new Error("CI/CD targets use generate() with AST, not generateMultiWorkflow()");
71486
- }
71487
- async generateNodeTypeService(_nodeTypes, _options) {
71488
- throw new Error("CI/CD targets do not export node types as services");
71489
- }
71490
- async generateBundle(_workflows, _nodeTypes, _options) {
71491
- throw new Error("CI/CD targets use generate() with AST, not generateBundle()");
71492
- }
71493
- // ---------------------------------------------------------------------------
71494
- // Shared CI/CD Logic
71495
- // ---------------------------------------------------------------------------
71496
- resolveActionMapping(step, targetName) {
71497
- const deployConfig = step.nodeTypeDeploy?.[targetName];
71498
- if (deployConfig) {
71499
- return {
71500
- githubAction: deployConfig.action,
71501
- githubWith: deployConfig.with ? typeof deployConfig.with === "string" ? JSON.parse(deployConfig.with) : deployConfig.with : void 0,
71502
- gitlabScript: deployConfig.script ? Array.isArray(deployConfig.script) ? deployConfig.script : [deployConfig.script] : void 0,
71503
- gitlabImage: deployConfig.image,
71504
- label: deployConfig.label || step.name
71505
- };
71506
- }
71507
- return NODE_ACTION_MAP[step.nodeType] || NODE_ACTION_MAP[step.nodeType.replace(/([A-Z])/g, "-$1").toLowerCase()];
71508
- }
71509
- buildJobGraph(ast) {
71510
- const nodeTypeLookup = /* @__PURE__ */ new Map();
71511
- for (const nt of ast.nodeTypes) {
71512
- nodeTypeLookup.set(nt.name, nt);
71513
- if (nt.functionName !== nt.name) nodeTypeLookup.set(nt.functionName, nt);
71514
- }
71515
- const jobMap = /* @__PURE__ */ new Map();
71516
- const defaultRunner = ast.options?.cicd?.runner;
71517
- for (const inst of ast.instances) {
71518
- const jobName = inst.job || "default";
71519
- if (!jobMap.has(jobName)) jobMap.set(jobName, []);
71520
- jobMap.get(jobName).push(inst);
71521
- }
71522
- const nodeJob = /* @__PURE__ */ new Map();
71523
- for (const inst of ast.instances) {
71524
- nodeJob.set(inst.id, inst.job || "default");
71525
- }
71526
- const jobDeps = /* @__PURE__ */ new Map();
71527
- for (const conn of ast.connections) {
71528
- if (conn.from.node.startsWith("secret:")) continue;
71529
- if (conn.from.node === "Start" || conn.to.node === "Exit") continue;
71530
- const fromJob = nodeJob.get(conn.from.node);
71531
- const toJob = nodeJob.get(conn.to.node);
71532
- if (fromJob && toJob && fromJob !== toJob) {
71533
- if (!jobDeps.has(toJob)) jobDeps.set(toJob, /* @__PURE__ */ new Set());
71534
- jobDeps.get(toJob).add(fromJob);
71535
- }
71536
- }
71537
- const jobs = [];
71538
- for (const [jobId, instances] of jobMap) {
71539
- const environment = instances.find((i) => i.environment)?.environment;
71540
- const steps = instances.map((inst) => {
71541
- const nt = nodeTypeLookup.get(inst.nodeType);
71542
- return {
71543
- id: inst.id,
71544
- name: inst.config?.label || inst.id,
71545
- nodeType: inst.nodeType,
71546
- ...nt?.deploy && { nodeTypeDeploy: nt.deploy }
71547
- };
71548
- });
71549
- const needs = jobDeps.get(jobId) ? Array.from(jobDeps.get(jobId)) : [];
71550
- jobs.push({
71551
- id: jobId,
71552
- name: jobId,
71553
- runner: defaultRunner,
71554
- needs,
71555
- steps,
71556
- environment,
71557
- secrets: []
71558
- });
71559
- }
71560
- const jobConfigs = ast.options?.cicd?.jobs;
71561
- if (jobConfigs) {
71562
- for (const jc of jobConfigs) {
71563
- const job = jobs.find((j) => j.id === jc.id);
71564
- if (!job) continue;
71565
- if (jc.retry !== void 0) job.retry = jc.retry;
71566
- if (jc.allowFailure !== void 0) job.allowFailure = jc.allowFailure;
71567
- if (jc.timeout) job.timeout = jc.timeout;
71568
- if (jc.variables) job.variables = { ...job.variables, ...jc.variables };
71569
- if (jc.tags) job.tags = jc.tags;
71570
- if (jc.beforeScript) job.beforeScript = jc.beforeScript;
71571
- if (jc.rules) job.rules = jc.rules;
71572
- if (jc.coverage) job.coverage = jc.coverage;
71573
- if (jc.reports) job.reports = jc.reports;
71574
- if (jc.runner) job.runner = jc.runner;
71575
- if (jc.extends) job.extends = jc.extends;
71576
- }
71577
- }
71578
- const stages = ast.options?.cicd?.stages;
71579
- if (stages && stages.length > 0) {
71580
- const depthMap = this.computeJobDepths(jobs);
71581
- for (const job of jobs) {
71582
- if (!job.stage) {
71583
- for (const s of stages) {
71584
- if (job.id === s.name || job.id.startsWith(s.name + "-") || job.id.startsWith(s.name + "_")) {
71585
- job.stage = s.name;
71586
- break;
71587
- }
71588
- }
71589
- }
71590
- }
71591
- for (const job of jobs) {
71592
- if (!job.stage) {
71593
- const depth = depthMap.get(job.id) || 0;
71594
- job.stage = stages[Math.min(depth, stages.length - 1)].name;
71595
- }
71596
- }
71597
- }
71598
- const cicd = ast.options?.cicd;
71599
- if (cicd) {
71600
- for (const job of jobs) {
71601
- if (cicd.variables && !job.variables) {
71602
- job.variables = { ...cicd.variables };
71603
- }
71604
- if (cicd.beforeScript && !job.beforeScript) {
71605
- job.beforeScript = [...cicd.beforeScript];
71606
- }
71607
- if (cicd.tags && !job.tags) {
71608
- job.tags = [...cicd.tags];
71609
- }
71610
- }
71611
- }
71612
- return this.topoSortJobs(jobs);
71613
- }
71614
- topoSortJobs(jobs) {
71615
- const jobMap = new Map(jobs.map((j) => [j.id, j]));
71616
- const visited = /* @__PURE__ */ new Set();
71617
- const sorted = [];
71618
- function visit(id) {
71619
- if (visited.has(id)) return;
71620
- visited.add(id);
71621
- const job = jobMap.get(id);
71622
- if (!job) return;
71623
- for (const dep of job.needs) {
71624
- visit(dep);
71625
- }
71626
- sorted.push(job);
71627
- }
71628
- for (const job of jobs) {
71629
- visit(job.id);
71630
- }
71631
- return sorted;
71632
- }
71633
- computeJobDepths(jobs) {
71634
- const depths = /* @__PURE__ */ new Map();
71635
- function depth(jobId, visited) {
71636
- if (depths.has(jobId)) return depths.get(jobId);
71637
- if (visited.has(jobId)) return 0;
71638
- visited.add(jobId);
71639
- const job = jobs.find((j) => j.id === jobId);
71640
- if (!job || job.needs.length === 0) {
71641
- depths.set(jobId, 0);
71642
- return 0;
71643
- }
71644
- const maxDep = Math.max(...job.needs.map((n) => depth(n, visited)));
71645
- const d = maxDep + 1;
71646
- depths.set(jobId, d);
71647
- return d;
71648
- }
71649
- for (const job of jobs) {
71650
- depth(job.id, /* @__PURE__ */ new Set());
71651
- }
71652
- return depths;
71653
- }
71654
- resolveJobSecrets(jobs, ast, renderSecretRef) {
71655
- const nodeJob = /* @__PURE__ */ new Map();
71656
- for (const inst of ast.instances) {
71657
- nodeJob.set(inst.id, inst.job || "default");
71658
- }
71659
- const stepMap = /* @__PURE__ */ new Map();
71660
- for (const job of jobs) {
71661
- for (const step of job.steps) {
71662
- stepMap.set(step.id, step);
71663
- }
71664
- }
71665
- for (const conn of ast.connections) {
71666
- if (!conn.from.node.startsWith("secret:")) continue;
71667
- const secretName = conn.from.node.substring(7);
71668
- const targetNode = conn.to.node;
71669
- const targetPort = conn.to.port;
71670
- const jobId = nodeJob.get(targetNode);
71671
- if (!jobId) continue;
71672
- const job = jobs.find((j) => j.id === jobId);
71673
- if (!job) continue;
71674
- if (!job.secrets.includes(secretName)) {
71675
- job.secrets.push(secretName);
71676
- }
71677
- const step = stepMap.get(targetNode);
71678
- if (step) {
71679
- step.env = step.env || {};
71680
- step.env[targetPort.replace(/([A-Z])/g, "_$1").toUpperCase().replace(/^_/, "")] = renderSecretRef(secretName);
71681
- }
71682
- }
71683
- }
71684
- injectArtifactSteps(jobs, artifacts) {
71685
- if (artifacts.length === 0) return;
71686
- for (const job of jobs) {
71687
- if (job.needs.length === 0) continue;
71688
- const neededJobs = jobs.filter((j) => job.needs.includes(j.id));
71689
- for (const needed of neededJobs) {
71690
- const jobArtifacts = artifacts.filter(
71691
- (a) => !a.name || needed.steps.some((s) => s.nodeType === a.name)
71692
- );
71693
- if (jobArtifacts.length > 0) {
71694
- needed.uploadArtifacts = (needed.uploadArtifacts || []).concat(jobArtifacts);
71695
- job.downloadArtifacts = (job.downloadArtifacts || []).concat(
71696
- jobArtifacts.map((a) => a.name)
71697
- );
71698
- }
71699
- }
71700
- }
71701
- }
71702
- generateSecretsDoc(secrets, platform) {
71703
- if (secrets.length === 0) return "";
71704
- const lines = [
71705
- "# Secrets Setup Guide",
71706
- "",
71707
- `This workflow requires ${secrets.length} secret(s) to be configured.`,
71708
- ""
71709
- ];
71710
- for (const secret of secrets) {
71711
- lines.push(`## ${secret.name}`);
71712
- if (secret.description) {
71713
- lines.push(`> ${secret.description}`);
71714
- }
71715
- lines.push("");
71716
- if (platform === "github-actions" || secret.platform === "all" || secret.platform === "github" || !secret.platform) {
71717
- lines.push("**GitHub Actions:**");
71718
- lines.push("1. Go to your repository on GitHub");
71719
- lines.push("2. Navigate to Settings > Secrets and variables > Actions");
71720
- lines.push('3. Click "New repository secret"');
71721
- lines.push(`4. Name: \`${secret.name}\``);
71722
- lines.push('5. Paste your secret value and click "Add secret"');
71723
- lines.push("");
71724
- }
71725
- if (platform === "gitlab-ci" || secret.platform === "all" || secret.platform === "gitlab" || !secret.platform) {
71726
- lines.push("**GitLab CI:**");
71727
- lines.push("1. Go to your project on GitLab");
71728
- lines.push("2. Navigate to Settings > CI/CD > Variables");
71729
- lines.push('3. Click "Add variable"');
71730
- lines.push(`4. Key: \`${secret.name}\``);
71731
- lines.push("5. Paste your secret value");
71732
- lines.push('6. Check "Mask variable" and optionally "Protect variable"');
71733
- lines.push('7. Click "Add variable"');
71734
- lines.push("");
71735
- }
71736
- lines.push("---");
71737
- lines.push("");
71738
- }
71739
- return lines.join("\n");
71740
- }
71741
- };
71742
- }
71743
- });
71744
-
71745
71333
  // src/marketplace/registry.ts
71746
71334
  var registry_exports = {};
71747
71335
  __export(registry_exports, {
@@ -71897,7 +71485,6 @@ var init_registry = __esm({
71897
71485
  // src/deployment/index.ts
71898
71486
  var deployment_exports = {};
71899
71487
  __export(deployment_exports, {
71900
- BaseCICDTarget: () => BaseCICDTarget,
71901
71488
  BaseExportTarget: () => BaseExportTarget,
71902
71489
  CliRequestAdapter: () => CliRequestAdapter,
71903
71490
  DEFAULT_CONFIG: () => DEFAULT_CONFIG,
@@ -71905,7 +71492,6 @@ __export(deployment_exports, {
71905
71492
  DEFAULT_SERVER_CONFIG: () => DEFAULT_SERVER_CONFIG,
71906
71493
  ExportTargetRegistry: () => ExportTargetRegistry,
71907
71494
  HttpRequestAdapter: () => HttpRequestAdapter,
71908
- NODE_ACTION_MAP: () => NODE_ACTION_MAP,
71909
71495
  OpenAPIGenerator: () => OpenAPIGenerator,
71910
71496
  SchemaConverter: () => SchemaConverter,
71911
71497
  UnifiedWorkflowExecutor: () => UnifiedWorkflowExecutor,
@@ -71920,7 +71506,6 @@ __export(deployment_exports, {
71920
71506
  generateStandaloneRuntimeModule: () => generateStandaloneRuntimeModule,
71921
71507
  getConfigValue: () => getConfigValue,
71922
71508
  getDefaultConfig: () => getDefaultConfig,
71923
- isCICDWorkflow: () => isCICDWorkflow,
71924
71509
  loadConfig: () => loadConfig,
71925
71510
  loadConfigSync: () => loadConfigSync,
71926
71511
  schemaConverter: () => schemaConverter
@@ -71954,9 +71539,7 @@ var init_deployment = __esm({
71954
71539
  init_generator();
71955
71540
  init_schema_converter();
71956
71541
  init_base();
71957
- init_detection();
71958
71542
  init_inline_runtime();
71959
- init_base_target();
71960
71543
  init_base();
71961
71544
  }
71962
71545
  });
@@ -73513,11 +73096,50 @@ function parseCicdTrigger(text, d, warnings) {
73513
73096
  triggers.push(trigger);
73514
73097
  }
73515
73098
 
73516
- // src/extensions/cicd/register.ts
73517
- init_detection();
73099
+ // src/extensions/cicd/detection.ts
73100
+ function isCICDWorkflow(ast) {
73101
+ const cicd = ast.options?.cicd;
73102
+ if (cicd) {
73103
+ if (cicd.secrets && cicd.secrets.length > 0) return true;
73104
+ if (cicd.runner) return true;
73105
+ if (cicd.caches && cicd.caches.length > 0) return true;
73106
+ if (cicd.artifacts && cicd.artifacts.length > 0) return true;
73107
+ if (cicd.environments && cicd.environments.length > 0) return true;
73108
+ if (cicd.matrix) return true;
73109
+ if (cicd.services && cicd.services.length > 0) return true;
73110
+ if (cicd.concurrency) return true;
73111
+ if (cicd.triggers && cicd.triggers.length > 0) return true;
73112
+ if (cicd.jobs && cicd.jobs.length > 0) return true;
73113
+ if (cicd.variables && Object.keys(cicd.variables).length > 0) return true;
73114
+ if (cicd.beforeScript && cicd.beforeScript.length > 0) return true;
73115
+ if (cicd.tags && cicd.tags.length > 0) return true;
73116
+ if (cicd.includes && cicd.includes.length > 0) return true;
73117
+ if (cicd.stages && cicd.stages.length > 0) return true;
73118
+ }
73119
+ if (ast.instances.some((inst) => inst.job)) return true;
73120
+ return false;
73121
+ }
73122
+ function getJobNames(ast) {
73123
+ const jobs = /* @__PURE__ */ new Set();
73124
+ for (const inst of ast.instances) {
73125
+ if (inst.job) jobs.add(inst.job);
73126
+ }
73127
+ return Array.from(jobs);
73128
+ }
73129
+ function getDeclaredSecrets(ast) {
73130
+ return (ast.options?.cicd?.secrets || []).map((s) => s.name);
73131
+ }
73132
+ function getReferencedSecrets(ast) {
73133
+ const secrets = /* @__PURE__ */ new Set();
73134
+ for (const conn of ast.connections) {
73135
+ if (conn.from.node.startsWith("secret:")) {
73136
+ secrets.add(conn.from.node.substring(7));
73137
+ }
73138
+ }
73139
+ return Array.from(secrets);
73140
+ }
73518
73141
 
73519
73142
  // src/extensions/cicd/rules.ts
73520
- init_detection();
73521
73143
  var secretNotDeclaredRule = {
73522
73144
  name: "CICD_SECRET_NOT_DECLARED",
73523
73145
  validate(ast) {
@@ -103605,7 +103227,7 @@ function getRegisteredMigrations() {
103605
103227
  }
103606
103228
 
103607
103229
  // src/mcp/tools-pattern.ts
103608
- init_manipulation2();
103230
+ init_manipulation();
103609
103231
  init_query();
103610
103232
  init_parser2();
103611
103233
  var modifyParamsSchemas = {
@@ -109304,7 +108926,7 @@ function displayInstalledPackage(pkg) {
109304
108926
 
109305
108927
  // src/cli/index.ts
109306
108928
  init_error_utils();
109307
- var version2 = true ? "0.17.4" : "0.0.0-dev";
108929
+ var version2 = true ? "0.17.6" : "0.0.0-dev";
109308
108930
  var program2 = new Command();
109309
108931
  program2.name("flow-weaver").description("Flow Weaver Annotations - Compile and validate workflow files").option("-v, --version", "Output the current version").option("--no-color", "Disable colors").option("--color", "Force colors").on("option:version", () => {
109310
108932
  logger.banner(version2);
@@ -15,11 +15,7 @@ export { loadConfig, loadConfigSync, getConfigValue } from './config/loader.js';
15
15
  export { OpenAPIGenerator, generateOpenAPIJson, generateOpenAPIYaml, type OpenAPIDocument, type OpenAPIInfo, type OpenAPIServer, type GeneratorOptions, } from './openapi/generator.js';
16
16
  export { SchemaConverter, schemaConverter, type OpenAPISchema, } from './openapi/schema-converter.js';
17
17
  export { type ExportTarget, type ExportOptions, type ExportArtifacts, type GeneratedFile, type DeployInstructions, type DeploySchema, type DeploySchemaField, type CompiledWorkflow, type MultiWorkflowArtifacts, type NodeTypeInfo, type NodeTypeExportOptions, type NodeTypeArtifacts, type BundleWorkflow, type BundleNodeType, type BundleArtifacts, BaseExportTarget, ExportTargetRegistry, } from './targets/base.js';
18
- /** @deprecated Import from '@synergenius/flow-weaver/extensions/cicd' instead */
19
- export { isCICDWorkflow } from '../extensions/cicd/detection.js';
20
18
  export { generateStandaloneRuntimeModule } from '../api/inline-runtime.js';
21
- /** @deprecated Import from '@synergenius/flow-weaver/extensions/cicd' instead */
22
- export { BaseCICDTarget, NODE_ACTION_MAP, type CICDStep, type CICDJob, type ActionMapping, } from '../extensions/cicd/base-target.js';
23
19
  import { ExportTargetRegistry } from './targets/base.js';
24
20
  /**
25
21
  * Create an export target registry via marketplace discovery.
@@ -18,12 +18,7 @@ export { OpenAPIGenerator, generateOpenAPIJson, generateOpenAPIYaml, } from './o
18
18
  export { SchemaConverter, schemaConverter, } from './openapi/schema-converter.js';
19
19
  // Export Targets
20
20
  export { BaseExportTarget, ExportTargetRegistry, } from './targets/base.js';
21
- // Utilities needed by export target packs
22
- /** @deprecated Import from '@synergenius/flow-weaver/extensions/cicd' instead */
23
- export { isCICDWorkflow } from '../extensions/cicd/detection.js';
24
21
  export { generateStandaloneRuntimeModule } from '../api/inline-runtime.js';
25
- /** @deprecated Import from '@synergenius/flow-weaver/extensions/cicd' instead */
26
- export { BaseCICDTarget, NODE_ACTION_MAP, } from '../extensions/cicd/base-target.js';
27
22
  import * as path from 'path';
28
23
  import { pathToFileURL } from 'url';
29
24
  import { ExportTargetRegistry } from './targets/base.js';
@@ -331,7 +331,7 @@ export declare class ExportTargetRegistry {
331
331
  private instances;
332
332
  /**
333
333
  * Register a target factory. The target is only instantiated on first use.
334
- * Also accepts a pre-instantiated target for backwards compatibility.
334
+ * Also accepts a pre-instantiated target.
335
335
  */
336
336
  register(nameOrTarget: string | ExportTarget, factory?: () => ExportTarget): void;
337
337
  get(name: string): ExportTarget | undefined;
@@ -810,7 +810,7 @@ export class ExportTargetRegistry {
810
810
  instances = new Map();
811
811
  /**
812
812
  * Register a target factory. The target is only instantiated on first use.
813
- * Also accepts a pre-instantiated target for backwards compatibility.
813
+ * Also accepts a pre-instantiated target.
814
814
  */
815
815
  register(nameOrTarget, factory) {
816
816
  if (typeof nameOrTarget === 'string') {
@@ -25,7 +25,5 @@ export declare function portBadgeWidth(port: DiagramPort): number;
25
25
  export declare function computeNodeDimensions(node: DiagramNode): void;
26
26
  export declare function computePortPositions(node: DiagramNode): void;
27
27
  export declare function computeConnectionPath(sx: number, sy: number, tx: number, ty: number): string;
28
- /** @deprecated Use computeConnectionPath instead */
29
- export declare function computeBezierPath(sx: number, sy: number, tx: number, ty: number): string;
30
28
  export declare function buildDiagramGraph(ast: TWorkflowAST, options?: DiagramOptions): DiagramGraph;
31
29
  //# sourceMappingURL=geometry.d.ts.map
@@ -137,10 +137,6 @@ export function computeConnectionPath(sx, sy, tx, ty) {
137
137
  path += ` L ${hx},${hy}`;
138
138
  return path;
139
139
  }
140
- /** @deprecated Use computeConnectionPath instead */
141
- export function computeBezierPath(sx, sy, tx, ty) {
142
- return computeConnectionPath(sx, sy, tx, ty);
143
- }
144
140
  // ---- Port ordering helpers ----
145
141
  /**
146
142
  * Get ordered ports from a port definition record using metadata.order.
@@ -3,7 +3,12 @@
3
3
  *
4
4
  * Re-exports detection, base target, and validation rule utilities
5
5
  * for consumers importing from `@synergenius/flow-weaver/extensions/cicd`.
6
+ *
7
+ * The register import is a side effect that populates the global tag handler
8
+ * registry with CI/CD handlers. Without it, parseWorkflow() silently drops
9
+ * all CI/CD annotations (@runner, @stage, @job, @variables, etc.).
6
10
  */
11
+ import './register.js';
7
12
  export { isCICDWorkflow, getJobNames, getDeclaredSecrets, getReferencedSecrets } from './detection.js';
8
13
  export { BaseCICDTarget, NODE_ACTION_MAP, type CICDJob, type CICDStep, type ActionMapping } from './base-target.js';
9
14
  export { getCICDValidationRules } from './rules.js';
@@ -3,7 +3,12 @@
3
3
  *
4
4
  * Re-exports detection, base target, and validation rule utilities
5
5
  * for consumers importing from `@synergenius/flow-weaver/extensions/cicd`.
6
+ *
7
+ * The register import is a side effect that populates the global tag handler
8
+ * registry with CI/CD handlers. Without it, parseWorkflow() silently drops
9
+ * all CI/CD annotations (@runner, @stage, @job, @variables, etc.).
6
10
  */
11
+ import './register.js';
7
12
  export { isCICDWorkflow, getJobNames, getDeclaredSecrets, getReferencedSecrets } from './detection.js';
8
13
  export { BaseCICDTarget, NODE_ACTION_MAP } from './base-target.js';
9
14
  export { getCICDValidationRules } from './rules.js';
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.17.4";
1
+ export declare const VERSION = "0.17.6";
2
2
  //# sourceMappingURL=generated-version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by scripts/generate-version.ts — do not edit manually
2
- export const VERSION = '0.17.4';
2
+ export const VERSION = '0.17.6';
3
3
  //# sourceMappingURL=generated-version.js.map
@@ -39,7 +39,7 @@ export function shouldWorkflowBeAsync(workflow, nodeTypes) {
39
39
  */
40
40
  export function validateWorkflowAsync(workflow, nodeTypes) {
41
41
  const computedAsync = shouldWorkflowBeAsync(workflow, nodeTypes);
42
- const userAsync = workflow.userSpecifiedAsync ?? true; // Default to async for backwards compat
42
+ const userAsync = workflow.userSpecifiedAsync ?? true;
43
43
  if (!userAsync && computedAsync) {
44
44
  // User wrote sync function, but workflow contains async nodes
45
45
  return {
@@ -49,7 +49,7 @@ export type TBuildNodeArgsOptions = {
49
49
  *
50
50
  * ## Resolution Priority (per port):
51
51
  * 1. **Skip Ports**: If port is in skipPorts set, use pre-declared variable
52
- * 2. **Instance Expression**: Check instance.config.portConfigs for evaluateConstantAs
52
+ * 2. **Instance Expression**: Check instance.config.portConfigs for constant expressions
53
53
  * 3. **Connection**: Get value from connected output port via ctx.getVariable()
54
54
  * 4. **Node Type Expression**: Check nodeType.inputs[port].expression
55
55
  * 5. **Default Value**: Use nodeType.inputs[port].default if available
@@ -64,7 +64,7 @@ export type TBuildNodeArgsOptions = {
64
64
  * ## STEP Port Execution Strategies:
65
65
  * - **CONJUNCTION (AND)**: `execute = stepA && stepB && stepC`
66
66
  * - **DISJUNCTION (OR)**: `execute = stepA || stepB || stepC`
67
- * - **CUSTOM**: Uses evaluateExecutionSignalAs expression
67
+ * - **CUSTOM**: Uses executionSignal expression
68
68
  *
69
69
  * @param opts - Configuration object with node, workflow, and generation settings
70
70
  * @param opts.node - The node type definition with input/output port specs
@@ -114,7 +114,7 @@ export function buildMergeExpression(sources, strategy) {
114
114
  *
115
115
  * ## Resolution Priority (per port):
116
116
  * 1. **Skip Ports**: If port is in skipPorts set, use pre-declared variable
117
- * 2. **Instance Expression**: Check instance.config.portConfigs for evaluateConstantAs
117
+ * 2. **Instance Expression**: Check instance.config.portConfigs for constant expressions
118
118
  * 3. **Connection**: Get value from connected output port via ctx.getVariable()
119
119
  * 4. **Node Type Expression**: Check nodeType.inputs[port].expression
120
120
  * 5. **Default Value**: Use nodeType.inputs[port].default if available
@@ -129,7 +129,7 @@ export function buildMergeExpression(sources, strategy) {
129
129
  * ## STEP Port Execution Strategies:
130
130
  * - **CONJUNCTION (AND)**: `execute = stepA && stepB && stepC`
131
131
  * - **DISJUNCTION (OR)**: `execute = stepA || stepB || stepC`
132
- * - **CUSTOM**: Uses evaluateExecutionSignalAs expression
132
+ * - **CUSTOM**: Uses executionSignal expression
133
133
  *
134
134
  * @param opts - Configuration object with node, workflow, and generation settings
135
135
  * @param opts.node - The node type definition with input/output port specs
package/dist/index.d.ts CHANGED
@@ -79,7 +79,7 @@ export { generator, WorkflowGenerator } from './generator.js';
79
79
  export { AnnotationGenerator } from './annotation-generator.js';
80
80
  export type { GenerateAnnotationsOptions } from './annotation-generator.js';
81
81
  export * as GeneratorUtils from './generator.js';
82
- export { parsePortsFromFunctionText, updatePortsInFunctionText, formatPortsInFunctionText, syncCodeRenames, renamePortInCode, parseReturnTypeFields, parseFunctionSignature, parseReturnFields, } from './jsdoc-port-sync.js';
82
+ export { parsePortsFromFunctionText, updatePortsInFunctionText, formatPortsInFunctionText, syncCodeRenames, renamePortInCode, parseReturnTypeFields, parseFunctionSignature, parseReturnFields, } from './jsdoc-port-sync/index.js';
83
83
  export { workflowTemplates, nodeTemplates, getWorkflowTemplate, getNodeTemplate, toCamelCase, toPascalCase, } from './cli/templates/index.js';
84
84
  export type { WorkflowTemplate, NodeTemplate, WorkflowTemplateOptions } from './cli/templates/index.js';
85
85
  export { WorkflowDiffer } from './diff/WorkflowDiffer.js';
package/dist/index.js CHANGED
@@ -82,7 +82,7 @@ export { AnnotationGenerator } from './annotation-generator.js';
82
82
  // Generator Utilities (for advanced use)
83
83
  export * as GeneratorUtils from './generator.js';
84
84
  // JSDoc Port Sync (browser-compatible parsing/updating)
85
- export { parsePortsFromFunctionText, updatePortsInFunctionText, formatPortsInFunctionText, syncCodeRenames, renamePortInCode, parseReturnTypeFields, parseFunctionSignature, parseReturnFields, } from './jsdoc-port-sync.js';
85
+ export { parsePortsFromFunctionText, updatePortsInFunctionText, formatPortsInFunctionText, syncCodeRenames, renamePortInCode, parseReturnTypeFields, parseFunctionSignature, parseReturnFields, } from './jsdoc-port-sync/index.js';
86
86
  // Templates (for workflow/node creation)
87
87
  export { workflowTemplates, nodeTemplates, getWorkflowTemplate, getNodeTemplate, toCamelCase, toPascalCase, } from './cli/templates/index.js';
88
88
  // Diff (semantic comparison)
@@ -1055,6 +1055,12 @@ export class JSDocParser {
1055
1055
  // Try core FW trigger parsing first (event= and/or cron=)
1056
1056
  const result = parseTriggerLine(`@trigger ${comment}`, warnings);
1057
1057
  if (result) {
1058
+ // Warn if the event name matches a CI/CD trigger keyword (likely user error)
1059
+ const cicdKeywords = ['push', 'pull_request', 'dispatch', 'tag', 'schedule'];
1060
+ if (result.event && cicdKeywords.includes(result.event)) {
1061
+ warnings.push(`@trigger event="${result.event}" is treated as an Inngest event trigger, not a CI/CD trigger. ` +
1062
+ `For CI/CD, use: @trigger ${result.event}`);
1063
+ }
1058
1064
  // Merge: multiple @trigger tags accumulate (event + cron can be separate tags)
1059
1065
  config.trigger = config.trigger || {};
1060
1066
  if (result.event)
@@ -187,7 +187,7 @@ export function registerEditorTools(mcp, connection, buffer) {
187
187
  message: 'Workflow paused at waitForAgent node. Use fw_resume_workflow to continue.',
188
188
  });
189
189
  }
190
- // Completed without pausing return flat result for backward compatibility
190
+ // Completed without pausing, return flat result
191
191
  return makeToolResult(raceResult.result);
192
192
  }
193
193
  catch (err) {
@@ -7,7 +7,7 @@ import { listPatterns, applyPattern, findWorkflows, extractPattern } from '../ap
7
7
  import { generateInPlace } from '../api/generate-in-place.js';
8
8
  import { applyMigrations, getRegisteredMigrations } from '../migration/registry.js';
9
9
  import { describeWorkflow, formatDescribeOutput } from '../cli/commands/describe.js';
10
- import { addNode as manipAddNode, removeNode as manipRemoveNode, renameNode as manipRenameNode, addConnection as manipAddConnection, removeConnection as manipRemoveConnection, setNodePosition as manipSetNodePosition, setNodeLabel as manipSetNodeLabel, } from '../api/manipulation.js';
10
+ import { addNode as manipAddNode, removeNode as manipRemoveNode, renameNode as manipRenameNode, addConnection as manipAddConnection, removeConnection as manipRemoveConnection, setNodePosition as manipSetNodePosition, setNodeLabel as manipSetNodeLabel, } from '../api/manipulation/index.js';
11
11
  import { findIsolatedNodes } from '../api/query.js';
12
12
  import { AnnotationParser } from '../parser.js';
13
13
  import { makeToolResult, makeErrorResult, addHintsToItems } from './response-utils.js';
package/dist/parser.js CHANGED
@@ -187,7 +187,9 @@ export class AnnotationParser {
187
187
  nodeTypes.push(...inferredNodeTypes);
188
188
  const workflows = this.extractWorkflows(sourceFile, nodeTypes, filePath, errors, warnings);
189
189
  const patterns = this.extractPatterns(sourceFile, nodeTypes, filePath, errors, warnings);
190
- const result = { workflows, nodeTypes, patterns, errors, warnings };
190
+ // Deduplicate warnings (extractWorkflowSignatures + extractWorkflows both parse JSDoc)
191
+ const dedupedWarnings = [...new Set(warnings)];
192
+ const result = { workflows, nodeTypes, patterns, errors, warnings: dedupedWarnings };
191
193
  // Clean up source file to prevent ts-morph Project bloat
192
194
  // (results are captured in the returned AST, source file is no longer needed)
193
195
  this.project.removeSourceFile(sourceFile);
@@ -238,12 +240,14 @@ export class AnnotationParser {
238
240
  // Clean up virtual source file to prevent memory bloat
239
241
  // (tests create many unique virtual paths that accumulate)
240
242
  this.project.removeSourceFile(sourceFile);
243
+ // Deduplicate warnings (extractWorkflowSignatures + extractWorkflows both parse JSDoc)
244
+ const dedupedWarnings = [...new Set(warnings)];
241
245
  return {
242
246
  workflows,
243
247
  nodeTypes,
244
248
  patterns,
245
249
  errors,
246
- warnings,
250
+ warnings: dedupedWarnings,
247
251
  };
248
252
  }
249
253
  clearCache() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synergenius/flow-weaver",
3
- "version": "0.17.4",
3
+ "version": "0.17.6",
4
4
  "description": "Deterministic workflow compiler for AI agents. Compiles to standalone TypeScript, no runtime dependencies.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,6 +0,0 @@
1
- /**
2
- * Validation wrappers for workflow manipulation operations
3
- * Re-exports from helpers.ts for backward compatibility
4
- */
5
- export { withoutValidation, type RemoveOptions, type NodeFilter, type OperationResult, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeExists, assertNodeNotExists, } from "../helpers.js";
6
- //# sourceMappingURL=validation.d.ts.map
@@ -1,6 +0,0 @@
1
- /**
2
- * Validation wrappers for workflow manipulation operations
3
- * Re-exports from helpers.ts for backward compatibility
4
- */
5
- export { withoutValidation, validatePortReference, portReferencesEqual, formatPortReference, generateUniqueNodeId, assertNodeExists, assertNodeNotExists, } from "../helpers.js";
6
- //# sourceMappingURL=validation.js.map
@@ -1,8 +0,0 @@
1
- /**
2
- * Manipulation API for programmatic workflow creation and modification
3
- * All operations are immutable (return new AST) and validated
4
- *
5
- * This file re-exports all functions from the manipulation module for backward compatibility.
6
- */
7
- export * from "./manipulation/index.js";
8
- //# sourceMappingURL=manipulation.d.ts.map
@@ -1,8 +0,0 @@
1
- /**
2
- * Manipulation API for programmatic workflow creation and modification
3
- * All operations are immutable (return new AST) and validated
4
- *
5
- * This file re-exports all functions from the manipulation module for backward compatibility.
6
- */
7
- export * from "./manipulation/index.js";
8
- //# sourceMappingURL=manipulation.js.map
@@ -1,10 +0,0 @@
1
- /**
2
- * @module jsdoc-port-sync
3
- *
4
- * Re-exports from modular jsdoc-port-sync/ directory.
5
- * This file maintains backwards compatibility for existing imports.
6
- *
7
- * @see ./jsdoc-port-sync/index.ts for the modular implementation
8
- */
9
- export * from "./jsdoc-port-sync/index.js";
10
- //# sourceMappingURL=jsdoc-port-sync.d.ts.map
@@ -1,10 +0,0 @@
1
- /**
2
- * @module jsdoc-port-sync
3
- *
4
- * Re-exports from modular jsdoc-port-sync/ directory.
5
- * This file maintains backwards compatibility for existing imports.
6
- *
7
- * @see ./jsdoc-port-sync/index.ts for the modular implementation
8
- */
9
- export * from "./jsdoc-port-sync/index.js";
10
- //# sourceMappingURL=jsdoc-port-sync.js.map