@renseiai/agentfactory 0.8.12 → 0.8.13

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 (101) hide show
  1. package/dist/src/config/repository-config.d.ts +24 -0
  2. package/dist/src/config/repository-config.d.ts.map +1 -1
  3. package/dist/src/config/repository-config.js +21 -0
  4. package/dist/src/config/repository-config.test.js +202 -0
  5. package/dist/src/governor/decision-engine.d.ts +2 -0
  6. package/dist/src/governor/decision-engine.d.ts.map +1 -1
  7. package/dist/src/governor/decision-engine.js +7 -0
  8. package/dist/src/governor/decision-engine.test.js +63 -0
  9. package/dist/src/governor/governor-types.d.ts +2 -1
  10. package/dist/src/governor/governor-types.d.ts.map +1 -1
  11. package/dist/src/index.d.ts +1 -0
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/index.js +1 -0
  14. package/dist/src/merge-queue/conflict-resolver.d.ts +62 -0
  15. package/dist/src/merge-queue/conflict-resolver.d.ts.map +1 -0
  16. package/dist/src/merge-queue/conflict-resolver.js +168 -0
  17. package/dist/src/merge-queue/conflict-resolver.test.d.ts +2 -0
  18. package/dist/src/merge-queue/conflict-resolver.test.d.ts.map +1 -0
  19. package/dist/src/merge-queue/conflict-resolver.test.js +405 -0
  20. package/dist/src/merge-queue/lock-file-regeneration.d.ts +14 -0
  21. package/dist/src/merge-queue/lock-file-regeneration.d.ts.map +1 -0
  22. package/dist/src/merge-queue/lock-file-regeneration.js +82 -0
  23. package/dist/src/merge-queue/lock-file-regeneration.test.d.ts +2 -0
  24. package/dist/src/merge-queue/lock-file-regeneration.test.d.ts.map +1 -0
  25. package/dist/src/merge-queue/lock-file-regeneration.test.js +236 -0
  26. package/dist/src/merge-queue/merge-worker.d.ts +79 -0
  27. package/dist/src/merge-queue/merge-worker.d.ts.map +1 -0
  28. package/dist/src/merge-queue/merge-worker.js +221 -0
  29. package/dist/src/merge-queue/merge-worker.test.d.ts +2 -0
  30. package/dist/src/merge-queue/merge-worker.test.d.ts.map +1 -0
  31. package/dist/src/merge-queue/merge-worker.test.js +883 -0
  32. package/dist/src/merge-queue/strategies/index.d.ts +19 -0
  33. package/dist/src/merge-queue/strategies/index.d.ts.map +1 -0
  34. package/dist/src/merge-queue/strategies/index.js +30 -0
  35. package/dist/src/merge-queue/strategies/merge-commit-strategy.d.ts +14 -0
  36. package/dist/src/merge-queue/strategies/merge-commit-strategy.d.ts.map +1 -0
  37. package/dist/src/merge-queue/strategies/merge-commit-strategy.js +58 -0
  38. package/dist/src/merge-queue/strategies/rebase-strategy.d.ts +14 -0
  39. package/dist/src/merge-queue/strategies/rebase-strategy.d.ts.map +1 -0
  40. package/dist/src/merge-queue/strategies/rebase-strategy.js +62 -0
  41. package/dist/src/merge-queue/strategies/squash-strategy.d.ts +14 -0
  42. package/dist/src/merge-queue/strategies/squash-strategy.d.ts.map +1 -0
  43. package/dist/src/merge-queue/strategies/squash-strategy.js +59 -0
  44. package/dist/src/merge-queue/strategies/strategies.test.d.ts +2 -0
  45. package/dist/src/merge-queue/strategies/strategies.test.d.ts.map +1 -0
  46. package/dist/src/merge-queue/strategies/strategies.test.js +354 -0
  47. package/dist/src/merge-queue/strategies/types.d.ts +62 -0
  48. package/dist/src/merge-queue/strategies/types.d.ts.map +1 -0
  49. package/dist/src/merge-queue/strategies/types.js +7 -0
  50. package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -1
  51. package/dist/src/orchestrator/parse-work-result.js +22 -0
  52. package/dist/src/orchestrator/parse-work-result.test.js +49 -0
  53. package/dist/src/providers/index.d.ts +1 -0
  54. package/dist/src/providers/index.d.ts.map +1 -1
  55. package/dist/src/providers/plugin-types.d.ts +177 -0
  56. package/dist/src/providers/plugin-types.d.ts.map +1 -0
  57. package/dist/src/providers/plugin-types.js +10 -0
  58. package/dist/src/providers/plugin-types.test.d.ts +2 -0
  59. package/dist/src/providers/plugin-types.test.d.ts.map +1 -0
  60. package/dist/src/providers/plugin-types.test.js +810 -0
  61. package/dist/src/registry/index.d.ts +4 -0
  62. package/dist/src/registry/index.d.ts.map +1 -0
  63. package/dist/src/registry/index.js +2 -0
  64. package/dist/src/registry/loader.d.ts +25 -0
  65. package/dist/src/registry/loader.d.ts.map +1 -0
  66. package/dist/src/registry/loader.js +88 -0
  67. package/dist/src/registry/node-type-registry.d.ts +52 -0
  68. package/dist/src/registry/node-type-registry.d.ts.map +1 -0
  69. package/dist/src/registry/node-type-registry.js +130 -0
  70. package/dist/src/registry/types.d.ts +65 -0
  71. package/dist/src/registry/types.d.ts.map +1 -0
  72. package/dist/src/registry/types.js +10 -0
  73. package/dist/src/workflow/expression/ast.d.ts +1 -1
  74. package/dist/src/workflow/expression/ast.d.ts.map +1 -1
  75. package/dist/src/workflow/expression/context.d.ts +4 -0
  76. package/dist/src/workflow/expression/context.d.ts.map +1 -1
  77. package/dist/src/workflow/expression/context.js +5 -1
  78. package/dist/src/workflow/expression/evaluator.d.ts.map +1 -1
  79. package/dist/src/workflow/expression/evaluator.js +24 -1
  80. package/dist/src/workflow/expression/evaluator.test.js +174 -0
  81. package/dist/src/workflow/expression/expression.test.js +140 -1
  82. package/dist/src/workflow/expression/helpers.d.ts +4 -0
  83. package/dist/src/workflow/expression/helpers.d.ts.map +1 -1
  84. package/dist/src/workflow/expression/helpers.js +51 -0
  85. package/dist/src/workflow/expression/index.d.ts +14 -0
  86. package/dist/src/workflow/expression/index.d.ts.map +1 -1
  87. package/dist/src/workflow/expression/index.js +28 -1
  88. package/dist/src/workflow/expression/lexer.d.ts.map +1 -1
  89. package/dist/src/workflow/expression/lexer.js +43 -0
  90. package/dist/src/workflow/expression/parser.js +1 -1
  91. package/dist/src/workflow/index.d.ts +3 -3
  92. package/dist/src/workflow/index.d.ts.map +1 -1
  93. package/dist/src/workflow/index.js +4 -2
  94. package/dist/src/workflow/workflow-loader.d.ts +8 -2
  95. package/dist/src/workflow/workflow-loader.d.ts.map +1 -1
  96. package/dist/src/workflow/workflow-loader.js +21 -2
  97. package/dist/src/workflow/workflow-types.d.ts +781 -12
  98. package/dist/src/workflow/workflow-types.d.ts.map +1 -1
  99. package/dist/src/workflow/workflow-types.js +248 -3
  100. package/dist/src/workflow/workflow-types.test.js +621 -1
  101. package/package.json +3 -2
@@ -88,6 +88,22 @@ describe('evaluate — variable lookup', () => {
88
88
  const ast = { type: 'VariableRef', name: 'data' };
89
89
  expect(evaluate(ast, ctx({ data: null }))).toBe(null);
90
90
  });
91
+ it('resolves dotted variable path from nested context', () => {
92
+ const ast = { type: 'VariableRef', name: 'trigger.data.issueId' };
93
+ expect(evaluate(ast, ctx({ trigger: { data: { issueId: 'SUP-123' } } }))).toBe('SUP-123');
94
+ });
95
+ it('resolves two-level dotted path', () => {
96
+ const ast = { type: 'VariableRef', name: 'steps.route.result' };
97
+ expect(evaluate(ast, ctx({ steps: { route: { result: 'development' } } }))).toBe('development');
98
+ });
99
+ it('returns false for dotted path when intermediate is missing', () => {
100
+ const ast = { type: 'VariableRef', name: 'trigger.data.issueId' };
101
+ expect(evaluate(ast, ctx({}))).toBe(false);
102
+ });
103
+ it('returns false for dotted path when intermediate is null', () => {
104
+ const ast = { type: 'VariableRef', name: 'trigger.data.issueId' };
105
+ expect(evaluate(ast, ctx({ trigger: null }))).toBe(false);
106
+ });
91
107
  });
92
108
  // ---------------------------------------------------------------------------
93
109
  // 3. Boolean operators
@@ -437,6 +453,30 @@ describe('evaluate — comparisons', () => {
437
453
  });
438
454
  });
439
455
  // ---------------------------------------------------------------------------
456
+ // 4b. in operator
457
+ // ---------------------------------------------------------------------------
458
+ describe('evaluate — in operator', () => {
459
+ it('returns true when value is in array', () => {
460
+ const result = evaluateCondition("{{ 'bug' in labels }}", ctx({ labels: ['bug', 'enhancement'] }));
461
+ expect(result).toBe(true);
462
+ });
463
+ it('returns false when value is not in array', () => {
464
+ const result = evaluateCondition("{{ 'feature' in labels }}", ctx({ labels: ['bug', 'enhancement'] }));
465
+ expect(result).toBe(false);
466
+ });
467
+ it('returns true for substring in string', () => {
468
+ const result = evaluateCondition("{{ 'fix' in title }}", ctx({ title: 'Quick fix for bug' }));
469
+ expect(result).toBe(true);
470
+ });
471
+ it('returns false when substring not in string', () => {
472
+ const result = evaluateCondition("{{ 'hotfix' in title }}", ctx({ title: 'Quick fix for bug' }));
473
+ expect(result).toBe(false);
474
+ });
475
+ it('throws for invalid right operand type', () => {
476
+ expect(() => evaluateCondition("{{ 'x' in count }}", ctx({ count: 42 }))).toThrow(EvaluationError);
477
+ });
478
+ });
479
+ // ---------------------------------------------------------------------------
440
480
  // 5. Function calls
441
481
  // ---------------------------------------------------------------------------
442
482
  describe('evaluate — function calls', () => {
@@ -561,6 +601,91 @@ describe('built-in helpers', () => {
561
601
  expect(helpers.isParentIssue()).toBe(false);
562
602
  });
563
603
  });
604
+ describe('hasSubIssues', () => {
605
+ it('returns true when hasSubIssues is true', () => {
606
+ const issue = makeIssue();
607
+ const helpers = createBuiltinHelpers(issue, { hasSubIssues: true });
608
+ expect(helpers.hasSubIssues()).toBe(true);
609
+ });
610
+ it('returns false when hasSubIssues is false', () => {
611
+ const issue = makeIssue();
612
+ const helpers = createBuiltinHelpers(issue, { hasSubIssues: false });
613
+ expect(helpers.hasSubIssues()).toBe(false);
614
+ });
615
+ it('returns false when hasSubIssues is not specified', () => {
616
+ const issue = makeIssue();
617
+ const helpers = createBuiltinHelpers(issue);
618
+ expect(helpers.hasSubIssues()).toBe(false);
619
+ });
620
+ });
621
+ describe('isAssignedToHuman', () => {
622
+ it('returns true when isAssignedToHuman is true', () => {
623
+ const issue = makeIssue();
624
+ const helpers = createBuiltinHelpers(issue, { isAssignedToHuman: true });
625
+ expect(helpers.isAssignedToHuman()).toBe(true);
626
+ });
627
+ it('returns false when isAssignedToHuman is false', () => {
628
+ const issue = makeIssue();
629
+ const helpers = createBuiltinHelpers(issue, { isAssignedToHuman: false });
630
+ expect(helpers.isAssignedToHuman()).toBe(false);
631
+ });
632
+ it('returns false when isAssignedToHuman is not specified', () => {
633
+ const issue = makeIssue();
634
+ const helpers = createBuiltinHelpers(issue);
635
+ expect(helpers.isAssignedToHuman()).toBe(false);
636
+ });
637
+ });
638
+ describe('hasBlockingIncomplete', () => {
639
+ it('returns true when hasBlockingIncomplete is true', () => {
640
+ const issue = makeIssue();
641
+ const helpers = createBuiltinHelpers(issue, { hasBlockingIncomplete: true });
642
+ expect(helpers.hasBlockingIncomplete()).toBe(true);
643
+ });
644
+ it('returns false when hasBlockingIncomplete is false', () => {
645
+ const issue = makeIssue();
646
+ const helpers = createBuiltinHelpers(issue, { hasBlockingIncomplete: false });
647
+ expect(helpers.hasBlockingIncomplete()).toBe(false);
648
+ });
649
+ it('returns false when hasBlockingIncomplete is not specified', () => {
650
+ const issue = makeIssue();
651
+ const helpers = createBuiltinHelpers(issue);
652
+ expect(helpers.hasBlockingIncomplete()).toBe(false);
653
+ });
654
+ });
655
+ describe('startsWith', () => {
656
+ it('returns true when string starts with prefix', () => {
657
+ const issue = makeIssue({ title: 'fix: resolve bug' });
658
+ const helpers = createBuiltinHelpers(issue);
659
+ expect(helpers.startsWith('fix: resolve bug', 'fix')).toBe(true);
660
+ });
661
+ it('returns false when string does not start with prefix', () => {
662
+ const issue = makeIssue();
663
+ const helpers = createBuiltinHelpers(issue);
664
+ expect(helpers.startsWith('hello world', 'world')).toBe(false);
665
+ });
666
+ it('returns false for non-string arguments', () => {
667
+ const issue = makeIssue();
668
+ const helpers = createBuiltinHelpers(issue);
669
+ expect(helpers.startsWith(123, 'fix')).toBe(false);
670
+ });
671
+ });
672
+ describe('contains', () => {
673
+ it('returns true when string contains substring', () => {
674
+ const issue = makeIssue();
675
+ const helpers = createBuiltinHelpers(issue);
676
+ expect(helpers.contains('hello world', 'world')).toBe(true);
677
+ });
678
+ it('returns false when string does not contain substring', () => {
679
+ const issue = makeIssue();
680
+ const helpers = createBuiltinHelpers(issue);
681
+ expect(helpers.contains('hello world', 'foo')).toBe(false);
682
+ });
683
+ it('returns false for non-string arguments', () => {
684
+ const issue = makeIssue();
685
+ const helpers = createBuiltinHelpers(issue);
686
+ expect(helpers.contains(42, 'test')).toBe(false);
687
+ });
688
+ });
564
689
  });
565
690
  // ---------------------------------------------------------------------------
566
691
  // 7. Complex expressions (end-to-end with evaluateCondition)
@@ -635,6 +760,37 @@ describe('evaluateCondition — end-to-end', () => {
635
760
  const context = buildEvaluationContext(issue, { researchCompleted: true }, { hasSubIssues: false });
636
761
  expect(evaluateCondition("{{ hasLabel('bug') and researchCompleted }}", context)).toBe(true);
637
762
  });
763
+ it('evaluates hasSubIssues() in condition', () => {
764
+ const issue = makeIssue();
765
+ const context = buildEvaluationContext(issue, undefined, { hasSubIssues: true });
766
+ expect(evaluateCondition('{{ hasSubIssues() }}', context)).toBe(true);
767
+ });
768
+ it('evaluates isAssignedToHuman() in condition', () => {
769
+ const issue = makeIssue();
770
+ const context = buildEvaluationContext(issue, undefined, { isAssignedToHuman: true });
771
+ expect(evaluateCondition('{{ isAssignedToHuman() }}', context)).toBe(true);
772
+ });
773
+ it('evaluates hasBlockingIncomplete() in condition', () => {
774
+ const issue = makeIssue();
775
+ const context = buildEvaluationContext(issue, undefined, { hasBlockingIncomplete: true });
776
+ expect(evaluateCondition('{{ hasBlockingIncomplete() }}', context)).toBe(true);
777
+ });
778
+ it('evaluates dotted path expression end-to-end', () => {
779
+ const context = ctx({ trigger: { data: { issueId: 'SUP-123' } } });
780
+ expect(evaluateCondition("{{ trigger.data.issueId == 'SUP-123' }}", context)).toBe(true);
781
+ });
782
+ it('evaluates symbolic operators end-to-end', () => {
783
+ const context = ctx({ priority: 5 });
784
+ expect(evaluateCondition('{{ priority > 3 }}', context)).toBe(true);
785
+ });
786
+ it('evaluates startsWith() function in condition', () => {
787
+ const context = ctx({ title: 'fix: resolve memory leak' }, { startsWith: (...args) => typeof args[0] === 'string' && typeof args[1] === 'string' && args[0].startsWith(args[1]) });
788
+ expect(evaluateCondition("{{ startsWith(title, 'fix') }}", context)).toBe(true);
789
+ });
790
+ it('evaluates contains() function in condition', () => {
791
+ const context = ctx({ description: 'This is a hotfix release' }, { contains: (...args) => typeof args[0] === 'string' && typeof args[1] === 'string' && args[0].includes(args[1]) });
792
+ expect(evaluateCondition("{{ contains(description, 'hotfix') }}", context)).toBe(true);
793
+ });
638
794
  });
639
795
  // ---------------------------------------------------------------------------
640
796
  // 8. Error cases
@@ -774,6 +930,24 @@ describe('buildEvaluationContext', () => {
774
930
  expect(context.functions.isParentIssue).toBeDefined();
775
931
  expect(context.functions.isParentIssue()).toBe(true);
776
932
  });
933
+ it('registers hasSubIssues function', () => {
934
+ const issue = makeIssue();
935
+ const context = buildEvaluationContext(issue, undefined, { hasSubIssues: true });
936
+ expect(context.functions.hasSubIssues).toBeDefined();
937
+ expect(context.functions.hasSubIssues()).toBe(true);
938
+ });
939
+ it('registers isAssignedToHuman function', () => {
940
+ const issue = makeIssue();
941
+ const context = buildEvaluationContext(issue, undefined, { isAssignedToHuman: true });
942
+ expect(context.functions.isAssignedToHuman).toBeDefined();
943
+ expect(context.functions.isAssignedToHuman()).toBe(true);
944
+ });
945
+ it('registers hasBlockingIncomplete function', () => {
946
+ const issue = makeIssue();
947
+ const context = buildEvaluationContext(issue, undefined, { hasBlockingIncomplete: true });
948
+ expect(context.functions.hasBlockingIncomplete).toBeDefined();
949
+ expect(context.functions.hasBlockingIncomplete()).toBe(true);
950
+ });
777
951
  it('works end-to-end with evaluateCondition', () => {
778
952
  const issue = makeIssue({
779
953
  labels: ['bug', 'priority-high'],
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { parseExpression, tokenize, parse, ParseError } from './index.js';
2
+ import { parseExpression, tokenize, parse, ParseError, interpolateTemplate } from './index.js';
3
3
  // ---------------------------------------------------------------------------
4
4
  // Lexer tests
5
5
  // ---------------------------------------------------------------------------
@@ -67,6 +67,43 @@ describe('tokenize', () => {
67
67
  const tokens = tokenize('{{ x }}');
68
68
  expect(tokens[tokens.length - 1].type).toBe('EOF');
69
69
  });
70
+ it('tokenizes dotted variable path as single Identifier', () => {
71
+ const tokens = tokenize('{{ trigger.data.issueId }}');
72
+ const nonEof = tokens.filter((t) => t.type !== 'EOF');
73
+ expect(nonEof).toHaveLength(1);
74
+ expect(nonEof[0].type).toBe('Identifier');
75
+ expect(nonEof[0].value).toBe('trigger.data.issueId');
76
+ });
77
+ it('tokenizes symbolic operators == != > < >= <=', () => {
78
+ const cases = [
79
+ { input: '{{ x == y }}', expected: 'eq' },
80
+ { input: '{{ x != y }}', expected: 'neq' },
81
+ { input: '{{ x > y }}', expected: 'gt' },
82
+ { input: '{{ x < y }}', expected: 'lt' },
83
+ { input: '{{ x >= y }}', expected: 'gte' },
84
+ { input: '{{ x <= y }}', expected: 'lte' },
85
+ ];
86
+ for (const { input, expected } of cases) {
87
+ const tokens = tokenize(input);
88
+ const ops = tokens.filter((t) => t.type === 'Operator');
89
+ expect(ops).toHaveLength(1);
90
+ expect(ops[0].value).toBe(expected);
91
+ }
92
+ });
93
+ it('tokenizes mixed symbolic and keyword operators', () => {
94
+ const tokens = tokenize('{{ x == 5 and y > 3 }}');
95
+ const types = tokens.map((t) => `${t.type}:${t.value}`);
96
+ expect(types).toEqual([
97
+ 'Identifier:x',
98
+ 'Operator:eq',
99
+ 'NumberLiteral:5',
100
+ 'Operator:and',
101
+ 'Identifier:y',
102
+ 'Operator:gt',
103
+ 'NumberLiteral:3',
104
+ 'EOF:',
105
+ ]);
106
+ });
70
107
  });
71
108
  // ---------------------------------------------------------------------------
72
109
  // Parser tests — simple expressions
@@ -224,6 +261,59 @@ describe('parseExpression', () => {
224
261
  right: { type: 'NumberLiteral', value: 5 },
225
262
  });
226
263
  });
264
+ it('parses in', () => {
265
+ const ast = parseExpression("{{ 'bug' in labels }}");
266
+ expect(ast).toEqual({
267
+ type: 'BinaryOp',
268
+ operator: 'in',
269
+ left: { type: 'StringLiteral', value: 'bug' },
270
+ right: { type: 'VariableRef', name: 'labels' },
271
+ });
272
+ });
273
+ });
274
+ // -------------------------------------------------------------------------
275
+ // Dotted variable paths
276
+ // -------------------------------------------------------------------------
277
+ describe('dotted variable paths', () => {
278
+ it('parses dotted variable reference', () => {
279
+ const ast = parseExpression('{{ trigger.data.issueId }}');
280
+ expect(ast).toEqual({
281
+ type: 'VariableRef',
282
+ name: 'trigger.data.issueId',
283
+ });
284
+ });
285
+ it('parses dotted path with symbolic comparison', () => {
286
+ const ast = parseExpression('{{ trigger.data.priority > 3 }}');
287
+ expect(ast).toEqual({
288
+ type: 'BinaryOp',
289
+ operator: 'gt',
290
+ left: { type: 'VariableRef', name: 'trigger.data.priority' },
291
+ right: { type: 'NumberLiteral', value: 3 },
292
+ });
293
+ });
294
+ });
295
+ // -------------------------------------------------------------------------
296
+ // Symbolic operators
297
+ // -------------------------------------------------------------------------
298
+ describe('symbolic operators', () => {
299
+ it('parses expression with symbolic == operator', () => {
300
+ const ast = parseExpression("{{ status == 'active' }}");
301
+ expect(ast).toEqual({
302
+ type: 'BinaryOp',
303
+ operator: 'eq',
304
+ left: { type: 'VariableRef', name: 'status' },
305
+ right: { type: 'StringLiteral', value: 'active' },
306
+ });
307
+ });
308
+ it('parses expression with symbolic != operator', () => {
309
+ const ast = parseExpression("{{ status != 'closed' }}");
310
+ expect(ast).toEqual({
311
+ type: 'BinaryOp',
312
+ operator: 'neq',
313
+ left: { type: 'VariableRef', name: 'status' },
314
+ right: { type: 'StringLiteral', value: 'closed' },
315
+ });
316
+ });
227
317
  });
228
318
  // -------------------------------------------------------------------------
229
319
  // Function calls
@@ -514,3 +604,52 @@ describe('parseExpression', () => {
514
604
  });
515
605
  });
516
606
  });
607
+ // ---------------------------------------------------------------------------
608
+ // Template interpolation tests
609
+ // ---------------------------------------------------------------------------
610
+ describe('interpolateTemplate', () => {
611
+ /** Create a context with the given variables and optional functions. */
612
+ function ctx(variables, functions = {}) {
613
+ return { variables, functions };
614
+ }
615
+ it('resolves a single expression', () => {
616
+ const result = interpolateTemplate('Issue {{ issueId }} is ready', ctx({ issueId: 'SUP-123' }));
617
+ expect(result).toBe('Issue SUP-123 is ready');
618
+ });
619
+ it('resolves multiple expressions', () => {
620
+ const result = interpolateTemplate('{{ name }} has {{ count }} items', ctx({ name: 'Alice', count: 5 }));
621
+ expect(result).toBe('Alice has 5 items');
622
+ });
623
+ it('resolves dotted path expressions', () => {
624
+ const result = interpolateTemplate('Issue {{ trigger.data.issueId }} is ready', ctx({ trigger: { data: { issueId: 'SUP-123' } } }));
625
+ expect(result).toBe('Issue SUP-123 is ready');
626
+ });
627
+ it('coerces boolean to string', () => {
628
+ const result = interpolateTemplate('Result: {{ active }}', ctx({ active: true }));
629
+ expect(result).toBe('Result: true');
630
+ });
631
+ it('coerces number to string', () => {
632
+ const result = interpolateTemplate('Count: {{ count }}', ctx({ count: 42 }));
633
+ expect(result).toBe('Count: 42');
634
+ });
635
+ it('passes through static string without expressions', () => {
636
+ const result = interpolateTemplate('No expressions here', ctx({}));
637
+ expect(result).toBe('No expressions here');
638
+ });
639
+ it('resolves expression-only template', () => {
640
+ const result = interpolateTemplate('{{ status }}', ctx({ status: 'In Progress' }));
641
+ expect(result).toBe('In Progress');
642
+ });
643
+ it('resolves function calls in template', () => {
644
+ const result = interpolateTemplate('Has bug: {{ hasLabel(\'bug\') }}', ctx({}, { hasLabel: (...args) => args[0] === 'bug' }));
645
+ expect(result).toBe('Has bug: true');
646
+ });
647
+ it('throws ParseError on empty expression', () => {
648
+ expect(() => interpolateTemplate('Hello {{ }}', ctx({}))).toThrow(ParseError);
649
+ expect(() => interpolateTemplate('Hello {{ }}', ctx({}))).toThrow(/Empty expression/);
650
+ });
651
+ it('resolves false for undefined variables', () => {
652
+ const result = interpolateTemplate('Value: {{ missing }}', ctx({}));
653
+ expect(result).toBe('Value: false');
654
+ });
655
+ });
@@ -9,6 +9,10 @@ import type { GovernorIssue } from '../../governor/governor-types.js';
9
9
  export interface BuiltinHelperOptions {
10
10
  /** Whether the issue has sub-issues (i.e., it is a parent issue) */
11
11
  hasSubIssues?: boolean;
12
+ /** Whether the issue is assigned to a human user (vs unassigned or bot) */
13
+ isAssignedToHuman?: boolean;
14
+ /** Whether the issue has incomplete blocking relations */
15
+ hasBlockingIncomplete?: boolean;
12
16
  }
13
17
  /**
14
18
  * Create the set of built-in helper functions bound to the given issue.
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/workflow/expression/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAMrE,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAMD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE,oBAAyB,GAC9B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAwCjD"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/workflow/expression/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAMrE,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,0DAA0D;IAC1D,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAMD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE,oBAAyB,GAC9B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAgGjD"}
@@ -52,5 +52,56 @@ export function createBuiltinHelpers(issue, opts = {}) {
52
52
  isParentIssue() {
53
53
  return opts.hasSubIssues === true;
54
54
  },
55
+ /**
56
+ * Check whether the issue has sub-issues.
57
+ * Alias for `isParentIssue()`.
58
+ *
59
+ * Usage in expressions: `hasSubIssues()`
60
+ */
61
+ hasSubIssues() {
62
+ return opts.hasSubIssues === true;
63
+ },
64
+ /**
65
+ * Check whether the issue is assigned to a human user (vs unassigned or bot).
66
+ *
67
+ * Usage in expressions: `isAssignedToHuman()`
68
+ */
69
+ isAssignedToHuman() {
70
+ return opts.isAssignedToHuman === true;
71
+ },
72
+ /**
73
+ * Check whether the issue has incomplete blocking relations.
74
+ *
75
+ * Usage in expressions: `hasBlockingIncomplete()`
76
+ */
77
+ hasBlockingIncomplete() {
78
+ return opts.hasBlockingIncomplete === true;
79
+ },
80
+ /**
81
+ * Check whether a string starts with a given prefix.
82
+ *
83
+ * Usage in expressions: `startsWith(title, 'fix')`
84
+ */
85
+ startsWith(...args) {
86
+ const str = args[0];
87
+ const prefix = args[1];
88
+ if (typeof str !== 'string' || typeof prefix !== 'string') {
89
+ return false;
90
+ }
91
+ return str.startsWith(prefix);
92
+ },
93
+ /**
94
+ * Check whether a string contains a given substring.
95
+ *
96
+ * Usage in expressions: `contains(title, 'hotfix')`
97
+ */
98
+ contains(...args) {
99
+ const str = args[0];
100
+ const substring = args[1];
101
+ if (typeof str !== 'string' || typeof substring !== 'string') {
102
+ return false;
103
+ }
104
+ return str.includes(substring);
105
+ },
55
106
  };
56
107
  }
@@ -52,4 +52,18 @@ export declare function parseExpression(condition: string): ASTNode;
52
52
  * @throws {EvaluationError} on runtime errors (unknown functions, type mismatches).
53
53
  */
54
54
  export declare function evaluateCondition(condition: string, context: EvaluationContext): boolean;
55
+ /**
56
+ * Interpolate template expressions within a string.
57
+ *
58
+ * Finds all `{{ ... }}` expressions in the input string, evaluates each
59
+ * against the context, and replaces the placeholder with the string
60
+ * representation of the result.
61
+ *
62
+ * @param template - The template string containing `{{ }}` expressions.
63
+ * @param context - The sandboxed evaluation context.
64
+ * @returns The fully resolved string.
65
+ * @throws {ParseError} on syntax errors in expressions.
66
+ * @throws {EvaluationError} on runtime errors in expressions.
67
+ */
68
+ export declare function interpolateTemplate(template: string, context: EvaluationContext): string;
55
69
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/workflow/expression/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AASrD,YAAY,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,UAAU,CAAA;AAMjB,YAAY,EACV,KAAK,EACL,SAAS,EACT,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAMjD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAMnC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAM1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAMrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAMnD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAIxF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/workflow/expression/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AASrD,YAAY,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,UAAU,CAAA;AAMjB,YAAY,EACV,KAAK,EACL,SAAS,EACT,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAMjD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAMnC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAM1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAMrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAMnD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAIxF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAcxF"}
@@ -17,7 +17,7 @@
17
17
  * // => true or false
18
18
  * ```
19
19
  */
20
- import { tokenize } from './lexer.js';
20
+ import { tokenize, ParseError } from './lexer.js';
21
21
  import { parse } from './parser.js';
22
22
  import { evaluate } from './evaluator.js';
23
23
  export { ParseError, tokenize } from './lexer.js';
@@ -69,3 +69,30 @@ export function evaluateCondition(condition, context) {
69
69
  const result = evaluate(ast, context);
70
70
  return Boolean(result);
71
71
  }
72
+ /**
73
+ * Interpolate template expressions within a string.
74
+ *
75
+ * Finds all `{{ ... }}` expressions in the input string, evaluates each
76
+ * against the context, and replaces the placeholder with the string
77
+ * representation of the result.
78
+ *
79
+ * @param template - The template string containing `{{ }}` expressions.
80
+ * @param context - The sandboxed evaluation context.
81
+ * @returns The fully resolved string.
82
+ * @throws {ParseError} on syntax errors in expressions.
83
+ * @throws {EvaluationError} on runtime errors in expressions.
84
+ */
85
+ export function interpolateTemplate(template, context) {
86
+ // Regex to match {{ ... }} expressions (non-greedy)
87
+ const EXPR_PATTERN = /\{\{(.*?)\}\}/g;
88
+ return template.replace(EXPR_PATTERN, (_match, expr) => {
89
+ const trimmed = expr.trim();
90
+ if (trimmed.length === 0) {
91
+ throw new ParseError('Empty expression in template', { offset: 0, column: 1 });
92
+ }
93
+ const tokens = tokenize(trimmed);
94
+ const ast = parse(tokens);
95
+ const result = evaluate(ast, context);
96
+ return String(result);
97
+ });
98
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../../../src/workflow/expression/lexer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,gBAAgB,GAChB,eAAe,GACf,eAAe,GACf,UAAU,GACV,WAAW,GACX,YAAY,GACZ,OAAO,GACP,KAAK,CAAA;AAET,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;CAClC;AAMD;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;gBAErB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc;CAKtD;AAsED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAsF/C"}
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../../../src/workflow/expression/lexer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,gBAAgB,GAChB,eAAe,GACf,eAAe,GACf,UAAU,GACV,WAAW,GACX,YAAY,GACZ,OAAO,GACP,KAAK,CAAA;AAET,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;CAClC;AAMD;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;gBAErB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc;CAKtD;AAuED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAkI/C"}
@@ -26,6 +26,7 @@ export class ParseError extends Error {
26
26
  const OPERATORS = new Set([
27
27
  'and', 'or', 'not',
28
28
  'eq', 'neq', 'gt', 'lt', 'gte', 'lte',
29
+ 'in',
29
30
  ]);
30
31
  const BOOLEAN_LITERALS = new Set(['true', 'false']);
31
32
  // ---------------------------------------------------------------------------
@@ -129,6 +130,15 @@ export function tokenize(input) {
129
130
  const start = i;
130
131
  while (i < inner.length && isIdentChar(inner[i]))
131
132
  i++;
133
+ // Dotted variable paths: consume `.` followed by another identifier segment
134
+ while (i < inner.length &&
135
+ inner[i] === '.' &&
136
+ i + 1 < inner.length &&
137
+ isIdentStart(inner[i + 1])) {
138
+ i++; // skip the dot
139
+ while (i < inner.length && isIdentChar(inner[i]))
140
+ i++;
141
+ }
132
142
  const word = inner.slice(start, i);
133
143
  if (BOOLEAN_LITERALS.has(word)) {
134
144
  tokens.push({ type: 'BooleanLiteral', value: word, position: pos(start) });
@@ -158,6 +168,39 @@ export function tokenize(input) {
158
168
  i++;
159
169
  continue;
160
170
  }
171
+ // Symbolic comparison operators
172
+ if (ch === '=' && i + 1 < inner.length && inner[i + 1] === '=') {
173
+ tokens.push({ type: 'Operator', value: 'eq', position: pos(i) });
174
+ i += 2;
175
+ continue;
176
+ }
177
+ if (ch === '!' && i + 1 < inner.length && inner[i + 1] === '=') {
178
+ tokens.push({ type: 'Operator', value: 'neq', position: pos(i) });
179
+ i += 2;
180
+ continue;
181
+ }
182
+ if (ch === '>') {
183
+ if (i + 1 < inner.length && inner[i + 1] === '=') {
184
+ tokens.push({ type: 'Operator', value: 'gte', position: pos(i) });
185
+ i += 2;
186
+ }
187
+ else {
188
+ tokens.push({ type: 'Operator', value: 'gt', position: pos(i) });
189
+ i += 1;
190
+ }
191
+ continue;
192
+ }
193
+ if (ch === '<') {
194
+ if (i + 1 < inner.length && inner[i + 1] === '=') {
195
+ tokens.push({ type: 'Operator', value: 'lte', position: pos(i) });
196
+ i += 2;
197
+ }
198
+ else {
199
+ tokens.push({ type: 'Operator', value: 'lt', position: pos(i) });
200
+ i += 1;
201
+ }
202
+ continue;
203
+ }
161
204
  // Unknown character
162
205
  throw new ParseError(`Unexpected character '${ch}'`, pos(i));
163
206
  }
@@ -14,7 +14,7 @@ import { ParseError } from './lexer.js';
14
14
  // ---------------------------------------------------------------------------
15
15
  // Operator sets
16
16
  // ---------------------------------------------------------------------------
17
- const COMPARISON_OPERATORS = new Set(['eq', 'neq', 'gt', 'lt', 'gte', 'lte']);
17
+ const COMPARISON_OPERATORS = new Set(['eq', 'neq', 'gt', 'lt', 'gte', 'lte', 'in']);
18
18
  function peek(state) {
19
19
  return state.tokens[state.pos];
20
20
  }
@@ -4,9 +4,9 @@
4
4
  * Declarative workflow graph definitions using YAML (v1.1 schema extension).
5
5
  * Defines phases, transitions, escalation ladder, gates, and parallelism.
6
6
  */
7
- export type { EscalationStrategy, PhaseDefinition, PhaseOutputDeclaration, PhaseInputDeclaration, TransitionDefinition, EscalationLadderRung, EscalationConfig, GateDefinition, ParallelismGroupDefinition, WorkflowDefinition, BranchingDefinition, TemplateRetryConfig, TemplateTimeoutConfig, } from './workflow-types.js';
8
- export { PhaseDefinitionSchema, PhaseOutputDeclarationSchema, PhaseInputDeclarationSchema, TransitionDefinitionSchema, EscalationLadderRungSchema, EscalationConfigSchema, GateDefinitionSchema, ParallelismGroupDefinitionSchema, WorkflowDefinitionSchema, BranchingDefinitionSchema, TemplateRetryConfigSchema, TemplateTimeoutConfigSchema, validateWorkflowDefinition, } from './workflow-types.js';
9
- export { loadWorkflowDefinitionFile, getBuiltinWorkflowDir, getBuiltinWorkflowPath, } from './workflow-loader.js';
7
+ export type { EscalationStrategy, PhaseDefinition, PhaseOutputDeclaration, PhaseInputDeclaration, TransitionDefinition, EscalationLadderRung, EscalationConfig, GateDefinition, ParallelismGroupDefinition, WorkflowDefinition, BranchingDefinition, TemplateRetryConfig, TemplateTimeoutConfig, WorkflowTriggerDefinition, ProviderRequirement, WorkflowConfig, StepDefinition, NodeDefinition, WorkflowDefinitionV2, AnyWorkflowDefinition, } from './workflow-types.js';
8
+ export { PhaseDefinitionSchema, PhaseOutputDeclarationSchema, PhaseInputDeclarationSchema, TransitionDefinitionSchema, EscalationLadderRungSchema, EscalationConfigSchema, GateDefinitionSchema, ParallelismGroupDefinitionSchema, WorkflowDefinitionSchema, BranchingDefinitionSchema, TemplateRetryConfigSchema, TemplateTimeoutConfigSchema, validateWorkflowDefinition, WorkflowTriggerDefinitionSchema, ProviderRequirementSchema, WorkflowConfigSchema, StepDefinitionSchema, NodeDefinitionSchema, WorkflowDefinitionV2Schema, AnyWorkflowDefinitionSchema, validateAnyWorkflowDefinition, crossValidateWorkflowV2, } from './workflow-types.js';
9
+ export { loadWorkflowDefinitionFile, loadAnyWorkflowDefinitionFile, getBuiltinWorkflowDir, getBuiltinWorkflowPath, } from './workflow-loader.js';
10
10
  export type { WorkflowRegistryConfig, WorkflowStoreSource } from './workflow-registry.js';
11
11
  export { WorkflowRegistry } from './workflow-registry.js';
12
12
  export type { TransitionContext, TransitionResult } from './transition-engine.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflow/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflow/index.ts"],"names":[],"mappings":"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"}
@@ -4,8 +4,10 @@
4
4
  * Declarative workflow graph definitions using YAML (v1.1 schema extension).
5
5
  * Defines phases, transitions, escalation ladder, gates, and parallelism.
6
6
  */
7
- export { PhaseDefinitionSchema, PhaseOutputDeclarationSchema, PhaseInputDeclarationSchema, TransitionDefinitionSchema, EscalationLadderRungSchema, EscalationConfigSchema, GateDefinitionSchema, ParallelismGroupDefinitionSchema, WorkflowDefinitionSchema, BranchingDefinitionSchema, TemplateRetryConfigSchema, TemplateTimeoutConfigSchema, validateWorkflowDefinition, } from './workflow-types.js';
8
- export { loadWorkflowDefinitionFile, getBuiltinWorkflowDir, getBuiltinWorkflowPath, } from './workflow-loader.js';
7
+ export { PhaseDefinitionSchema, PhaseOutputDeclarationSchema, PhaseInputDeclarationSchema, TransitionDefinitionSchema, EscalationLadderRungSchema, EscalationConfigSchema, GateDefinitionSchema, ParallelismGroupDefinitionSchema, WorkflowDefinitionSchema, BranchingDefinitionSchema, TemplateRetryConfigSchema, TemplateTimeoutConfigSchema, validateWorkflowDefinition,
8
+ // v2 schemas & validation
9
+ WorkflowTriggerDefinitionSchema, ProviderRequirementSchema, WorkflowConfigSchema, StepDefinitionSchema, NodeDefinitionSchema, WorkflowDefinitionV2Schema, AnyWorkflowDefinitionSchema, validateAnyWorkflowDefinition, crossValidateWorkflowV2, } from './workflow-types.js';
10
+ export { loadWorkflowDefinitionFile, loadAnyWorkflowDefinitionFile, getBuiltinWorkflowDir, getBuiltinWorkflowPath, } from './workflow-loader.js';
9
11
  export { WorkflowRegistry } from './workflow-registry.js';
10
12
  export { evaluateTransitions } from './transition-engine.js';
11
13
  export { evaluateBranching } from './branching-router.js';