@wizdear/atlas-code 0.2.4 → 0.2.5

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 (93) hide show
  1. package/dist/agent-factory.d.ts +8 -1
  2. package/dist/agent-factory.d.ts.map +1 -1
  3. package/dist/agent-factory.js +42 -2
  4. package/dist/agent-factory.js.map +1 -1
  5. package/dist/cli.d.ts +7 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +8 -0
  8. package/dist/cli.js.map +1 -1
  9. package/dist/discovery.d.ts +9 -0
  10. package/dist/discovery.d.ts.map +1 -1
  11. package/dist/discovery.js +4 -4
  12. package/dist/discovery.js.map +1 -1
  13. package/dist/extension.d.ts +9 -2
  14. package/dist/extension.d.ts.map +1 -1
  15. package/dist/extension.js +1096 -333
  16. package/dist/extension.js.map +1 -1
  17. package/dist/gate.d.ts +1 -1
  18. package/dist/gate.d.ts.map +1 -1
  19. package/dist/gate.js.map +1 -1
  20. package/dist/orchestrator.d.ts +0 -2
  21. package/dist/orchestrator.d.ts.map +1 -1
  22. package/dist/orchestrator.js +0 -1
  23. package/dist/orchestrator.js.map +1 -1
  24. package/dist/pipeline-editor.d.ts +2 -0
  25. package/dist/pipeline-editor.d.ts.map +1 -1
  26. package/dist/pipeline-editor.js +36 -5
  27. package/dist/pipeline-editor.js.map +1 -1
  28. package/dist/pipeline.d.ts +2 -5
  29. package/dist/pipeline.d.ts.map +1 -1
  30. package/dist/pipeline.js +4 -3
  31. package/dist/pipeline.js.map +1 -1
  32. package/dist/planner.d.ts +9 -0
  33. package/dist/planner.d.ts.map +1 -1
  34. package/dist/planner.js +20 -10
  35. package/dist/planner.js.map +1 -1
  36. package/dist/roles/architect.d.ts +1 -1
  37. package/dist/roles/architect.d.ts.map +1 -1
  38. package/dist/roles/architect.js +1 -1
  39. package/dist/roles/architect.js.map +1 -1
  40. package/dist/roles/documenter.d.ts +1 -1
  41. package/dist/roles/documenter.d.ts.map +1 -1
  42. package/dist/roles/documenter.js +11 -0
  43. package/dist/roles/documenter.js.map +1 -1
  44. package/dist/roles/index.d.ts +1 -0
  45. package/dist/roles/index.d.ts.map +1 -1
  46. package/dist/roles/index.js +3 -0
  47. package/dist/roles/index.js.map +1 -1
  48. package/dist/roles/recover.d.ts +5 -0
  49. package/dist/roles/recover.d.ts.map +1 -0
  50. package/dist/roles/recover.js +82 -0
  51. package/dist/roles/recover.js.map +1 -0
  52. package/dist/router.d.ts.map +1 -1
  53. package/dist/router.js +6 -6
  54. package/dist/router.js.map +1 -1
  55. package/dist/standards.d.ts.map +1 -1
  56. package/dist/standards.js +1 -0
  57. package/dist/standards.js.map +1 -1
  58. package/dist/step-executor.d.ts +2 -0
  59. package/dist/step-executor.d.ts.map +1 -1
  60. package/dist/step-executor.js +16 -4
  61. package/dist/step-executor.js.map +1 -1
  62. package/dist/store.d.ts +3 -0
  63. package/dist/store.d.ts.map +1 -1
  64. package/dist/store.js +48 -19
  65. package/dist/store.js.map +1 -1
  66. package/dist/system-architect.d.ts +9 -0
  67. package/dist/system-architect.d.ts.map +1 -1
  68. package/dist/system-architect.js +11 -9
  69. package/dist/system-architect.js.map +1 -1
  70. package/dist/telegram/bridge.d.ts +39 -0
  71. package/dist/telegram/bridge.d.ts.map +1 -0
  72. package/dist/telegram/bridge.js +380 -0
  73. package/dist/telegram/bridge.js.map +1 -0
  74. package/dist/telegram/formatter.d.ts +15 -0
  75. package/dist/telegram/formatter.d.ts.map +1 -0
  76. package/dist/telegram/formatter.js +86 -0
  77. package/dist/telegram/formatter.js.map +1 -0
  78. package/dist/telegram/renderer.d.ts +45 -0
  79. package/dist/telegram/renderer.d.ts.map +1 -0
  80. package/dist/telegram/renderer.js +150 -0
  81. package/dist/telegram/renderer.js.map +1 -0
  82. package/dist/telegram/telegram-api.d.ts +84 -0
  83. package/dist/telegram/telegram-api.d.ts.map +1 -0
  84. package/dist/telegram/telegram-api.js +134 -0
  85. package/dist/telegram/telegram-api.js.map +1 -0
  86. package/dist/types.d.ts +10 -1
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js.map +1 -1
  89. package/dist/ui.d.ts +1 -1
  90. package/dist/ui.d.ts.map +1 -1
  91. package/dist/ui.js +2 -0
  92. package/dist/ui.js.map +1 -1
  93. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FeaturePipeline, PipelineStep, WorkflowType } from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Pipeline creation options */\nexport interface CreatePipelineOptions {\n\tparentFeatureId?: string;\n\tissueRef?: string;\n\tmaxRetries?: number;\n}\n\n/** Workflow classification result */\nexport interface WorkflowClassification {\n\ttype: WorkflowType;\n\treason: string;\n\tconfidence: number;\n}\n\n// ─── Step Templates ──────────────────────────────────────────────────────────\n\n/** new_feature: Design → Branch → Implement → Test → Regression → Review → PR/Merge (spec.md is pre-placed by orchestrator) */\nexport function newFeatureSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"architect\",\n\t\t\taction: \"design\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [\"design.md\"],\n\t\t\tgate: { type: \"file_exists\", target: \"design.md\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"implement\",\n\t\t\tinputs: [\"spec.md\", \"design.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"test\",\n\t\t\tinputs: [\"spec.md\", \"design.md\"],\n\t\t\toutputs: [\"test-report.md\"],\n\t\t\tgate: { type: \"test_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"spec.md\", \"test-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"regression_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"spec.md\", \"design.md\", \"test-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n/** enhancement: Analyze → Design → Branch → Implement → Test → Regression → Review → PR/Merge (spec.md is pre-placed by orchestrator; Analyze also runs at orchestration level for Planner) */\nexport function enhancementSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"analyzer\",\n\t\t\taction: \"analyze\",\n\t\t\tinputs: [],\n\t\t\toutputs: [\"impact-report.md\"],\n\t\t},\n\t\t{\n\t\t\tagent: \"architect\",\n\t\t\taction: \"design\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [\"design.md\"],\n\t\t\tgate: { type: \"file_exists\", target: \"design.md\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"implement\",\n\t\t\tinputs: [\"spec.md\", \"design.md\", \"impact-report.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"test\",\n\t\t\tinputs: [\"spec.md\", \"design.md\"],\n\t\t\toutputs: [\"test-report.md\"],\n\t\t\tgate: { type: \"test_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"impact-report.md\", \"test-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"regression_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"spec.md\", \"design.md\", \"test-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n/** bugfix: Investigate → Diagnose → Branch → Fix → Test → Regression → Review → PR/Merge */\nexport function bugfixSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"diagnostician\",\n\t\t\taction: \"investigate\",\n\t\t\tinputs: [],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"diagnostician\",\n\t\t\taction: \"diagnose\",\n\t\t\tinputs: [],\n\t\t\toutputs: [\"diagnosis.md\"],\n\t\t\tgate: { type: \"diagnosis_approve\", target: \"\" },\n\t\t\tinheritPriorHistory: true,\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"diagnosis.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"fix\",\n\t\t\tinputs: [\"diagnosis.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"test\",\n\t\t\tinputs: [\"diagnosis.md\"],\n\t\t\toutputs: [\"test-report.md\"],\n\t\t\tgate: { type: \"test_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"diagnosis.md\", \"test-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"regression_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"diagnosis.md\", \"test-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n/** refactor: Analyze → Design → Branch → Implement → Regression → Review → PR/Merge */\nexport function refactorSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"analyzer\",\n\t\t\taction: \"analyze\",\n\t\t\tinputs: [],\n\t\t\toutputs: [\"impact-report.md\"],\n\t\t},\n\t\t{\n\t\t\tagent: \"architect\",\n\t\t\taction: \"design\",\n\t\t\tinputs: [\"impact-report.md\"],\n\t\t\toutputs: [\"design.md\"],\n\t\t\tgate: { type: \"file_exists\", target: \"design.md\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"design.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"implement\",\n\t\t\tinputs: [\"design.md\", \"impact-report.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"impact-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"all_tests_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"design.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n// ─── Pipeline Factory ────────────────────────────────────────────────────────\n\n/**\n * Creates a FeaturePipeline matching the given workflow type.\n */\nexport function createPipeline(\n\ttype: WorkflowType,\n\tfeatureId: string,\n\toptions?: CreatePipelineOptions,\n): FeaturePipeline {\n\tlet steps: PipelineStep[];\n\tswitch (type) {\n\t\tcase \"new_feature\":\n\t\t\tsteps = newFeatureSteps();\n\t\t\tbreak;\n\t\tcase \"enhancement\":\n\t\t\tsteps = enhancementSteps();\n\t\t\tbreak;\n\t\tcase \"bugfix\":\n\t\t\tsteps = bugfixSteps();\n\t\t\tbreak;\n\t\tcase \"refactor\":\n\t\t\tsteps = refactorSteps();\n\t\t\tbreak;\n\t\tcase \"mixed\":\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot create pipeline with workflowType \"mixed\". Resolve to a concrete type (new_feature, enhancement, bugfix, refactor) first.',\n\t\t\t);\n\t}\n\n\treturn {\n\t\tfeatureId,\n\t\tworkflowType: type,\n\t\tsteps,\n\t\tcurrentStep: 0,\n\t\tstatus: \"pending\",\n\t\tretryCount: 0,\n\t\tmaxRetries: options?.maxRetries ?? 3,\n\t\tparentFeatureId: options?.parentFeatureId,\n\t\tissueRef: options?.issueRef,\n\t};\n}\n\n// ─── Execution Order ─────────────────────────────────────────────────────────\n\n/**\n * Topologically sorts the dependency graph and returns the execution order.\n * Uses Kahn's algorithm. Throws on circular dependencies.\n */\nexport function resolveExecutionOrder(dependencyGraph: Record<string, string[]>): string[] {\n\t// Collect all nodes: both keys and values (dependency targets)\n\tconst nodeSet = new Set<string>();\n\tfor (const [node, deps] of Object.entries(dependencyGraph)) {\n\t\tnodeSet.add(node);\n\t\tfor (const dep of deps) {\n\t\t\tnodeSet.add(dep);\n\t\t}\n\t}\n\tconst nodes = [...nodeSet];\n\tconst inDegree = new Map<string, number>();\n\tconst adjacency = new Map<string, string[]>();\n\n\tfor (const node of nodes) {\n\t\tinDegree.set(node, 0);\n\t\tadjacency.set(node, []);\n\t}\n\n\tfor (const [node, deps] of Object.entries(dependencyGraph)) {\n\t\tinDegree.set(node, deps.length);\n\t\tfor (const dep of deps) {\n\t\t\tconst adj = adjacency.get(dep);\n\t\t\tif (adj) {\n\t\t\t\tadj.push(node);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst queue: string[] = [];\n\tfor (const [node, degree] of inDegree) {\n\t\tif (degree === 0) {\n\t\t\tqueue.push(node);\n\t\t}\n\t}\n\n\tconst result: string[] = [];\n\twhile (queue.length > 0) {\n\t\t// Process in alphabetical order for stable sorting\n\t\tqueue.sort();\n\t\tconst node = queue.shift()!;\n\t\tresult.push(node);\n\n\t\tconst neighbors = adjacency.get(node) ?? [];\n\t\tfor (const neighbor of neighbors) {\n\t\t\tconst degree = (inDegree.get(neighbor) ?? 1) - 1;\n\t\t\tinDegree.set(neighbor, degree);\n\t\t\tif (degree === 0) {\n\t\t\t\tqueue.push(neighbor);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (result.length !== nodes.length) {\n\t\tthrow new Error(\"Circular dependency detected in dependency graph\");\n\t}\n\n\treturn result;\n}\n\n// ─── Workflow Classification ─────────────────────────────────────────────────\n\nconst BUGFIX_KEYWORDS = [\"bug\", \"fix\", \"error\", \"crash\", \"broken\", \"regression\", \"issue\", \"defect\", \"fault\"];\nconst ENHANCEMENT_KEYWORDS = [\"enhance\", \"improve\", \"upgrade\", \"extend\", \"add to\", \"expand\", \"optimize\"];\nconst REFACTOR_KEYWORDS = [\"refactor\", \"restructure\", \"reorganize\", \"clean up\", \"simplify\", \"modernize\"];\n\n/**\n * Classifies the workflow type from requirement text using keyword matching.\n */\nexport function classifyWorkflow(requirement: string): WorkflowClassification {\n\tconst lower = requirement.toLowerCase();\n\n\tconst bugfixScore = BUGFIX_KEYWORDS.filter((kw) => lower.includes(kw)).length;\n\tconst enhancementScore = ENHANCEMENT_KEYWORDS.filter((kw) => lower.includes(kw)).length;\n\tconst refactorScore = REFACTOR_KEYWORDS.filter((kw) => lower.includes(kw)).length;\n\n\tconst maxScore = Math.max(bugfixScore, enhancementScore, refactorScore);\n\n\tif (maxScore === 0) {\n\t\treturn {\n\t\t\ttype: \"new_feature\",\n\t\t\treason: \"No specific workflow keywords detected; defaulting to new_feature\",\n\t\t\tconfidence: 0.5,\n\t\t};\n\t}\n\n\tif (bugfixScore === maxScore && bugfixScore > enhancementScore && bugfixScore > refactorScore) {\n\t\treturn {\n\t\t\ttype: \"bugfix\",\n\t\t\treason: `Matched bugfix keywords: ${BUGFIX_KEYWORDS.filter((kw) => lower.includes(kw)).join(\", \")}`,\n\t\t\tconfidence: Math.min(0.9, 0.5 + bugfixScore * 0.1),\n\t\t};\n\t}\n\n\tif (refactorScore === maxScore && refactorScore > enhancementScore) {\n\t\treturn {\n\t\t\ttype: \"refactor\",\n\t\t\treason: `Matched refactor keywords: ${REFACTOR_KEYWORDS.filter((kw) => lower.includes(kw)).join(\", \")}`,\n\t\t\tconfidence: Math.min(0.9, 0.5 + refactorScore * 0.1),\n\t\t};\n\t}\n\n\tif (enhancementScore === maxScore) {\n\t\treturn {\n\t\t\ttype: \"enhancement\",\n\t\t\treason: `Matched enhancement keywords: ${ENHANCEMENT_KEYWORDS.filter((kw) => lower.includes(kw)).join(\", \")}`,\n\t\t\tconfidence: Math.min(0.9, 0.5 + enhancementScore * 0.1),\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: \"new_feature\",\n\t\treason: \"Ambiguous classification; defaulting to new_feature\",\n\t\tconfidence: 0.4,\n\t};\n}\n\n// ─── Feature ID Type Inference ───────────────────────────────────────────────\n\n/** Infers WorkflowType from the featureId prefix. Never returns \"mixed\". */\nexport function inferWorkflowType(featureId: string): Exclude<WorkflowType, \"mixed\"> {\n\tif (featureId.startsWith(\"fix-\")) return \"bugfix\";\n\tif (featureId.startsWith(\"enhance-\")) return \"enhancement\";\n\tif (featureId.startsWith(\"refactor-\")) return \"refactor\";\n\treturn \"new_feature\";\n}\n\n/** If the plan's workflowType is \"mixed\", infer from featureId; otherwise use the plan type as-is. */\nexport function resolveFeatureWorkflowType(\n\tfeatureId: string,\n\tplanWorkflowType: WorkflowType,\n): Exclude<WorkflowType, \"mixed\"> {\n\tif (planWorkflowType === \"mixed\") {\n\t\treturn inferWorkflowType(featureId);\n\t}\n\treturn planWorkflowType as Exclude<WorkflowType, \"mixed\">;\n}\n"]}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAkBA,0MAAgF;AAEhF,2IAA+H;AAC/H,MAAM,UAAU,eAAe,GAAmB;IACjD,OAAO;QACN;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE;SAClD;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;YAChC,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;YAChC,OAAO,EAAE,CAAC,gBAAgB,CAAC;YAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;SACvC;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,CAAC,SAAS,EAAE,gBAAgB,CAAC;YACrC,OAAO,EAAE,CAAC,sBAAsB,CAAC;YACjC,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC7C;QACD;YACC,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,sBAAsB,CAAC;YAC1E,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC5C;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,EAAE;SAC3C;KACD,CAAC;AAAA,CACF;AAED,6MAA+L;AAC/L,MAAM,UAAU,gBAAgB,GAAmB;IAClD,OAAO;QACN;YACC,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,CAAC,kBAAkB,CAAC;SAC7B;QACD;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE;SAClD;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,kBAAkB,CAAC;YACpD,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;YAChC,OAAO,EAAE,CAAC,gBAAgB,CAAC;YAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;SACvC;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,CAAC;YACzD,OAAO,EAAE,CAAC,sBAAsB,CAAC;YACjC,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC7C;QACD;YACC,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,CAAC;YAC9F,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC5C;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,EAAE;SAC3C;KACD,CAAC;AAAA,CACF;AAED,0GAA4F;AAC5F,MAAM,UAAU,WAAW,GAAmB;IAC7C,OAAO;QACN;YACC,KAAK,EAAE,eAAe;YACtB,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,eAAe;YACtB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,CAAC,cAAc,CAAC;YACzB,IAAI,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,EAAE,EAAE;YAC/C,mBAAmB,EAAE,IAAI;SACzB;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,cAAc,CAAC;YACxB,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,CAAC,cAAc,CAAC;YACxB,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,CAAC,cAAc,CAAC;YACxB,OAAO,EAAE,CAAC,gBAAgB,CAAC;YAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;SACvC;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC;YAC1C,OAAO,EAAE,CAAC,sBAAsB,CAAC;YACjC,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC7C;QACD;YACC,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,cAAc,EAAE,gBAAgB,EAAE,sBAAsB,CAAC;YAClE,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC5C;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,EAAE;SAC3C;KACD,CAAC;AAAA,CACF;AAED,mGAAuF;AACvF,MAAM,UAAU,aAAa,GAAmB;IAC/C,OAAO;QACN;YACC,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,CAAC,kBAAkB,CAAC;SAC7B;QACD;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,kBAAkB,CAAC;YAC5B,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE;SAClD;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,CAAC,WAAW,EAAE,kBAAkB,CAAC;YACzC,OAAO,EAAE,EAAE;SACX;QACD;YACC,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,CAAC,WAAW,EAAE,kBAAkB,CAAC;YACzC,OAAO,EAAE,CAAC,sBAAsB,CAAC;YACjC,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC5C;QACD;YACC,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,CAAC,WAAW,EAAE,kBAAkB,EAAE,sBAAsB,CAAC;YACjE,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;SAC5C;QACD;YACC,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,EAAE;SAC3C;KACD,CAAC;AAAA,CACF;AAED,sMAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,cAAc,CAC7B,IAAkB,EAClB,SAAiB,EACjB,OAA+B,EACb;IAClB,IAAI,KAAqB,CAAC;IAC1B,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,aAAa;YACjB,KAAK,GAAG,eAAe,EAAE,CAAC;YAC1B,MAAM;QACP,KAAK,aAAa;YACjB,KAAK,GAAG,gBAAgB,EAAE,CAAC;YAC3B,MAAM;QACP,KAAK,QAAQ;YACZ,KAAK,GAAG,WAAW,EAAE,CAAC;YACtB,MAAM;QACP,KAAK,UAAU;YACd,KAAK,GAAG,aAAa,EAAE,CAAC;YACxB,MAAM;QACP,KAAK,OAAO;YACX,MAAM,IAAI,KAAK,CACd,kIAAkI,CAClI,CAAC;IACJ,CAAC;IAED,OAAO;QACN,SAAS;QACT,YAAY,EAAE,IAAI;QAClB,KAAK;QACL,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,CAAC;QACpC,eAAe,EAAE,OAAO,EAAE,eAAe;QACzC,QAAQ,EAAE,OAAO,EAAE,QAAQ;KAC3B,CAAC;AAAA,CACF;AAED,wMAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,eAAyC,EAAY;IAC1F,+DAA+D;IAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtB,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5D,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,GAAG,EAAE,CAAC;gBACT,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,mDAAmD;QACnD,KAAK,CAAC,IAAI,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAElB,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/B,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd;AAED,wLAAgF;AAEhF,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC7G,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AACzG,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAEzG;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAA0B;IAC7E,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IAExC,MAAM,WAAW,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9E,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACxF,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAElF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAExE,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO;YACN,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,mEAAmE;YAC3E,UAAU,EAAE,GAAG;SACf,CAAC;IACH,CAAC;IAED,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,GAAG,gBAAgB,IAAI,WAAW,GAAG,aAAa,EAAE,CAAC;QAC/F,OAAO;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,4BAA4B,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACnG,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,GAAG,GAAG,CAAC;SAClD,CAAC;IACH,CAAC;IAED,IAAI,aAAa,KAAK,QAAQ,IAAI,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACpE,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,8BAA8B,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACvG,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,aAAa,GAAG,GAAG,CAAC;SACpD,CAAC;IACH,CAAC;IAED,IAAI,gBAAgB,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO;YACN,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,iCAAiC,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC7G,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,gBAAgB,GAAG,GAAG,CAAC;SACvD,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,qDAAqD;QAC7D,UAAU,EAAE,GAAG;KACf,CAAC;AAAA,CACF;AAED,oLAAgF;AAEhF,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAkC;IACpF,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClD,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,aAAa,CAAC;IAC3D,IAAI,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,UAAU,CAAC;IACzD,OAAO,aAAa,CAAC;AAAA,CACrB;AAED,sGAAsG;AACtG,MAAM,UAAU,0BAA0B,CACzC,SAAiB,EACjB,gBAA8B,EACG;IACjC,IAAI,gBAAgB,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,gBAAkD,CAAC;AAAA,CAC1D","sourcesContent":["import type { FeaturePipeline, PipelineStep, WorkflowType } from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Pipeline creation options */\nexport interface CreatePipelineOptions {\n\tparentFeatureId?: string;\n\tissueRef?: string;\n\tmaxRetries?: number;\n}\n\n/** Workflow classification result */\nexport interface WorkflowClassification {\n\ttype: WorkflowType;\n\treason: string;\n\tconfidence: number;\n}\n\n// ─── Step Templates ──────────────────────────────────────────────────────────\n\n/** new_feature: Design → Branch → Implement → Test → Regression → Review → PR/Merge (spec.md is pre-placed by orchestrator) */\nexport function newFeatureSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"architect\",\n\t\t\taction: \"design\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [\"design.md\"],\n\t\t\tgate: { type: \"file_exists\", target: \"design.md\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"implement\",\n\t\t\tinputs: [\"spec.md\", \"design.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"test\",\n\t\t\tinputs: [\"spec.md\", \"design.md\"],\n\t\t\toutputs: [\"test-report.md\"],\n\t\t\tgate: { type: \"test_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"spec.md\", \"test-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"regression_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"spec.md\", \"design.md\", \"test-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n/** enhancement: Analyze → Design → Branch → Implement → Test → Regression → Review → PR/Merge (spec.md is pre-placed by orchestrator; Analyze also runs at orchestration level for Planner) */\nexport function enhancementSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"analyzer\",\n\t\t\taction: \"analyze\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [\"impact-report.md\"],\n\t\t},\n\t\t{\n\t\t\tagent: \"architect\",\n\t\t\taction: \"design\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [\"design.md\"],\n\t\t\tgate: { type: \"file_exists\", target: \"design.md\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"implement\",\n\t\t\tinputs: [\"spec.md\", \"design.md\", \"impact-report.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"test\",\n\t\t\tinputs: [\"spec.md\", \"design.md\"],\n\t\t\toutputs: [\"test-report.md\"],\n\t\t\tgate: { type: \"test_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"spec.md\", \"impact-report.md\", \"test-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"regression_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"spec.md\", \"design.md\", \"impact-report.md\", \"test-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n/** bugfix: Investigate → Diagnose → Branch → Fix → Test → Regression → Review → PR/Merge */\nexport function bugfixSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"diagnostician\",\n\t\t\taction: \"investigate\",\n\t\t\tinputs: [],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"diagnostician\",\n\t\t\taction: \"diagnose\",\n\t\t\tinputs: [],\n\t\t\toutputs: [\"diagnosis.md\"],\n\t\t\tgate: { type: \"diagnosis_approve\", target: \"\" },\n\t\t\tinheritPriorHistory: true,\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"diagnosis.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"fix\",\n\t\t\tinputs: [\"diagnosis.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"test\",\n\t\t\tinputs: [\"diagnosis.md\"],\n\t\t\toutputs: [\"test-report.md\"],\n\t\t\tgate: { type: \"test_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"diagnosis.md\", \"test-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"regression_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"diagnosis.md\", \"test-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n/** refactor: Analyze → Design → Branch → Implement → Regression → Review → PR/Merge */\nexport function refactorSteps(): PipelineStep[] {\n\treturn [\n\t\t{\n\t\t\tagent: \"analyzer\",\n\t\t\taction: \"analyze\",\n\t\t\tinputs: [\"spec.md\"],\n\t\t\toutputs: [\"impact-report.md\"],\n\t\t},\n\t\t{\n\t\t\tagent: \"architect\",\n\t\t\taction: \"design\",\n\t\t\tinputs: [\"impact-report.md\"],\n\t\t\toutputs: [\"design.md\"],\n\t\t\tgate: { type: \"file_exists\", target: \"design.md\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"branch\",\n\t\t\tinputs: [\"design.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"developer\",\n\t\t\taction: \"implement\",\n\t\t\tinputs: [\"design.md\", \"impact-report.md\"],\n\t\t\toutputs: [],\n\t\t},\n\t\t{\n\t\t\tagent: \"tester\",\n\t\t\taction: \"regression\",\n\t\t\tinputs: [\"design.md\", \"impact-report.md\"],\n\t\t\toutputs: [\"regression-report.md\"],\n\t\t\tgate: { type: \"all_tests_pass\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"reviewer\",\n\t\t\taction: \"review\",\n\t\t\tinputs: [\"design.md\", \"impact-report.md\", \"regression-report.md\"],\n\t\t\toutputs: [\"review.md\"],\n\t\t\tgate: { type: \"review_approve\", target: \"\" },\n\t\t},\n\t\t{\n\t\t\tagent: \"cicd\",\n\t\t\taction: \"merge\",\n\t\t\tinputs: [\"review.md\"],\n\t\t\toutputs: [],\n\t\t\tgate: { type: \"merge_approve\", target: \"\" },\n\t\t},\n\t];\n}\n\n// ─── Pipeline Factory ────────────────────────────────────────────────────────\n\n/**\n * Creates a FeaturePipeline matching the given workflow type.\n */\nexport function createPipeline(\n\ttype: WorkflowType,\n\tfeatureId: string,\n\toptions?: CreatePipelineOptions,\n): FeaturePipeline {\n\tlet steps: PipelineStep[];\n\tswitch (type) {\n\t\tcase \"new_feature\":\n\t\t\tsteps = newFeatureSteps();\n\t\t\tbreak;\n\t\tcase \"enhancement\":\n\t\t\tsteps = enhancementSteps();\n\t\t\tbreak;\n\t\tcase \"bugfix\":\n\t\t\tsteps = bugfixSteps();\n\t\t\tbreak;\n\t\tcase \"refactor\":\n\t\t\tsteps = refactorSteps();\n\t\t\tbreak;\n\t\tcase \"mixed\":\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot create pipeline with workflowType \"mixed\". Resolve to a concrete type (new_feature, enhancement, bugfix, refactor) first.',\n\t\t\t);\n\t}\n\n\treturn {\n\t\tfeatureId,\n\t\tworkflowType: type,\n\t\tsteps,\n\t\tcurrentStep: 0,\n\t\tstatus: \"pending\",\n\t\tretryCount: 0,\n\t\tmaxRetries: options?.maxRetries ?? 3,\n\t\tparentFeatureId: options?.parentFeatureId,\n\t\tissueRef: options?.issueRef,\n\t};\n}\n\n// ─── Execution Order ─────────────────────────────────────────────────────────\n\n/**\n * Topologically sorts the dependency graph and returns the execution order.\n * Uses Kahn's algorithm. Throws on circular dependencies.\n */\nexport function resolveExecutionOrder(dependencyGraph: Record<string, string[]>): string[] {\n\t// Collect all nodes: both keys and values (dependency targets)\n\tconst nodeSet = new Set<string>();\n\tfor (const [node, deps] of Object.entries(dependencyGraph)) {\n\t\tnodeSet.add(node);\n\t\tfor (const dep of deps) {\n\t\t\tnodeSet.add(dep);\n\t\t}\n\t}\n\tconst nodes = [...nodeSet];\n\tconst inDegree = new Map<string, number>();\n\tconst adjacency = new Map<string, string[]>();\n\n\tfor (const node of nodes) {\n\t\tinDegree.set(node, 0);\n\t\tadjacency.set(node, []);\n\t}\n\n\tfor (const [node, deps] of Object.entries(dependencyGraph)) {\n\t\tinDegree.set(node, deps.length);\n\t\tfor (const dep of deps) {\n\t\t\tconst adj = adjacency.get(dep);\n\t\t\tif (adj) {\n\t\t\t\tadj.push(node);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst queue: string[] = [];\n\tfor (const [node, degree] of inDegree) {\n\t\tif (degree === 0) {\n\t\t\tqueue.push(node);\n\t\t}\n\t}\n\n\tconst result: string[] = [];\n\twhile (queue.length > 0) {\n\t\t// Process in alphabetical order for stable sorting\n\t\tqueue.sort();\n\t\tconst node = queue.shift()!;\n\t\tresult.push(node);\n\n\t\tconst neighbors = adjacency.get(node) ?? [];\n\t\tfor (const neighbor of neighbors) {\n\t\t\tconst degree = (inDegree.get(neighbor) ?? 1) - 1;\n\t\t\tinDegree.set(neighbor, degree);\n\t\t\tif (degree === 0) {\n\t\t\t\tqueue.push(neighbor);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (result.length !== nodes.length) {\n\t\tthrow new Error(\"Circular dependency detected in dependency graph\");\n\t}\n\n\treturn result;\n}\n\n// ─── Workflow Classification ─────────────────────────────────────────────────\n\nconst BUGFIX_KEYWORDS = [\"bug\", \"fix\", \"error\", \"crash\", \"broken\", \"regression\", \"issue\", \"defect\", \"fault\"];\nconst ENHANCEMENT_KEYWORDS = [\"enhance\", \"improve\", \"upgrade\", \"extend\", \"add to\", \"expand\", \"optimize\"];\nconst REFACTOR_KEYWORDS = [\"refactor\", \"restructure\", \"reorganize\", \"clean up\", \"simplify\", \"modernize\"];\n\n/**\n * Classifies the workflow type from requirement text using keyword matching.\n */\nexport function classifyWorkflow(requirement: string): WorkflowClassification {\n\tconst lower = requirement.toLowerCase();\n\n\tconst bugfixScore = BUGFIX_KEYWORDS.filter((kw) => lower.includes(kw)).length;\n\tconst enhancementScore = ENHANCEMENT_KEYWORDS.filter((kw) => lower.includes(kw)).length;\n\tconst refactorScore = REFACTOR_KEYWORDS.filter((kw) => lower.includes(kw)).length;\n\n\tconst maxScore = Math.max(bugfixScore, enhancementScore, refactorScore);\n\n\tif (maxScore === 0) {\n\t\treturn {\n\t\t\ttype: \"new_feature\",\n\t\t\treason: \"No specific workflow keywords detected; defaulting to new_feature\",\n\t\t\tconfidence: 0.5,\n\t\t};\n\t}\n\n\tif (bugfixScore === maxScore && bugfixScore > enhancementScore && bugfixScore > refactorScore) {\n\t\treturn {\n\t\t\ttype: \"bugfix\",\n\t\t\treason: `Matched bugfix keywords: ${BUGFIX_KEYWORDS.filter((kw) => lower.includes(kw)).join(\", \")}`,\n\t\t\tconfidence: Math.min(0.9, 0.5 + bugfixScore * 0.1),\n\t\t};\n\t}\n\n\tif (refactorScore === maxScore && refactorScore > enhancementScore) {\n\t\treturn {\n\t\t\ttype: \"refactor\",\n\t\t\treason: `Matched refactor keywords: ${REFACTOR_KEYWORDS.filter((kw) => lower.includes(kw)).join(\", \")}`,\n\t\t\tconfidence: Math.min(0.9, 0.5 + refactorScore * 0.1),\n\t\t};\n\t}\n\n\tif (enhancementScore === maxScore) {\n\t\treturn {\n\t\t\ttype: \"enhancement\",\n\t\t\treason: `Matched enhancement keywords: ${ENHANCEMENT_KEYWORDS.filter((kw) => lower.includes(kw)).join(\", \")}`,\n\t\t\tconfidence: Math.min(0.9, 0.5 + enhancementScore * 0.1),\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: \"new_feature\",\n\t\treason: \"Ambiguous classification; defaulting to new_feature\",\n\t\tconfidence: 0.4,\n\t};\n}\n\n// ─── Feature ID Type Inference ───────────────────────────────────────────────\n\n/** Infers WorkflowType from the featureId prefix. Never returns \"mixed\". */\nexport function inferWorkflowType(featureId: string): Exclude<WorkflowType, \"mixed\"> {\n\tif (featureId.startsWith(\"fix-\")) return \"bugfix\";\n\tif (featureId.startsWith(\"enhance-\")) return \"enhancement\";\n\tif (featureId.startsWith(\"refactor-\")) return \"refactor\";\n\treturn \"new_feature\";\n}\n\n/** If the plan's workflowType is \"mixed\", infer from featureId; otherwise use the plan type as-is. */\nexport function resolveFeatureWorkflowType(\n\tfeatureId: string,\n\tplanWorkflowType: WorkflowType,\n): Exclude<WorkflowType, \"mixed\"> {\n\tif (planWorkflowType === \"mixed\") {\n\t\treturn inferWorkflowType(featureId);\n\t}\n\treturn planWorkflowType as Exclude<WorkflowType, \"mixed\">;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"standards.d.ts","sourceRoot":"","sources":["../src/standards.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE1E,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,SAAS,EAAE,gBAAgB,EAAE,CAqDxE,CAAC;AA6DF;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKpH;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBpH;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAUtE","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, join, resolve } from \"node:path\";\nimport type { AgentRole, StandardFileName, VibeConfig } from \"./types.js\";\n\n/** Default standards mapping by role */\nexport const DEFAULT_ROLE_STANDARDS: Record<AgentRole, StandardFileName[]> = {\n\tplanner: [\".artifact-standards.md\"],\n\tarchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tdeveloper: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"tech-stack.md\",\n\t\t\"api-design.md\",\n\t\t\"documentation.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t],\n\ttester: [\"testing-standards.md\", \"coding-conventions.md\", \"performance-guidelines.md\", \".artifact-standards.md\"],\n\treviewer: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"architecture-principles.md\",\n\t\t\"api-design.md\",\n\t\t\"testing-standards.md\",\n\t\t\"documentation.md\",\n\t\t\"security-policy.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tcicd: [\"git-workflow.md\"],\n\tanalyzer: [\"architecture-principles.md\", \"tech-stack.md\", \".artifact-standards.md\"],\n\tdiagnostician: [\"coding-conventions.md\", \"observability.md\", \"logging.md\", \".artifact-standards.md\"],\n\tdiscovery: [\".artifact-standards.md\"],\n\tprojectAnalyzer: [\".artifact-standards.md\"],\n\tdocumenter: [\"documentation.md\", \".artifact-standards.md\"],\n\tstandardsEnricher: [],\n\tsystemArchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n};\n\n/** Checks whether a file exists. */\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Resolves a path to an absolute path relative to projectRoot. */\nfunction resolvePath(source: string, projectRoot: string): string {\n\tif (isAbsolute(source)) {\n\t\treturn source;\n\t}\n\treturn resolve(projectRoot, source);\n}\n\n/**\n * Traverses all source paths and returns a Map<filename, absolutePath> of discovered .md files.\n * When the same filename exists in multiple sources, the later source takes precedence.\n */\nasync function resolveStandardFiles(sources: string[], projectRoot: string): Promise<Map<string, string>> {\n\tconst result = new Map<string, string>();\n\n\tfor (const source of sources) {\n\t\tconst absPath = resolvePath(source, projectRoot);\n\t\tif (!(await fileExists(absPath))) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst info = await stat(absPath);\n\t\tif (info.isDirectory()) {\n\t\t\tconst entries = await readdir(absPath);\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (entry.endsWith(\".md\")) {\n\t\t\t\t\tresult.set(entry, join(absPath, entry));\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (info.isFile()) {\n\t\t\tresult.set(basename(absPath), absPath);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Determines the list of standard filenames mapped to a role.\n * Uses config.standards.roleMapping if the role exists there; otherwise uses DEFAULT_ROLE_STANDARDS.\n */\nfunction getRoleMappedFiles(role: AgentRole, config: VibeConfig): string[] {\n\tconst customMapping = config.standards.roleMapping;\n\tif (customMapping && role in customMapping) {\n\t\treturn customMapping[role] ?? DEFAULT_ROLE_STANDARDS[role];\n\t}\n\treturn DEFAULT_ROLE_STANDARDS[role];\n}\n\n/**\n * Returns the list of standard filenames that will actually be loaded for the given role (existing ones only).\n */\nexport async function getLoadedStandards(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string[]> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\treturn mappedFiles.filter((fileName) => availableFiles.has(fileName));\n}\n\n/**\n * Loads the standard files mapped to a role and returns them as a concatenated string.\n * Returns an empty string if no standard files are found.\n */\nexport async function loadStandardsForRole(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\tconst contents: string[] = [];\n\tfor (const fileName of mappedFiles) {\n\t\tconst filePath = availableFiles.get(fileName);\n\t\tif (filePath) {\n\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\tcontents.push(content.trim());\n\t\t}\n\t}\n\n\tif (contents.length === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn contents.join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Formats the loaded standards content as a system prompt section.\n * Returns an empty string if the input is empty.\n */\nexport function formatStandardsPrompt(standardsContent: string): string {\n\tif (!standardsContent) {\n\t\treturn \"\";\n\t}\n\n\treturn `## Organization Standards\n\nYou MUST follow these standards:\n\n${standardsContent}`;\n}\n"]}
1
+ {"version":3,"file":"standards.d.ts","sourceRoot":"","sources":["../src/standards.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE1E,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,SAAS,EAAE,gBAAgB,EAAE,CAsDxE,CAAC;AA6DF;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKpH;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBpH;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAUtE","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, join, resolve } from \"node:path\";\nimport type { AgentRole, StandardFileName, VibeConfig } from \"./types.js\";\n\n/** Default standards mapping by role */\nexport const DEFAULT_ROLE_STANDARDS: Record<AgentRole, StandardFileName[]> = {\n\tplanner: [\".artifact-standards.md\"],\n\tarchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tdeveloper: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"tech-stack.md\",\n\t\t\"api-design.md\",\n\t\t\"documentation.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t],\n\ttester: [\"testing-standards.md\", \"coding-conventions.md\", \"performance-guidelines.md\", \".artifact-standards.md\"],\n\treviewer: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"architecture-principles.md\",\n\t\t\"api-design.md\",\n\t\t\"testing-standards.md\",\n\t\t\"documentation.md\",\n\t\t\"security-policy.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tcicd: [\"git-workflow.md\"],\n\tanalyzer: [\"architecture-principles.md\", \"tech-stack.md\", \".artifact-standards.md\"],\n\tdiagnostician: [\"coding-conventions.md\", \"observability.md\", \"logging.md\", \".artifact-standards.md\"],\n\tdiscovery: [\".artifact-standards.md\"],\n\tprojectAnalyzer: [\".artifact-standards.md\"],\n\tdocumenter: [\"documentation.md\", \".artifact-standards.md\"],\n\tstandardsEnricher: [],\n\trecover: [],\n\tsystemArchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n};\n\n/** Checks whether a file exists. */\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Resolves a path to an absolute path relative to projectRoot. */\nfunction resolvePath(source: string, projectRoot: string): string {\n\tif (isAbsolute(source)) {\n\t\treturn source;\n\t}\n\treturn resolve(projectRoot, source);\n}\n\n/**\n * Traverses all source paths and returns a Map<filename, absolutePath> of discovered .md files.\n * When the same filename exists in multiple sources, the later source takes precedence.\n */\nasync function resolveStandardFiles(sources: string[], projectRoot: string): Promise<Map<string, string>> {\n\tconst result = new Map<string, string>();\n\n\tfor (const source of sources) {\n\t\tconst absPath = resolvePath(source, projectRoot);\n\t\tif (!(await fileExists(absPath))) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst info = await stat(absPath);\n\t\tif (info.isDirectory()) {\n\t\t\tconst entries = await readdir(absPath);\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (entry.endsWith(\".md\")) {\n\t\t\t\t\tresult.set(entry, join(absPath, entry));\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (info.isFile()) {\n\t\t\tresult.set(basename(absPath), absPath);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Determines the list of standard filenames mapped to a role.\n * Uses config.standards.roleMapping if the role exists there; otherwise uses DEFAULT_ROLE_STANDARDS.\n */\nfunction getRoleMappedFiles(role: AgentRole, config: VibeConfig): string[] {\n\tconst customMapping = config.standards.roleMapping;\n\tif (customMapping && role in customMapping) {\n\t\treturn customMapping[role] ?? DEFAULT_ROLE_STANDARDS[role];\n\t}\n\treturn DEFAULT_ROLE_STANDARDS[role];\n}\n\n/**\n * Returns the list of standard filenames that will actually be loaded for the given role (existing ones only).\n */\nexport async function getLoadedStandards(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string[]> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\treturn mappedFiles.filter((fileName) => availableFiles.has(fileName));\n}\n\n/**\n * Loads the standard files mapped to a role and returns them as a concatenated string.\n * Returns an empty string if no standard files are found.\n */\nexport async function loadStandardsForRole(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\tconst contents: string[] = [];\n\tfor (const fileName of mappedFiles) {\n\t\tconst filePath = availableFiles.get(fileName);\n\t\tif (filePath) {\n\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\tcontents.push(content.trim());\n\t\t}\n\t}\n\n\tif (contents.length === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn contents.join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Formats the loaded standards content as a system prompt section.\n * Returns an empty string if the input is empty.\n */\nexport function formatStandardsPrompt(standardsContent: string): string {\n\tif (!standardsContent) {\n\t\treturn \"\";\n\t}\n\n\treturn `## Organization Standards\n\nYou MUST follow these standards:\n\n${standardsContent}`;\n}\n"]}
package/dist/standards.js CHANGED
@@ -46,6 +46,7 @@ export const DEFAULT_ROLE_STANDARDS = {
46
46
  projectAnalyzer: [".artifact-standards.md"],
47
47
  documenter: ["documentation.md", ".artifact-standards.md"],
48
48
  standardsEnricher: [],
49
+ recover: [],
49
50
  systemArchitect: [
50
51
  "architecture-principles.md",
51
52
  "tech-stack.md",
@@ -1 +1 @@
1
- {"version":3,"file":"standards.js","sourceRoot":"","sources":["../src/standards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGhE,wCAAwC;AACxC,MAAM,CAAC,MAAM,sBAAsB,GAA0C;IAC5E,OAAO,EAAE,CAAC,wBAAwB,CAAC;IACnC,SAAS,EAAE;QACV,4BAA4B;QAC5B,eAAe;QACf,iBAAiB;QACjB,eAAe;QACf,oBAAoB;QACpB,wBAAwB;KACxB;IACD,SAAS,EAAE;QACV,iBAAiB;QACjB,uBAAuB;QACvB,eAAe;QACf,eAAe;QACf,kBAAkB;QAClB,sBAAsB;QACtB,2BAA2B;QAC3B,kBAAkB;QAClB,kBAAkB;QAClB,YAAY;KACZ;IACD,MAAM,EAAE,CAAC,sBAAsB,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,wBAAwB,CAAC;IAChH,QAAQ,EAAE;QACT,iBAAiB;QACjB,uBAAuB;QACvB,4BAA4B;QAC5B,eAAe;QACf,sBAAsB;QACtB,kBAAkB;QAClB,oBAAoB;QACpB,sBAAsB;QACtB,2BAA2B;QAC3B,kBAAkB;QAClB,kBAAkB;QAClB,YAAY;QACZ,wBAAwB;KACxB;IACD,IAAI,EAAE,CAAC,iBAAiB,CAAC;IACzB,QAAQ,EAAE,CAAC,4BAA4B,EAAE,eAAe,EAAE,wBAAwB,CAAC;IACnF,aAAa,EAAE,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,YAAY,EAAE,wBAAwB,CAAC;IACpG,SAAS,EAAE,CAAC,wBAAwB,CAAC;IACrC,eAAe,EAAE,CAAC,wBAAwB,CAAC;IAC3C,UAAU,EAAE,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;IAC1D,iBAAiB,EAAE,EAAE;IACrB,eAAe,EAAE;QAChB,4BAA4B;QAC5B,eAAe;QACf,iBAAiB;QACjB,eAAe;QACf,oBAAoB;QACpB,wBAAwB;KACxB;CACD,CAAC;AAEF,oCAAoC;AACpC,KAAK,UAAU,UAAU,CAAC,IAAY,EAAoB;IACzD,IAAI,CAAC;QACJ,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AAAA,CACD;AAED,mEAAmE;AACnE,SAAS,WAAW,CAAC,MAAc,EAAE,WAAmB,EAAU;IACjE,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAAA,CACpC;AAED;;;GAGG;AACH,KAAK,UAAU,oBAAoB,CAAC,OAAiB,EAAE,WAAmB,EAAgC;IACzG,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YAClC,SAAS;QACV,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACvC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;gBACzC,CAAC;YACF,CAAC;QACF,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,IAAe,EAAE,MAAkB,EAAY;IAC1E,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;IACnD,IAAI,aAAa,IAAI,IAAI,IAAI,aAAa,EAAE,CAAC;QAC5C,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC;AAAA,CACpC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAe,EAAE,MAAkB,EAAE,WAAmB,EAAqB;IACrH,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACzF,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAErD,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAA,CACtE;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAe,EAAE,MAAkB,EAAE,WAAmB,EAAmB;IACrH,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACzF,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,QAAQ,IAAI,WAAW,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,QAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC;IACF,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAAA,CACpC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,gBAAwB,EAAU;IACvE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO;;;;EAIN,gBAAgB,EAAE,CAAC;AAAA,CACpB","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, join, resolve } from \"node:path\";\nimport type { AgentRole, StandardFileName, VibeConfig } from \"./types.js\";\n\n/** Default standards mapping by role */\nexport const DEFAULT_ROLE_STANDARDS: Record<AgentRole, StandardFileName[]> = {\n\tplanner: [\".artifact-standards.md\"],\n\tarchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tdeveloper: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"tech-stack.md\",\n\t\t\"api-design.md\",\n\t\t\"documentation.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t],\n\ttester: [\"testing-standards.md\", \"coding-conventions.md\", \"performance-guidelines.md\", \".artifact-standards.md\"],\n\treviewer: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"architecture-principles.md\",\n\t\t\"api-design.md\",\n\t\t\"testing-standards.md\",\n\t\t\"documentation.md\",\n\t\t\"security-policy.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tcicd: [\"git-workflow.md\"],\n\tanalyzer: [\"architecture-principles.md\", \"tech-stack.md\", \".artifact-standards.md\"],\n\tdiagnostician: [\"coding-conventions.md\", \"observability.md\", \"logging.md\", \".artifact-standards.md\"],\n\tdiscovery: [\".artifact-standards.md\"],\n\tprojectAnalyzer: [\".artifact-standards.md\"],\n\tdocumenter: [\"documentation.md\", \".artifact-standards.md\"],\n\tstandardsEnricher: [],\n\tsystemArchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n};\n\n/** Checks whether a file exists. */\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Resolves a path to an absolute path relative to projectRoot. */\nfunction resolvePath(source: string, projectRoot: string): string {\n\tif (isAbsolute(source)) {\n\t\treturn source;\n\t}\n\treturn resolve(projectRoot, source);\n}\n\n/**\n * Traverses all source paths and returns a Map<filename, absolutePath> of discovered .md files.\n * When the same filename exists in multiple sources, the later source takes precedence.\n */\nasync function resolveStandardFiles(sources: string[], projectRoot: string): Promise<Map<string, string>> {\n\tconst result = new Map<string, string>();\n\n\tfor (const source of sources) {\n\t\tconst absPath = resolvePath(source, projectRoot);\n\t\tif (!(await fileExists(absPath))) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst info = await stat(absPath);\n\t\tif (info.isDirectory()) {\n\t\t\tconst entries = await readdir(absPath);\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (entry.endsWith(\".md\")) {\n\t\t\t\t\tresult.set(entry, join(absPath, entry));\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (info.isFile()) {\n\t\t\tresult.set(basename(absPath), absPath);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Determines the list of standard filenames mapped to a role.\n * Uses config.standards.roleMapping if the role exists there; otherwise uses DEFAULT_ROLE_STANDARDS.\n */\nfunction getRoleMappedFiles(role: AgentRole, config: VibeConfig): string[] {\n\tconst customMapping = config.standards.roleMapping;\n\tif (customMapping && role in customMapping) {\n\t\treturn customMapping[role] ?? DEFAULT_ROLE_STANDARDS[role];\n\t}\n\treturn DEFAULT_ROLE_STANDARDS[role];\n}\n\n/**\n * Returns the list of standard filenames that will actually be loaded for the given role (existing ones only).\n */\nexport async function getLoadedStandards(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string[]> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\treturn mappedFiles.filter((fileName) => availableFiles.has(fileName));\n}\n\n/**\n * Loads the standard files mapped to a role and returns them as a concatenated string.\n * Returns an empty string if no standard files are found.\n */\nexport async function loadStandardsForRole(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\tconst contents: string[] = [];\n\tfor (const fileName of mappedFiles) {\n\t\tconst filePath = availableFiles.get(fileName);\n\t\tif (filePath) {\n\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\tcontents.push(content.trim());\n\t\t}\n\t}\n\n\tif (contents.length === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn contents.join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Formats the loaded standards content as a system prompt section.\n * Returns an empty string if the input is empty.\n */\nexport function formatStandardsPrompt(standardsContent: string): string {\n\tif (!standardsContent) {\n\t\treturn \"\";\n\t}\n\n\treturn `## Organization Standards\n\nYou MUST follow these standards:\n\n${standardsContent}`;\n}\n"]}
1
+ {"version":3,"file":"standards.js","sourceRoot":"","sources":["../src/standards.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, join, resolve } from \"node:path\";\nimport type { AgentRole, StandardFileName, VibeConfig } from \"./types.js\";\n\n/** Default standards mapping by role */\nexport const DEFAULT_ROLE_STANDARDS: Record<AgentRole, StandardFileName[]> = {\n\tplanner: [\".artifact-standards.md\"],\n\tarchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tdeveloper: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"tech-stack.md\",\n\t\t\"api-design.md\",\n\t\t\"documentation.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t],\n\ttester: [\"testing-standards.md\", \"coding-conventions.md\", \"performance-guidelines.md\", \".artifact-standards.md\"],\n\treviewer: [\n\t\t\"coding-style.md\",\n\t\t\"coding-conventions.md\",\n\t\t\"architecture-principles.md\",\n\t\t\"api-design.md\",\n\t\t\"testing-standards.md\",\n\t\t\"documentation.md\",\n\t\t\"security-policy.md\",\n\t\t\"dependency-policy.md\",\n\t\t\"performance-guidelines.md\",\n\t\t\"accessibility.md\",\n\t\t\"observability.md\",\n\t\t\"logging.md\",\n\t\t\".artifact-standards.md\",\n\t],\n\tcicd: [\"git-workflow.md\"],\n\tanalyzer: [\"architecture-principles.md\", \"tech-stack.md\", \".artifact-standards.md\"],\n\tdiagnostician: [\"coding-conventions.md\", \"observability.md\", \"logging.md\", \".artifact-standards.md\"],\n\tdiscovery: [\".artifact-standards.md\"],\n\tprojectAnalyzer: [\".artifact-standards.md\"],\n\tdocumenter: [\"documentation.md\", \".artifact-standards.md\"],\n\tstandardsEnricher: [],\n\trecover: [],\n\tsystemArchitect: [\n\t\t\"architecture-principles.md\",\n\t\t\"tech-stack.md\",\n\t\t\"design-guide.md\",\n\t\t\"api-design.md\",\n\t\t\"security-policy.md\",\n\t\t\".artifact-standards.md\",\n\t],\n};\n\n/** Checks whether a file exists. */\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Resolves a path to an absolute path relative to projectRoot. */\nfunction resolvePath(source: string, projectRoot: string): string {\n\tif (isAbsolute(source)) {\n\t\treturn source;\n\t}\n\treturn resolve(projectRoot, source);\n}\n\n/**\n * Traverses all source paths and returns a Map<filename, absolutePath> of discovered .md files.\n * When the same filename exists in multiple sources, the later source takes precedence.\n */\nasync function resolveStandardFiles(sources: string[], projectRoot: string): Promise<Map<string, string>> {\n\tconst result = new Map<string, string>();\n\n\tfor (const source of sources) {\n\t\tconst absPath = resolvePath(source, projectRoot);\n\t\tif (!(await fileExists(absPath))) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst info = await stat(absPath);\n\t\tif (info.isDirectory()) {\n\t\t\tconst entries = await readdir(absPath);\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (entry.endsWith(\".md\")) {\n\t\t\t\t\tresult.set(entry, join(absPath, entry));\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (info.isFile()) {\n\t\t\tresult.set(basename(absPath), absPath);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Determines the list of standard filenames mapped to a role.\n * Uses config.standards.roleMapping if the role exists there; otherwise uses DEFAULT_ROLE_STANDARDS.\n */\nfunction getRoleMappedFiles(role: AgentRole, config: VibeConfig): string[] {\n\tconst customMapping = config.standards.roleMapping;\n\tif (customMapping && role in customMapping) {\n\t\treturn customMapping[role] ?? DEFAULT_ROLE_STANDARDS[role];\n\t}\n\treturn DEFAULT_ROLE_STANDARDS[role];\n}\n\n/**\n * Returns the list of standard filenames that will actually be loaded for the given role (existing ones only).\n */\nexport async function getLoadedStandards(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string[]> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\treturn mappedFiles.filter((fileName) => availableFiles.has(fileName));\n}\n\n/**\n * Loads the standard files mapped to a role and returns them as a concatenated string.\n * Returns an empty string if no standard files are found.\n */\nexport async function loadStandardsForRole(role: AgentRole, config: VibeConfig, projectRoot: string): Promise<string> {\n\tconst availableFiles = await resolveStandardFiles(config.standards.sources, projectRoot);\n\tconst mappedFiles = getRoleMappedFiles(role, config);\n\n\tconst contents: string[] = [];\n\tfor (const fileName of mappedFiles) {\n\t\tconst filePath = availableFiles.get(fileName);\n\t\tif (filePath) {\n\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\tcontents.push(content.trim());\n\t\t}\n\t}\n\n\tif (contents.length === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn contents.join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Formats the loaded standards content as a system prompt section.\n * Returns an empty string if the input is empty.\n */\nexport function formatStandardsPrompt(standardsContent: string): string {\n\tif (!standardsContent) {\n\t\treturn \"\";\n\t}\n\n\treturn `## Organization Standards\n\nYou MUST follow these standards:\n\n${standardsContent}`;\n}\n"]}
@@ -3,6 +3,8 @@ import type { StepContext, StepExecutor, StepUsage } from "./pipeline.js";
3
3
  import type { AgentRole, PipelineStep, TestingConfig } from "./types.js";
4
4
  /** Determines whether the role is readonly (cannot write files via tools). */
5
5
  export declare function isReadonlyRole(role: AgentRole): boolean;
6
+ /** Roles that receive system-design.md as additional input context. */
7
+ export declare const SYSTEM_DESIGN_ROLES: ReadonlySet<AgentRole>;
6
8
  /**
7
9
  * Aggregates token usage from all assistant messages in a conversation.
8
10
  * Returns undefined if no assistant messages with usage data are found.
@@ -1 +1 @@
1
- {"version":3,"file":"step-executor.d.ts","sourceRoot":"","sources":["../src/step-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAgB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAcvF,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEvD;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,SAAS,GAAG,SAAS,CA8B9E;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBnH;AAQD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,cAAc,GAAE,OAAe,GAC7B,MAAM,GAAG,IAAI,CA6Bf;AAwGD;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,MAAM,GAClB,MAAM,CA4FR;AAsDD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAgHjC,CAAC","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { createModuleLogger, noopLogger } from \"./logger.js\";\nimport type { StepContext, StepExecutor, StepUsage } from \"./pipeline.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport type { AgentRole, ArtifactName, PipelineStep, TestingConfig } from \"./types.js\";\n\n// ─── Readonly Role Detection ─────────────────────────────────────────────────\n\n/** Roles that cannot write files via tools. Artifacts are extracted from the response and saved to the store. */\nconst READONLY_ROLES: ReadonlySet<AgentRole> = new Set<AgentRole>([\n\t\"planner\",\n\t\"analyzer\",\n\t\"reviewer\",\n\t\"diagnostician\",\n\t\"discovery\",\n\t\"projectAnalyzer\",\n]);\n\n/** Determines whether the role is readonly (cannot write files via tools). */\nexport function isReadonlyRole(role: AgentRole): boolean {\n\treturn READONLY_ROLES.has(role);\n}\n\n// ─── Usage Aggregation ───────────────────────────────────────────────────────\n\n/**\n * Aggregates token usage from all assistant messages in a conversation.\n * Returns undefined if no assistant messages with usage data are found.\n */\nexport function aggregateUsage(messages: AgentMessage[]): StepUsage | undefined {\n\tlet input = 0;\n\tlet output = 0;\n\tlet cacheRead = 0;\n\tlet cacheWrite = 0;\n\tlet totalTokens = 0;\n\tlet cost = 0;\n\tlet found = false;\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"assistant\" && \"usage\" in msg && msg.usage) {\n\t\t\tconst u = msg.usage as {\n\t\t\t\tinput: number;\n\t\t\t\toutput: number;\n\t\t\t\tcacheRead: number;\n\t\t\t\tcacheWrite: number;\n\t\t\t\ttotalTokens: number;\n\t\t\t\tcost: { total: number };\n\t\t\t};\n\t\t\tfound = true;\n\t\t\tinput += u.input;\n\t\t\toutput += u.output;\n\t\t\tcacheRead += u.cacheRead;\n\t\t\tcacheWrite += u.cacheWrite;\n\t\t\ttotalTokens += u.totalTokens;\n\t\t\tcost += u.cost.total;\n\t\t}\n\t}\n\n\treturn found ? { input, output, cacheRead, cacheWrite, totalTokens, cost } : undefined;\n}\n\n// ─── Input Artifact Loader ───────────────────────────────────────────────────\n\n/**\n * Reads the artifact files specified in step.inputs from the store\n * and combines them into a single context string.\n * Non-existent files are skipped.\n */\nexport async function loadInputArtifacts(inputs: string[], featureId: string, context: StepContext): Promise<string> {\n\tif (inputs.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst sections: string[] = [];\n\n\tfor (const input of inputs) {\n\t\tconst hasFile = await context.store.hasArtifact(featureId, input as ArtifactName);\n\t\tif (!hasFile) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst content = await context.store.readArtifact(featureId, input as ArtifactName);\n\t\tsections.push(`## Input: ${input}\\n\\n${content}`);\n\t}\n\n\treturn sections.join(\"\\n\\n---\\n\\n\");\n}\n\n// ─── Artifact Extraction ─────────────────────────────────────────────────────\n\nfunction escapeRegex(str: string): string {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Extracts artifact content from agent response text.\n * Used when a readonly role outputs markdown artifacts as text.\n *\n * Extraction strategies:\n * 1. Extract from ```artifactName code block (with nested fence pairing)\n * 2. Extract from ## artifactName section\n * 3. Return the entire response if it's a single output\n */\nexport function extractArtifactContent(\n\tresponseText: string,\n\tartifactName: string,\n\tisSingleOutput: boolean = false,\n): string | null {\n\tif (!responseText.trim()) {\n\t\treturn null;\n\t}\n\n\t// Pattern 1: ```artifactName\\n...\\n``` with nested code fence pairing.\n\t// A simple non-greedy regex fails when the content itself contains ``` fences\n\t// (e.g., directory trees or code examples inside a project-context.md artifact).\n\t// Instead, we find the opening fence and then iterate through subsequent fence\n\t// markers, pairing them (inner-open, inner-close) until we find the unpaired\n\t// closing fence for the outer block.\n\tconst content1 = extractFromCodeFence(responseText, artifactName);\n\tif (content1 !== null) {\n\t\treturn content1;\n\t}\n\n\t// Pattern 2: Content after ## artifactName (without m flag so $ matches end of string)\n\tconst pattern2 = new RegExp(`##\\\\s+${escapeRegex(artifactName)}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n##\\\\s|$)`);\n\tconst match2 = pattern2.exec(responseText);\n\tif (match2) {\n\t\treturn match2[1].trim();\n\t}\n\n\t// Pattern 3: Use the entire response if it's a single output\n\tif (isSingleOutput) {\n\t\treturn responseText.trim();\n\t}\n\n\treturn null;\n}\n\n/**\n * Extracts content from a fenced code block that may contain nested code fences.\n *\n * Algorithm:\n * 1. Find the opening fence (``` followed by artifactName)\n * 2. After the opening, scan for all ``` markers on their own lines\n * 3. Inner fences pair up sequentially (open+close). The first unpaired marker\n * is the closing fence of the outer block.\n */\nfunction extractFromCodeFence(text: string, artifactName: string): string | null {\n\t// Match the opening fence line: ```artifactName (possibly with trailing whitespace)\n\tconst openPattern = new RegExp(`^(\\`{3,})${escapeRegex(artifactName)}[ \\\\t]*$`, \"m\");\n\tconst openMatch = openPattern.exec(text);\n\tif (!openMatch) {\n\t\treturn null;\n\t}\n\n\tconst openTickCount = openMatch[1].length;\n\tconst contentStart = openMatch.index + openMatch[0].length + 1; // +1 for the newline\n\n\t// Collect fence markers after the opening fence, stopping at the next\n\t// artifact-level opening fence (a fence whose info string looks like a\n\t// file path — contains '.' or '/'). This prevents consuming fences that\n\t// belong to subsequent artifacts in multi-artifact responses.\n\tconst rest = text.slice(contentStart);\n\tconst fencePattern = /^(`{3,})[ \\t]*(\\S*)?[ \\t]*$/gm;\n\n\tinterface FenceMarker {\n\t\tindex: number;\n\t\ttickCount: number;\n\t\tinfoString: string;\n\t}\n\n\tconst markers: FenceMarker[] = [];\n\tfor (;;) {\n\t\tconst match = fencePattern.exec(rest);\n\t\tif (match === null) break;\n\t\tconst infoString = match[2] || \"\";\n\n\t\t// Stop at the next artifact-level opening fence (file-like info string)\n\t\tif (infoString !== \"\" && isArtifactInfoString(infoString)) {\n\t\t\tbreak;\n\t\t}\n\n\t\tmarkers.push({\n\t\t\tindex: match.index,\n\t\t\ttickCount: match[1].length,\n\t\t\tinfoString,\n\t\t});\n\t}\n\n\tif (markers.length === 0) {\n\t\treturn null;\n\t}\n\n\t// Within the bounded markers, find the outer closing fence.\n\t// Use the last bare fence (no info string) with >= openTickCount backticks.\n\t// Inner bare fences pair up (open+close) before it; the remaining one is\n\t// the outer close.\n\tfor (let i = markers.length - 1; i >= 0; i--) {\n\t\tconst m = markers[i];\n\t\tif (m.infoString === \"\" && m.tickCount >= openTickCount) {\n\t\t\tconst content = rest.slice(0, m.index);\n\t\t\treturn content.trim();\n\t\t}\n\t}\n\n\t// No valid closing fence found — return null (fall through to other patterns)\n\treturn null;\n}\n\n/**\n * Determines if a code fence info string looks like an artifact file path\n * rather than a code language identifier.\n *\n * Artifact info strings contain '.' (file extension) or '/' (path separator),\n * e.g., \"spec.md\", \"feat-auth/spec.md\", \"plan.json\".\n * Code language info strings are simple identifiers like \"python\", \"bash\", \"json\", \"text\".\n */\nfunction isArtifactInfoString(infoString: string): boolean {\n\treturn infoString.includes(\".\") || infoString.includes(\"/\");\n}\n\n// ─── Skill Search Instructions ───────────────────────────────────────────────\n\n/**\n * Instructions for searching past artifacts to add to specific actions when availableSkills is present.\n * The \"past feature artifacts\" keyword matches the qmd-memory description in Available Skills.\n */\nconst SKILL_SEARCH_INSTRUCTIONS: Readonly<Record<string, string>> = {\n\tplan: \"Before planning, search past feature artifacts for similar features, design patterns, or recurring decisions.\",\n\tdesign: \"Before designing, search past feature artifacts for related design patterns and architectural decisions.\",\n\ttest: \"Search past feature artifacts for related test patterns, integration points, and previously discovered defects before writing tests.\",\n\tregression:\n\t\t\"Search past feature artifacts for areas previously affected by regressions before running regression tests.\",\n\treview: \"Search past feature artifacts for recurring review feedback and common issues before reviewing.\",\n\tinvestigate: \"Search past feature artifacts for similar issues and prior investigation findings.\",\n\tdiagnose: \"Search past feature artifacts for similar bug patterns and fix strategies.\",\n};\n\n// ─── Action Prompt Builder ───────────────────────────────────────────────────\n\n/**\n * Builds the prompt to send to the agent based on the step's agent role and action.\n */\nexport function buildActionPrompt(\n\tstep: PipelineStep,\n\tfeatureId: string,\n\tinputContent: string,\n\tartifactDir: string,\n\tavailableSkills?: string,\n\tbaseBranch?: string,\n\ttestingConfig?: TestingConfig,\n\tprojectRoot?: string,\n): string {\n\tconst parts: string[] = [];\n\n\tparts.push(`You are working on feature \"${featureId}\".`);\n\tif (projectRoot) {\n\t\tparts.push(\n\t\t\t`The project root is \\`${projectRoot}\\`. All tool commands (bash, read, write, edit) ` +\n\t\t\t\t`execute relative to this directory. Do NOT prefix commands with \\`cd\\` to a different base directory.`,\n\t\t);\n\t}\n\tparts.push(\"\");\n\tparts.push(`## Task: ${step.action}`);\n\tparts.push(\"\");\n\tparts.push(getActionInstructions(step.agent, step.action, baseBranch));\n\n\tif (availableSkills) {\n\t\tconst skillInstruction = SKILL_SEARCH_INSTRUCTIONS[step.action];\n\t\tif (skillInstruction) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(skillInstruction);\n\t\t}\n\t}\n\n\tif (inputContent) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Input Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(inputContent);\n\t}\n\n\tif (step.outputs.length > 0) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Output Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(\"You must produce the following artifacts:\");\n\t\tfor (const output of step.outputs) {\n\t\t\tparts.push(`- \\`${output}\\` → \\`${artifactDir}/${output}\\``);\n\t\t}\n\n\t\tif (isReadonlyRole(step.agent)) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"Since you cannot write files directly, output the content of each artifact \" +\n\t\t\t\t\t\"in a markdown code block with the artifact filename as the info string. \" +\n\t\t\t\t\t\"For example: ```spec.md\\\\n(content)\\\\n```\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"Write each artifact directly to the specified file path using your tools.\");\n\t\t}\n\t}\n\n\t// Inject testing config for developer and tester actions\n\tif (testingConfig?.testCommand) {\n\t\tconst shouldInject =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInject) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## Project Test Configuration\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(`- **Test command**: \\`${testingConfig.testCommand}\\``);\n\t\t\tparts.push(`- **Timeout**: ${testingConfig.testTimeout} seconds`);\n\t\t\tparts.push(`- **Run existing tests**: ${testingConfig.runExistingTests}`);\n\t\t\tif (testingConfig.excludePatterns.length > 0) {\n\t\t\t\tparts.push(`- **Exclude patterns**: ${testingConfig.excludePatterns.join(\", \")}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Inject CI checks for developer and tester actions (tester can write/edit files too)\n\tif (testingConfig?.ciChecks && testingConfig.ciChecks.length > 0) {\n\t\tconst shouldInjectCiChecks =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInjectCiChecks) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## CI Verification Commands\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"You MUST run the following checks after implementation. All must pass before the task is complete.\",\n\t\t\t);\n\t\t\tparts.push(\"\");\n\t\t\tfor (const check of testingConfig.ciChecks) {\n\t\t\t\tparts.push(`- **${check.name}**: \\`${check.command}\\``);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n\n/**\n * Returns instructions for the given action.\n */\nfunction getActionInstructions(agent: AgentRole, action: string, baseBranch?: string): string {\n\tswitch (action) {\n\t\tcase \"plan\":\n\t\t\treturn \"Analyze the requirements and decompose them into features. Produce a spec.md for each feature and update plan.json.\";\n\n\t\tcase \"design\":\n\t\t\treturn \"Read the spec and produce a detailed design document with file structure, interfaces, and implementation guide.\";\n\n\t\tcase \"implement\":\n\t\t\treturn \"Implement the feature according to the spec and design documents. Write source code files and ensure they compile.\";\n\n\t\tcase \"fix\":\n\t\t\treturn \"Fix the bug as described in the diagnosis. Apply the minimal change necessary.\";\n\n\t\tcase \"test\":\n\t\t\treturn \"Write comprehensive tests for the feature and run them. Produce a test-report.md with results.\";\n\n\t\tcase \"regression\":\n\t\t\treturn \"Run existing tests to verify no regressions were introduced. Produce a regression-report.md with results.\";\n\n\t\tcase \"review\":\n\t\t\treturn \"Review the implementation for correctness, quality, architecture compliance, and standards compliance. Produce a review.md with your verdict.\";\n\n\t\tcase \"branch\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Create a feature branch from \\`${baseBranch}\\`. Run \\`git checkout ${baseBranch}\\` first, then create the branch.`\n\t\t\t\t: `Create a feature branch for ${agent === \"cicd\" ? \"this feature\" : \"the implementation\"}.`;\n\n\t\tcase \"merge\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Merge the feature branch into \\`${baseBranch}\\` using \\`--no-ff\\`. Run \\`git checkout ${baseBranch}\\` first, then merge. Do NOT run \\`git push\\` — push is handled by the orchestration system.`\n\t\t\t\t: \"Merge the feature branch after all checks pass. Do NOT run `git push`.\";\n\n\t\tcase \"analyze\":\n\t\t\treturn \"Analyze the impact of the proposed change on the existing codebase. Produce an impact-report.md.\";\n\n\t\tcase \"investigate\":\n\t\t\treturn \"Trace through the code to identify the root cause of the issue. Use read and bash tools to explore the codebase, run tests, add debug output if needed. Do not produce any artifacts — this is an exploratory step. Your findings will inform the subsequent diagnosis step.\";\n\n\t\tcase \"diagnose\":\n\t\t\treturn \"Analyze the bug, reproduce it, identify the root cause, and produce a diagnosis.md.\";\n\n\t\tdefault:\n\t\t\treturn `Execute the \"${action}\" task for this feature.`;\n\t}\n}\n\n// ─── Default Step Executor ───────────────────────────────────────────────────\n\n/**\n * Default StepExecutor implementation.\n * Creates a role-specific agent, passes input artifacts as context,\n * runs the agent, and saves the output artifacts.\n */\nexport const defaultStepExecutor: StepExecutor = async (step, featureId, context) => {\n\tconst { store, config, projectRoot } = context;\n\tconst log = createModuleLogger(context.logger ?? noopLogger, \"step-executor\");\n\n\t// 1. Ensure feature directory exists\n\tawait store.ensureFeatureDir(featureId);\n\n\t// 2. Load input artifacts\n\tlog.debug(`Loading input artifacts: [${step.inputs.join(\", \")}]`, { featureId, agent: step.agent });\n\tlet inputContent = await loadInputArtifacts(step.inputs, featureId, context);\n\n\t// 2b. Inject system-design.md for architect and reviewer roles (system-level architecture context)\n\tif ((step.agent === \"architect\" || step.agent === \"reviewer\") && (await store.hasSystemDesign())) {\n\t\tconst systemDesign = await store.readSystemDesign();\n\t\tconst systemDesignSection = `## Input: system-design.md (System Architecture)\\n\\n${systemDesign}`;\n\t\tinputContent = inputContent ? `${inputContent}\\n\\n---\\n\\n${systemDesignSection}` : systemDesignSection;\n\t\tlog.debug(`Injected system-design.md into ${step.agent} context`, { featureId });\n\t}\n\n\t// 3. Get system prompt\n\tconst systemPrompt = getSystemPromptForRole(step.agent);\n\n\t// 4. Artifact directory path\n\tconst artifactDir = store.getFeatureDir(featureId);\n\n\t// 5. Build execution prompt\n\tlet actionPrompt = buildActionPrompt(\n\t\tstep,\n\t\tfeatureId,\n\t\tinputContent,\n\t\tartifactDir,\n\t\tcontext.availableSkills,\n\t\tconfig.baseBranch,\n\t\tconfig.testing,\n\t\tprojectRoot,\n\t);\n\n\t// 6a. Load prior action history for the same role (only when step opts in)\n\tlet initialMessages: import(\"@mariozechner/pi-agent-core\").AgentMessage[] | undefined;\n\tif (step.inheritPriorHistory) {\n\t\tconst priorCheckpoints = await store.loadPriorAgentHistory(featureId, step.agent, step.action);\n\t\tif (priorCheckpoints.length > 0) {\n\t\t\tlog.debug(`Loading prior action history for ${step.agent}: ${priorCheckpoints.length} checkpoint(s)`, {\n\t\t\t\tfeatureId,\n\t\t\t\tagent: step.agent,\n\t\t\t});\n\t\t\tinitialMessages = priorCheckpoints.flatMap((cp) => cp.messages);\n\t\t}\n\t}\n\n\t// 6b. If retry history exists for the current action, append it (checkpoint restoration on retry)\n\tconst hasHistory = await store.hasAgentHistory(featureId, step.agent, step.action);\n\tif (hasHistory) {\n\t\tconst checkpoint = await store.loadAgentHistory(featureId, step.agent, step.action);\n\t\tif (checkpoint) {\n\t\t\tinitialMessages = [...(initialMessages ?? []), ...checkpoint.messages];\n\t\t\tactionPrompt = `[RETRY] Previous attempt for this step exists in your conversation history. Review what went wrong and try a different approach.\\n\\n${actionPrompt}`;\n\t\t}\n\t}\n\n\t// 7. Create agent (inject prior history)\n\tlog.info(`Creating agent: ${step.agent} for action: ${step.action}`, { featureId, hasHistory: !!initialMessages });\n\tconst agent = await createRoleAgent({\n\t\trole: step.agent,\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel: context.model,\n\t\tfeatureContext: inputContent || undefined,\n\t\tgetApiKey: context.getApiKey,\n\t\tinitialMessages,\n\t\tavailableSkills: context.availableSkills,\n\t\tprojectContext: context.projectContext,\n\t});\n\n\t// 8. Agent registration callback\n\tcontext.onAgentCreated?.(agent);\n\n\ttry {\n\t\t// 9. Run agent (with history)\n\t\tlog.info(`Agent executing: ${step.agent}:${step.action}`, { featureId });\n\t\tconst result = await runAgentWithHistory(agent, actionPrompt);\n\n\t\t// 9b. Aggregate token usage\n\t\tcontext.lastStepUsage = aggregateUsage(result.messages);\n\n\t\t// 10. Save history checkpoint\n\t\tawait store.saveAgentHistory(featureId, {\n\t\t\trole: step.agent,\n\t\t\taction: step.action,\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\n\t\t// 11. Save artifacts for readonly roles\n\t\tif (isReadonlyRole(step.agent) && step.outputs.length > 0) {\n\t\t\tconst isSingle = step.outputs.length === 1;\n\t\t\tfor (const output of step.outputs) {\n\t\t\t\tconst content = extractArtifactContent(result.text, output, isSingle);\n\t\t\t\tif (content) {\n\t\t\t\t\tlog.debug(`Extracted artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t\tawait store.writeArtifact(featureId, output as ArtifactName, content);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Failed to extract artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlog.info(`Agent completed: ${step.agent}:${step.action}`, { featureId });\n\t} finally {\n\t\t// 12. Agent release callback\n\t\tcontext.onAgentFinished?.();\n\t}\n};\n"]}
1
+ {"version":3,"file":"step-executor.d.ts","sourceRoot":"","sources":["../src/step-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAgB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAcvF,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEvD;AAID,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,SAAS,CAMrD,CAAC;AAIH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,SAAS,GAAG,SAAS,CA8B9E;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBnH;AAQD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,cAAc,GAAE,OAAe,GAC7B,MAAM,GAAG,IAAI,CA6Bf;AA6GD;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,MAAM,GAClB,MAAM,CA4FR;AAsDD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAgHjC,CAAC","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { createModuleLogger, noopLogger } from \"./logger.js\";\nimport type { StepContext, StepExecutor, StepUsage } from \"./pipeline.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport type { AgentRole, ArtifactName, PipelineStep, TestingConfig } from \"./types.js\";\n\n// ─── Readonly Role Detection ─────────────────────────────────────────────────\n\n/** Roles that cannot write files via tools. Artifacts are extracted from the response and saved to the store. */\nconst READONLY_ROLES: ReadonlySet<AgentRole> = new Set<AgentRole>([\n\t\"planner\",\n\t\"analyzer\",\n\t\"reviewer\",\n\t\"diagnostician\",\n\t\"discovery\",\n\t\"projectAnalyzer\",\n]);\n\n/** Determines whether the role is readonly (cannot write files via tools). */\nexport function isReadonlyRole(role: AgentRole): boolean {\n\treturn READONLY_ROLES.has(role);\n}\n\n// ─── System Design Injection ─────────────────────────────────────────────────\n\n/** Roles that receive system-design.md as additional input context. */\nexport const SYSTEM_DESIGN_ROLES: ReadonlySet<AgentRole> = new Set<AgentRole>([\n\t\"architect\",\n\t\"reviewer\",\n\t\"developer\",\n\t\"tester\",\n\t\"diagnostician\",\n]);\n\n// ─── Usage Aggregation ───────────────────────────────────────────────────────\n\n/**\n * Aggregates token usage from all assistant messages in a conversation.\n * Returns undefined if no assistant messages with usage data are found.\n */\nexport function aggregateUsage(messages: AgentMessage[]): StepUsage | undefined {\n\tlet input = 0;\n\tlet output = 0;\n\tlet cacheRead = 0;\n\tlet cacheWrite = 0;\n\tlet totalTokens = 0;\n\tlet cost = 0;\n\tlet found = false;\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"assistant\" && \"usage\" in msg && msg.usage) {\n\t\t\tconst u = msg.usage as {\n\t\t\t\tinput: number;\n\t\t\t\toutput: number;\n\t\t\t\tcacheRead: number;\n\t\t\t\tcacheWrite: number;\n\t\t\t\ttotalTokens: number;\n\t\t\t\tcost: { total: number };\n\t\t\t};\n\t\t\tfound = true;\n\t\t\tinput += u.input;\n\t\t\toutput += u.output;\n\t\t\tcacheRead += u.cacheRead;\n\t\t\tcacheWrite += u.cacheWrite;\n\t\t\ttotalTokens += u.totalTokens;\n\t\t\tcost += u.cost.total;\n\t\t}\n\t}\n\n\treturn found ? { input, output, cacheRead, cacheWrite, totalTokens, cost } : undefined;\n}\n\n// ─── Input Artifact Loader ───────────────────────────────────────────────────\n\n/**\n * Reads the artifact files specified in step.inputs from the store\n * and combines them into a single context string.\n * Non-existent files are skipped.\n */\nexport async function loadInputArtifacts(inputs: string[], featureId: string, context: StepContext): Promise<string> {\n\tif (inputs.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst sections: string[] = [];\n\n\tfor (const input of inputs) {\n\t\tconst hasFile = await context.store.hasArtifact(featureId, input as ArtifactName);\n\t\tif (!hasFile) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst content = await context.store.readArtifact(featureId, input as ArtifactName);\n\t\tsections.push(`## Input: ${input}\\n\\n${content}`);\n\t}\n\n\treturn sections.join(\"\\n\\n---\\n\\n\");\n}\n\n// ─── Artifact Extraction ─────────────────────────────────────────────────────\n\nfunction escapeRegex(str: string): string {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Extracts artifact content from agent response text.\n * Used when a readonly role outputs markdown artifacts as text.\n *\n * Extraction strategies:\n * 1. Extract from ```artifactName code block (with nested fence pairing)\n * 2. Extract from ## artifactName section\n * 3. Return the entire response if it's a single output\n */\nexport function extractArtifactContent(\n\tresponseText: string,\n\tartifactName: string,\n\tisSingleOutput: boolean = false,\n): string | null {\n\tif (!responseText.trim()) {\n\t\treturn null;\n\t}\n\n\t// Pattern 1: ```artifactName\\n...\\n``` with nested code fence pairing.\n\t// A simple non-greedy regex fails when the content itself contains ``` fences\n\t// (e.g., directory trees or code examples inside a project-context.md artifact).\n\t// Instead, we find the opening fence and then iterate through subsequent fence\n\t// markers, pairing them (inner-open, inner-close) until we find the unpaired\n\t// closing fence for the outer block.\n\tconst content1 = extractFromCodeFence(responseText, artifactName);\n\tif (content1 !== null) {\n\t\treturn content1;\n\t}\n\n\t// Pattern 2: Content after ## artifactName (without m flag so $ matches end of string)\n\tconst pattern2 = new RegExp(`##\\\\s+${escapeRegex(artifactName)}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n##\\\\s|$)`);\n\tconst match2 = pattern2.exec(responseText);\n\tif (match2) {\n\t\treturn match2[1].trim();\n\t}\n\n\t// Pattern 3: Use the entire response if it's a single output\n\tif (isSingleOutput) {\n\t\treturn responseText.trim();\n\t}\n\n\treturn null;\n}\n\n/**\n * Extracts content from a fenced code block that may contain nested code fences.\n *\n * Algorithm:\n * 1. Find the opening fence (``` followed by artifactName)\n * 2. After the opening, scan for all ``` markers on their own lines\n * 3. Inner fences pair up sequentially (open+close). The first unpaired marker\n * is the closing fence of the outer block.\n */\nfunction extractFromCodeFence(text: string, artifactName: string): string | null {\n\t// Match the opening fence line: ```artifactName (possibly with trailing whitespace)\n\tconst openPattern = new RegExp(`^(\\`{3,})${escapeRegex(artifactName)}[ \\\\t]*$`, \"m\");\n\tconst openMatch = openPattern.exec(text);\n\tif (!openMatch) {\n\t\treturn null;\n\t}\n\n\tconst openTickCount = openMatch[1].length;\n\tconst contentStart = openMatch.index + openMatch[0].length + 1; // +1 for the newline\n\n\t// Collect fence markers after the opening fence, stopping at the next\n\t// artifact-level opening fence (a fence whose info string looks like a\n\t// file path — contains '.' or '/'). This prevents consuming fences that\n\t// belong to subsequent artifacts in multi-artifact responses.\n\tconst rest = text.slice(contentStart);\n\tconst fencePattern = /^(`{3,})[ \\t]*(\\S*)?[ \\t]*$/gm;\n\n\tinterface FenceMarker {\n\t\tindex: number;\n\t\ttickCount: number;\n\t\tinfoString: string;\n\t}\n\n\tconst markers: FenceMarker[] = [];\n\tfor (;;) {\n\t\tconst match = fencePattern.exec(rest);\n\t\tif (match === null) break;\n\t\tconst infoString = match[2] || \"\";\n\n\t\t// Stop at the next artifact-level opening fence (file-like info string)\n\t\tif (infoString !== \"\" && isArtifactInfoString(infoString)) {\n\t\t\tbreak;\n\t\t}\n\n\t\tmarkers.push({\n\t\t\tindex: match.index,\n\t\t\ttickCount: match[1].length,\n\t\t\tinfoString,\n\t\t});\n\t}\n\n\tif (markers.length === 0) {\n\t\treturn null;\n\t}\n\n\t// Within the bounded markers, find the outer closing fence.\n\t// Use the last bare fence (no info string) with >= openTickCount backticks.\n\t// Inner bare fences pair up (open+close) before it; the remaining one is\n\t// the outer close.\n\tfor (let i = markers.length - 1; i >= 0; i--) {\n\t\tconst m = markers[i];\n\t\tif (m.infoString === \"\" && m.tickCount >= openTickCount) {\n\t\t\tconst content = rest.slice(0, m.index);\n\t\t\treturn content.trim();\n\t\t}\n\t}\n\n\t// No valid closing fence found — return null (fall through to other patterns)\n\treturn null;\n}\n\n/**\n * Determines if a code fence info string looks like an artifact file path\n * rather than a code language identifier.\n *\n * Artifact info strings contain '.' (file extension) or '/' (path separator),\n * e.g., \"spec.md\", \"feat-auth/spec.md\", \"plan.json\".\n * Code language info strings are simple identifiers like \"python\", \"bash\", \"json\", \"text\".\n */\nfunction isArtifactInfoString(infoString: string): boolean {\n\treturn infoString.includes(\".\") || infoString.includes(\"/\");\n}\n\n// ─── Skill Search Instructions ───────────────────────────────────────────────\n\n/**\n * Instructions for searching past artifacts to add to specific actions when availableSkills is present.\n * The \"past feature artifacts\" keyword matches the qmd-memory description in Available Skills.\n */\nconst SKILL_SEARCH_INSTRUCTIONS: Readonly<Record<string, string>> = {\n\tplan: \"Before planning, search past feature artifacts for similar features, design patterns, or recurring decisions.\",\n\tdesign: \"Before designing, search past feature artifacts for related design patterns and architectural decisions.\",\n\ttest: \"Search past feature artifacts for related test patterns, integration points, and previously discovered defects before writing tests.\",\n\tregression:\n\t\t\"Search past feature artifacts for areas previously affected by regressions before running regression tests.\",\n\treview: \"Search past feature artifacts for recurring review feedback and common issues before reviewing.\",\n\tinvestigate: \"Search past feature artifacts for similar issues and prior investigation findings.\",\n\tdiagnose: \"Search past feature artifacts for similar bug patterns and fix strategies.\",\n\timplement:\n\t\t\"Search past feature artifacts for similar implementation patterns, code conventions, and lessons learned before implementing.\",\n\tfix: \"Search past feature artifacts for similar fixes, related code areas, and previously applied fix strategies.\",\n\tanalyze:\n\t\t\"Search past feature artifacts for prior impact analyses, affected areas, and risk patterns before analyzing.\",\n};\n\n// ─── Action Prompt Builder ───────────────────────────────────────────────────\n\n/**\n * Builds the prompt to send to the agent based on the step's agent role and action.\n */\nexport function buildActionPrompt(\n\tstep: PipelineStep,\n\tfeatureId: string,\n\tinputContent: string,\n\tartifactDir: string,\n\tavailableSkills?: string,\n\tbaseBranch?: string,\n\ttestingConfig?: TestingConfig,\n\tprojectRoot?: string,\n): string {\n\tconst parts: string[] = [];\n\n\tparts.push(`You are working on feature \"${featureId}\".`);\n\tif (projectRoot) {\n\t\tparts.push(\n\t\t\t`The project root is \\`${projectRoot}\\`. All tool commands (bash, read, write, edit) ` +\n\t\t\t\t`execute relative to this directory. Do NOT prefix commands with \\`cd\\` to a different base directory.`,\n\t\t);\n\t}\n\tparts.push(\"\");\n\tparts.push(`## Task: ${step.action}`);\n\tparts.push(\"\");\n\tparts.push(getActionInstructions(step.agent, step.action, baseBranch));\n\n\tif (availableSkills) {\n\t\tconst skillInstruction = SKILL_SEARCH_INSTRUCTIONS[step.action];\n\t\tif (skillInstruction) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(skillInstruction);\n\t\t}\n\t}\n\n\tif (inputContent) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Input Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(inputContent);\n\t}\n\n\tif (step.outputs.length > 0) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Output Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(\"You must produce the following artifacts:\");\n\t\tfor (const output of step.outputs) {\n\t\t\tparts.push(`- \\`${output}\\` → \\`${artifactDir}/${output}\\``);\n\t\t}\n\n\t\tif (isReadonlyRole(step.agent)) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"Since you cannot write files directly, output the content of each artifact \" +\n\t\t\t\t\t\"in a markdown code block with the artifact filename as the info string. \" +\n\t\t\t\t\t\"For example: ```spec.md\\\\n(content)\\\\n```\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"Write each artifact directly to the specified file path using your tools.\");\n\t\t}\n\t}\n\n\t// Inject testing config for developer and tester actions\n\tif (testingConfig?.testCommand) {\n\t\tconst shouldInject =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInject) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## Project Test Configuration\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(`- **Test command**: \\`${testingConfig.testCommand}\\``);\n\t\t\tparts.push(`- **Timeout**: ${testingConfig.testTimeout} seconds`);\n\t\t\tparts.push(`- **Run existing tests**: ${testingConfig.runExistingTests}`);\n\t\t\tif (testingConfig.excludePatterns.length > 0) {\n\t\t\t\tparts.push(`- **Exclude patterns**: ${testingConfig.excludePatterns.join(\", \")}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Inject CI checks for developer and tester actions (tester can write/edit files too)\n\tif (testingConfig?.ciChecks && testingConfig.ciChecks.length > 0) {\n\t\tconst shouldInjectCiChecks =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInjectCiChecks) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## CI Verification Commands\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"You MUST run the following checks after implementation. All must pass before the task is complete.\",\n\t\t\t);\n\t\t\tparts.push(\"\");\n\t\t\tfor (const check of testingConfig.ciChecks) {\n\t\t\t\tparts.push(`- **${check.name}**: \\`${check.command}\\``);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n\n/**\n * Returns instructions for the given action.\n */\nfunction getActionInstructions(agent: AgentRole, action: string, baseBranch?: string): string {\n\tswitch (action) {\n\t\tcase \"plan\":\n\t\t\treturn \"Analyze the requirements and decompose them into features. Produce a spec.md for each feature and update plan.json.\";\n\n\t\tcase \"design\":\n\t\t\treturn \"Read the spec and produce a detailed design document with file structure, interfaces, and implementation guide.\";\n\n\t\tcase \"implement\":\n\t\t\treturn \"Implement the feature according to the spec and design documents. Write source code files and ensure they compile.\";\n\n\t\tcase \"fix\":\n\t\t\treturn \"Fix the bug as described in the diagnosis. Apply the minimal change necessary.\";\n\n\t\tcase \"test\":\n\t\t\treturn \"Write comprehensive tests for the feature and run them. Produce a test-report.md with results.\";\n\n\t\tcase \"regression\":\n\t\t\treturn \"Run existing tests to verify no regressions were introduced. Produce a regression-report.md with results.\";\n\n\t\tcase \"review\":\n\t\t\treturn \"Review the implementation for correctness, quality, architecture compliance, and standards compliance. Produce a review.md with your verdict.\";\n\n\t\tcase \"branch\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Create a feature branch from \\`${baseBranch}\\`. Run \\`git checkout ${baseBranch}\\` first, then create the branch.`\n\t\t\t\t: `Create a feature branch for ${agent === \"cicd\" ? \"this feature\" : \"the implementation\"}.`;\n\n\t\tcase \"merge\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Merge the feature branch into \\`${baseBranch}\\` using \\`--no-ff\\`. Run \\`git checkout ${baseBranch}\\` first, then merge. Do NOT run \\`git push\\` — push is handled by the orchestration system.`\n\t\t\t\t: \"Merge the feature branch after all checks pass. Do NOT run `git push`.\";\n\n\t\tcase \"analyze\":\n\t\t\treturn \"Analyze the impact of the proposed change on the existing codebase. Produce an impact-report.md.\";\n\n\t\tcase \"investigate\":\n\t\t\treturn \"Trace through the code to identify the root cause of the issue. Use read and bash tools to explore the codebase, run tests, add debug output if needed. Do not produce any artifacts — this is an exploratory step. Your findings will inform the subsequent diagnosis step.\";\n\n\t\tcase \"diagnose\":\n\t\t\treturn \"Analyze the bug, reproduce it, identify the root cause, and produce a diagnosis.md.\";\n\n\t\tdefault:\n\t\t\treturn `Execute the \"${action}\" task for this feature.`;\n\t}\n}\n\n// ─── Default Step Executor ───────────────────────────────────────────────────\n\n/**\n * Default StepExecutor implementation.\n * Creates a role-specific agent, passes input artifacts as context,\n * runs the agent, and saves the output artifacts.\n */\nexport const defaultStepExecutor: StepExecutor = async (step, featureId, context) => {\n\tconst { store, config, projectRoot } = context;\n\tconst log = createModuleLogger(context.logger ?? noopLogger, \"step-executor\");\n\n\t// 1. Ensure feature directory exists\n\tawait store.ensureFeatureDir(featureId);\n\n\t// 2. Load input artifacts\n\tlog.debug(`Loading input artifacts: [${step.inputs.join(\", \")}]`, { featureId, agent: step.agent });\n\tlet inputContent = await loadInputArtifacts(step.inputs, featureId, context);\n\n\t// 2b. Inject system-design.md for roles that need system-level architecture context\n\tif (SYSTEM_DESIGN_ROLES.has(step.agent) && (await store.hasSystemDesign())) {\n\t\tconst systemDesign = await store.readSystemDesign();\n\t\tconst systemDesignSection = `## Input: system-design.md (System Architecture)\\n\\n${systemDesign}`;\n\t\tinputContent = inputContent ? `${inputContent}\\n\\n---\\n\\n${systemDesignSection}` : systemDesignSection;\n\t\tlog.debug(`Injected system-design.md into ${step.agent} context`, { featureId });\n\t}\n\n\t// 3. Get system prompt\n\tconst systemPrompt = getSystemPromptForRole(step.agent);\n\n\t// 4. Artifact directory path\n\tconst artifactDir = store.getFeatureDir(featureId);\n\n\t// 5. Build execution prompt\n\tlet actionPrompt = buildActionPrompt(\n\t\tstep,\n\t\tfeatureId,\n\t\tinputContent,\n\t\tartifactDir,\n\t\tcontext.availableSkills,\n\t\tconfig.baseBranch,\n\t\tconfig.testing,\n\t\tprojectRoot,\n\t);\n\n\t// 6a. Load prior action history for the same role (only when step opts in)\n\tlet initialMessages: import(\"@mariozechner/pi-agent-core\").AgentMessage[] | undefined;\n\tif (step.inheritPriorHistory) {\n\t\tconst priorCheckpoints = await store.loadPriorAgentHistory(featureId, step.agent, step.action);\n\t\tif (priorCheckpoints.length > 0) {\n\t\t\tlog.debug(`Loading prior action history for ${step.agent}: ${priorCheckpoints.length} checkpoint(s)`, {\n\t\t\t\tfeatureId,\n\t\t\t\tagent: step.agent,\n\t\t\t});\n\t\t\tinitialMessages = priorCheckpoints.flatMap((cp) => cp.messages);\n\t\t}\n\t}\n\n\t// 6b. If retry history exists for the current action, append it (checkpoint restoration on retry)\n\tconst hasHistory = await store.hasAgentHistory(featureId, step.agent, step.action);\n\tif (hasHistory) {\n\t\tconst checkpoint = await store.loadAgentHistory(featureId, step.agent, step.action);\n\t\tif (checkpoint) {\n\t\t\tinitialMessages = [...(initialMessages ?? []), ...checkpoint.messages];\n\t\t\tactionPrompt = `[RETRY] Previous attempt for this step exists in your conversation history. Review what went wrong and try a different approach.\\n\\n${actionPrompt}`;\n\t\t}\n\t}\n\n\t// 7. Create agent (inject prior history)\n\tlog.info(`Creating agent: ${step.agent} for action: ${step.action}`, { featureId, hasHistory: !!initialMessages });\n\tconst agent = await createRoleAgent({\n\t\trole: step.agent,\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel: context.model,\n\t\tfeatureContext: inputContent || undefined,\n\t\tgetApiKey: context.getApiKey,\n\t\tinitialMessages,\n\t\tavailableSkills: context.availableSkills,\n\t});\n\n\t// 8. Agent registration callback\n\tcontext.onAgentCreated?.(agent);\n\n\ttry {\n\t\t// 9. Run agent (with history)\n\t\tlog.info(`Agent executing: ${step.agent}:${step.action}`, { featureId });\n\t\tconst result = await runAgentWithHistory(agent, actionPrompt);\n\n\t\t// 9b. Aggregate token usage and capture response text\n\t\tcontext.lastStepUsage = aggregateUsage(result.messages);\n\t\tcontext.lastStepResponseText = result.text;\n\n\t\t// 10. Save history checkpoint\n\t\tawait store.saveAgentHistory(featureId, {\n\t\t\trole: step.agent,\n\t\t\taction: step.action,\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\n\t\t// 11. Save artifacts for readonly roles\n\t\tif (isReadonlyRole(step.agent) && step.outputs.length > 0) {\n\t\t\tconst isSingle = step.outputs.length === 1;\n\t\t\tfor (const output of step.outputs) {\n\t\t\t\tconst content = extractArtifactContent(result.text, output, isSingle);\n\t\t\t\tif (content) {\n\t\t\t\t\tlog.debug(`Extracted artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t\tawait store.writeArtifact(featureId, output as ArtifactName, content);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Failed to extract artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlog.info(`Agent completed: ${step.agent}:${step.action}`, { featureId });\n\t} finally {\n\t\t// 12. Agent release callback\n\t\tcontext.onAgentFinished?.();\n\t}\n};\n"]}
@@ -15,6 +15,15 @@ const READONLY_ROLES = new Set([
15
15
  export function isReadonlyRole(role) {
16
16
  return READONLY_ROLES.has(role);
17
17
  }
18
+ // ─── System Design Injection ─────────────────────────────────────────────────
19
+ /** Roles that receive system-design.md as additional input context. */
20
+ export const SYSTEM_DESIGN_ROLES = new Set([
21
+ "architect",
22
+ "reviewer",
23
+ "developer",
24
+ "tester",
25
+ "diagnostician",
26
+ ]);
18
27
  // ─── Usage Aggregation ───────────────────────────────────────────────────────
19
28
  /**
20
29
  * Aggregates token usage from all assistant messages in a conversation.
@@ -183,6 +192,9 @@ const SKILL_SEARCH_INSTRUCTIONS = {
183
192
  review: "Search past feature artifacts for recurring review feedback and common issues before reviewing.",
184
193
  investigate: "Search past feature artifacts for similar issues and prior investigation findings.",
185
194
  diagnose: "Search past feature artifacts for similar bug patterns and fix strategies.",
195
+ implement: "Search past feature artifacts for similar implementation patterns, code conventions, and lessons learned before implementing.",
196
+ fix: "Search past feature artifacts for similar fixes, related code areas, and previously applied fix strategies.",
197
+ analyze: "Search past feature artifacts for prior impact analyses, affected areas, and risk patterns before analyzing.",
186
198
  };
187
199
  // ─── Action Prompt Builder ───────────────────────────────────────────────────
188
200
  /**
@@ -315,8 +327,8 @@ export const defaultStepExecutor = async (step, featureId, context) => {
315
327
  // 2. Load input artifacts
316
328
  log.debug(`Loading input artifacts: [${step.inputs.join(", ")}]`, { featureId, agent: step.agent });
317
329
  let inputContent = await loadInputArtifacts(step.inputs, featureId, context);
318
- // 2b. Inject system-design.md for architect and reviewer roles (system-level architecture context)
319
- if ((step.agent === "architect" || step.agent === "reviewer") && (await store.hasSystemDesign())) {
330
+ // 2b. Inject system-design.md for roles that need system-level architecture context
331
+ if (SYSTEM_DESIGN_ROLES.has(step.agent) && (await store.hasSystemDesign())) {
320
332
  const systemDesign = await store.readSystemDesign();
321
333
  const systemDesignSection = `## Input: system-design.md (System Architecture)\n\n${systemDesign}`;
322
334
  inputContent = inputContent ? `${inputContent}\n\n---\n\n${systemDesignSection}` : systemDesignSection;
@@ -361,7 +373,6 @@ export const defaultStepExecutor = async (step, featureId, context) => {
361
373
  getApiKey: context.getApiKey,
362
374
  initialMessages,
363
375
  availableSkills: context.availableSkills,
364
- projectContext: context.projectContext,
365
376
  });
366
377
  // 8. Agent registration callback
367
378
  context.onAgentCreated?.(agent);
@@ -369,8 +380,9 @@ export const defaultStepExecutor = async (step, featureId, context) => {
369
380
  // 9. Run agent (with history)
370
381
  log.info(`Agent executing: ${step.agent}:${step.action}`, { featureId });
371
382
  const result = await runAgentWithHistory(agent, actionPrompt);
372
- // 9b. Aggregate token usage
383
+ // 9b. Aggregate token usage and capture response text
373
384
  context.lastStepUsage = aggregateUsage(result.messages);
385
+ context.lastStepResponseText = result.text;
374
386
  // 10. Save history checkpoint
375
387
  await store.saveAgentHistory(featureId, {
376
388
  role: step.agent,
@@ -1 +1 @@
1
- {"version":3,"file":"step-executor.js","sourceRoot":"","sources":["../src/step-executor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACtG,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,wLAAgF;AAEhF,iHAAiH;AACjH,MAAM,cAAc,GAA2B,IAAI,GAAG,CAAY;IACjE,SAAS;IACT,UAAU;IACV,UAAU;IACV,eAAe;IACf,WAAW;IACX,iBAAiB;CACjB,CAAC,CAAC;AAEH,8EAA8E;AAC9E,MAAM,UAAU,cAAc,CAAC,IAAe,EAAW;IACxD,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAAA,CAChC;AAED,oMAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAwB,EAAyB;IAC/E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7D,MAAM,CAAC,GAAG,GAAG,CAAC,KAOb,CAAC;YACF,KAAK,GAAG,IAAI,CAAC;YACb,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC;YACjB,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC;YACnB,SAAS,IAAI,CAAC,CAAC,SAAS,CAAC;YACzB,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC;YAC3B,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;YAC7B,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CACvF;AAED,4LAAgF;AAEhF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAgB,EAAE,SAAiB,EAAE,OAAoB,EAAmB;IACpH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,KAAqB,CAAC,CAAC;QAClF,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,SAAS;QACV,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,KAAqB,CAAC,CAAC;QACnF,QAAQ,CAAC,IAAI,CAAC,aAAa,KAAK,OAAO,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAAA,CACpC;AAED,gMAAgF;AAEhF,SAAS,WAAW,CAAC,GAAW,EAAU;IACzC,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAAA,CAClD;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACrC,YAAoB,EACpB,YAAoB,EACpB,cAAc,GAAY,KAAK,EACf;IAChB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,uEAAuE;IACvE,8EAA8E;IAC9E,iFAAiF;IACjF,+EAA+E;IAC/E,6EAA6E;IAC7E,qCAAqC;IACrC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAClE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,uFAAuF;IACvF,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,SAAS,WAAW,CAAC,YAAY,CAAC,mCAAmC,CAAC,CAAC;IACnG,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,MAAM,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,6DAA6D;IAC7D,IAAI,cAAc,EAAE,CAAC;QACpB,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC;AAAA,CACZ;AAED;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAAC,IAAY,EAAE,YAAoB,EAAiB;IAChF,oFAAoF;IACpF,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,YAAY,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,qBAAqB;IAErF,sEAAsE;IACtE,uEAAuE;IACvE,0EAAwE;IACxE,8DAA8D;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,YAAY,GAAG,+BAA+B,CAAC;IAQrD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,SAAS,CAAC;QACT,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM;QAC1B,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAElC,wEAAwE;QACxE,IAAI,UAAU,KAAK,EAAE,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3D,MAAM;QACP,CAAC;QAED,OAAO,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;YAC1B,UAAU;SACV,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,4DAA4D;IAC5D,4EAA4E;IAC5E,yEAAyE;IACzE,mBAAmB;IACnB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,IAAI,CAAC,CAAC,SAAS,IAAI,aAAa,EAAE,CAAC;YACzD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IAED,gFAA8E;IAC9E,OAAO,IAAI,CAAC;AAAA,CACZ;AAED;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,UAAkB,EAAW;IAC1D,OAAO,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAAA,CAC5D;AAED,oLAAgF;AAEhF;;;GAGG;AACH,MAAM,yBAAyB,GAAqC;IACnE,IAAI,EAAE,+GAA+G;IACrH,MAAM,EAAE,0GAA0G;IAClH,IAAI,EAAE,sIAAsI;IAC5I,UAAU,EACT,6GAA6G;IAC9G,MAAM,EAAE,iGAAiG;IACzG,WAAW,EAAE,oFAAoF;IACjG,QAAQ,EAAE,4EAA4E;CACtF,CAAC;AAEF,4LAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAChC,IAAkB,EAClB,SAAiB,EACjB,YAAoB,EACpB,WAAmB,EACnB,eAAwB,EACxB,UAAmB,EACnB,aAA6B,EAC7B,WAAoB,EACX;IACT,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,+BAA+B,SAAS,IAAI,CAAC,CAAC;IACzD,IAAI,WAAW,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CACT,yBAAyB,WAAW,kDAAkD;YACrF,uGAAuG,CACxG,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAEvE,IAAI,eAAe,EAAE,CAAC;QACrB,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChE,IAAI,gBAAgB,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACxD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,YAAU,WAAW,IAAI,MAAM,IAAI,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACT,6EAA6E;gBAC5E,0EAA0E;gBAC1E,2CAA2C,CAC5C,CAAC;QACH,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;QACzF,CAAC;IACF,CAAC;IAED,yDAAyD;IACzD,IAAI,aAAa,EAAE,WAAW,EAAE,CAAC;QAChC,MAAM,YAAY,GACjB,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;YACtF,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC;QAEvF,IAAI,YAAY,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,yBAAyB,aAAa,CAAC,WAAW,IAAI,CAAC,CAAC;YACnE,KAAK,CAAC,IAAI,CAAC,kBAAkB,aAAa,CAAC,WAAW,UAAU,CAAC,CAAC;YAClE,KAAK,CAAC,IAAI,CAAC,6BAA6B,aAAa,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAC1E,IAAI,aAAa,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,KAAK,CAAC,IAAI,CAAC,2BAA2B,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnF,CAAC;QACF,CAAC;IACF,CAAC;IAED,sFAAsF;IACtF,IAAI,aAAa,EAAE,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,oBAAoB,GACzB,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;YACtF,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC;QAEvF,IAAI,oBAAoB,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACT,oGAAoG,CACpG,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;gBAC5C,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,SAAS,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACzD,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CACxB;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,KAAgB,EAAE,MAAc,EAAE,UAAmB,EAAU;IAC7F,QAAQ,MAAM,EAAE,CAAC;QAChB,KAAK,MAAM;YACV,OAAO,qHAAqH,CAAC;QAE9H,KAAK,QAAQ;YACZ,OAAO,iHAAiH,CAAC;QAE1H,KAAK,WAAW;YACf,OAAO,oHAAoH,CAAC;QAE7H,KAAK,KAAK;YACT,OAAO,gFAAgF,CAAC;QAEzF,KAAK,MAAM;YACV,OAAO,gGAAgG,CAAC;QAEzG,KAAK,YAAY;YAChB,OAAO,2GAA2G,CAAC;QAEpH,KAAK,QAAQ;YACZ,OAAO,+IAA+I,CAAC;QAExJ,KAAK,QAAQ;YACZ,OAAO,UAAU;gBAChB,CAAC,CAAC,kCAAkC,UAAU,0BAA0B,UAAU,mCAAmC;gBACrH,CAAC,CAAC,+BAA+B,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,oBAAoB,GAAG,CAAC;QAE/F,KAAK,OAAO;YACX,OAAO,UAAU;gBAChB,CAAC,CAAC,mCAAmC,UAAU,4CAA4C,UAAU,gGAA8F;gBACnM,CAAC,CAAC,wEAAwE,CAAC;QAE7E,KAAK,SAAS;YACb,OAAO,kGAAkG,CAAC;QAE3G,KAAK,aAAa;YACjB,OAAO,gRAA8Q,CAAC;QAEvR,KAAK,UAAU;YACd,OAAO,qFAAqF,CAAC;QAE9F;YACC,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;IAC1D,CAAC;AAAA,CACD;AAED,4LAAgF;AAEhF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC;IACpF,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC/C,MAAM,GAAG,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,EAAE,eAAe,CAAC,CAAC;IAE9E,qCAAqC;IACrC,MAAM,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAExC,0BAA0B;IAC1B,GAAG,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACpG,IAAI,YAAY,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAE7E,mGAAmG;IACnG,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC;QAClG,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACpD,MAAM,mBAAmB,GAAG,uDAAuD,YAAY,EAAE,CAAC;QAClG,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,cAAc,mBAAmB,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACvG,GAAG,CAAC,KAAK,CAAC,kCAAkC,IAAI,CAAC,KAAK,UAAU,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,uBAAuB;IACvB,MAAM,YAAY,GAAG,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAExD,6BAA6B;IAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAEnD,4BAA4B;IAC5B,IAAI,YAAY,GAAG,iBAAiB,CACnC,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,OAAO,CAAC,eAAe,EACvB,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,OAAO,EACd,WAAW,CACX,CAAC;IAEF,2EAA2E;IAC3E,IAAI,eAAiF,CAAC;IACtF,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC9B,MAAM,gBAAgB,GAAG,MAAM,KAAK,CAAC,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/F,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,GAAG,CAAC,KAAK,CAAC,oCAAoC,IAAI,CAAC,KAAK,KAAK,gBAAgB,CAAC,MAAM,gBAAgB,EAAE;gBACrG,SAAS;gBACT,KAAK,EAAE,IAAI,CAAC,KAAK;aACjB,CAAC,CAAC;YACH,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;IAED,kGAAkG;IAClG,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACnF,IAAI,UAAU,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpF,IAAI,UAAU,EAAE,CAAC;YAChB,eAAe,GAAG,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;YACvE,YAAY,GAAG,uIAAuI,YAAY,EAAE,CAAC;QACtK,CAAC;IACF,CAAC;IAED,yCAAyC;IACzC,GAAG,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,KAAK,gBAAgB,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;IACnH,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC,KAAK;QAChB,YAAY;QACZ,MAAM;QACN,WAAW;QACX,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,cAAc,EAAE,YAAY,IAAI,SAAS;QACzC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,eAAe;QACf,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,cAAc,EAAE,OAAO,CAAC,cAAc;KACtC,CAAC,CAAC;IAEH,iCAAiC;IACjC,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;IAEhC,IAAI,CAAC;QACJ,8BAA8B;QAC9B,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAE9D,4BAA4B;QAC5B,OAAO,CAAC,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAExD,8BAA8B;QAC9B,MAAM,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE;YACvC,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,0BAA0B,CAAC,MAAM,CAAC,QAAQ,CAAC;YACrD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC,CAAC;QAEH,wCAAwC;QACxC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;YAC3C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACtE,IAAI,OAAO,EAAE,CAAC;oBACb,GAAG,CAAC,KAAK,CAAC,uBAAuB,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;oBAC7E,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,MAAsB,EAAE,OAAO,CAAC,CAAC;gBACvE,CAAC;qBAAM,CAAC;oBACP,GAAG,CAAC,IAAI,CAAC,+BAA+B,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBACrF,CAAC;YACF,CAAC;QACF,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1E,CAAC;YAAS,CAAC;QACV,6BAA6B;QAC7B,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;IAC7B,CAAC;AAAA,CACD,CAAC","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { createModuleLogger, noopLogger } from \"./logger.js\";\nimport type { StepContext, StepExecutor, StepUsage } from \"./pipeline.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport type { AgentRole, ArtifactName, PipelineStep, TestingConfig } from \"./types.js\";\n\n// ─── Readonly Role Detection ─────────────────────────────────────────────────\n\n/** Roles that cannot write files via tools. Artifacts are extracted from the response and saved to the store. */\nconst READONLY_ROLES: ReadonlySet<AgentRole> = new Set<AgentRole>([\n\t\"planner\",\n\t\"analyzer\",\n\t\"reviewer\",\n\t\"diagnostician\",\n\t\"discovery\",\n\t\"projectAnalyzer\",\n]);\n\n/** Determines whether the role is readonly (cannot write files via tools). */\nexport function isReadonlyRole(role: AgentRole): boolean {\n\treturn READONLY_ROLES.has(role);\n}\n\n// ─── Usage Aggregation ───────────────────────────────────────────────────────\n\n/**\n * Aggregates token usage from all assistant messages in a conversation.\n * Returns undefined if no assistant messages with usage data are found.\n */\nexport function aggregateUsage(messages: AgentMessage[]): StepUsage | undefined {\n\tlet input = 0;\n\tlet output = 0;\n\tlet cacheRead = 0;\n\tlet cacheWrite = 0;\n\tlet totalTokens = 0;\n\tlet cost = 0;\n\tlet found = false;\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"assistant\" && \"usage\" in msg && msg.usage) {\n\t\t\tconst u = msg.usage as {\n\t\t\t\tinput: number;\n\t\t\t\toutput: number;\n\t\t\t\tcacheRead: number;\n\t\t\t\tcacheWrite: number;\n\t\t\t\ttotalTokens: number;\n\t\t\t\tcost: { total: number };\n\t\t\t};\n\t\t\tfound = true;\n\t\t\tinput += u.input;\n\t\t\toutput += u.output;\n\t\t\tcacheRead += u.cacheRead;\n\t\t\tcacheWrite += u.cacheWrite;\n\t\t\ttotalTokens += u.totalTokens;\n\t\t\tcost += u.cost.total;\n\t\t}\n\t}\n\n\treturn found ? { input, output, cacheRead, cacheWrite, totalTokens, cost } : undefined;\n}\n\n// ─── Input Artifact Loader ───────────────────────────────────────────────────\n\n/**\n * Reads the artifact files specified in step.inputs from the store\n * and combines them into a single context string.\n * Non-existent files are skipped.\n */\nexport async function loadInputArtifacts(inputs: string[], featureId: string, context: StepContext): Promise<string> {\n\tif (inputs.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst sections: string[] = [];\n\n\tfor (const input of inputs) {\n\t\tconst hasFile = await context.store.hasArtifact(featureId, input as ArtifactName);\n\t\tif (!hasFile) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst content = await context.store.readArtifact(featureId, input as ArtifactName);\n\t\tsections.push(`## Input: ${input}\\n\\n${content}`);\n\t}\n\n\treturn sections.join(\"\\n\\n---\\n\\n\");\n}\n\n// ─── Artifact Extraction ─────────────────────────────────────────────────────\n\nfunction escapeRegex(str: string): string {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Extracts artifact content from agent response text.\n * Used when a readonly role outputs markdown artifacts as text.\n *\n * Extraction strategies:\n * 1. Extract from ```artifactName code block (with nested fence pairing)\n * 2. Extract from ## artifactName section\n * 3. Return the entire response if it's a single output\n */\nexport function extractArtifactContent(\n\tresponseText: string,\n\tartifactName: string,\n\tisSingleOutput: boolean = false,\n): string | null {\n\tif (!responseText.trim()) {\n\t\treturn null;\n\t}\n\n\t// Pattern 1: ```artifactName\\n...\\n``` with nested code fence pairing.\n\t// A simple non-greedy regex fails when the content itself contains ``` fences\n\t// (e.g., directory trees or code examples inside a project-context.md artifact).\n\t// Instead, we find the opening fence and then iterate through subsequent fence\n\t// markers, pairing them (inner-open, inner-close) until we find the unpaired\n\t// closing fence for the outer block.\n\tconst content1 = extractFromCodeFence(responseText, artifactName);\n\tif (content1 !== null) {\n\t\treturn content1;\n\t}\n\n\t// Pattern 2: Content after ## artifactName (without m flag so $ matches end of string)\n\tconst pattern2 = new RegExp(`##\\\\s+${escapeRegex(artifactName)}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n##\\\\s|$)`);\n\tconst match2 = pattern2.exec(responseText);\n\tif (match2) {\n\t\treturn match2[1].trim();\n\t}\n\n\t// Pattern 3: Use the entire response if it's a single output\n\tif (isSingleOutput) {\n\t\treturn responseText.trim();\n\t}\n\n\treturn null;\n}\n\n/**\n * Extracts content from a fenced code block that may contain nested code fences.\n *\n * Algorithm:\n * 1. Find the opening fence (``` followed by artifactName)\n * 2. After the opening, scan for all ``` markers on their own lines\n * 3. Inner fences pair up sequentially (open+close). The first unpaired marker\n * is the closing fence of the outer block.\n */\nfunction extractFromCodeFence(text: string, artifactName: string): string | null {\n\t// Match the opening fence line: ```artifactName (possibly with trailing whitespace)\n\tconst openPattern = new RegExp(`^(\\`{3,})${escapeRegex(artifactName)}[ \\\\t]*$`, \"m\");\n\tconst openMatch = openPattern.exec(text);\n\tif (!openMatch) {\n\t\treturn null;\n\t}\n\n\tconst openTickCount = openMatch[1].length;\n\tconst contentStart = openMatch.index + openMatch[0].length + 1; // +1 for the newline\n\n\t// Collect fence markers after the opening fence, stopping at the next\n\t// artifact-level opening fence (a fence whose info string looks like a\n\t// file path — contains '.' or '/'). This prevents consuming fences that\n\t// belong to subsequent artifacts in multi-artifact responses.\n\tconst rest = text.slice(contentStart);\n\tconst fencePattern = /^(`{3,})[ \\t]*(\\S*)?[ \\t]*$/gm;\n\n\tinterface FenceMarker {\n\t\tindex: number;\n\t\ttickCount: number;\n\t\tinfoString: string;\n\t}\n\n\tconst markers: FenceMarker[] = [];\n\tfor (;;) {\n\t\tconst match = fencePattern.exec(rest);\n\t\tif (match === null) break;\n\t\tconst infoString = match[2] || \"\";\n\n\t\t// Stop at the next artifact-level opening fence (file-like info string)\n\t\tif (infoString !== \"\" && isArtifactInfoString(infoString)) {\n\t\t\tbreak;\n\t\t}\n\n\t\tmarkers.push({\n\t\t\tindex: match.index,\n\t\t\ttickCount: match[1].length,\n\t\t\tinfoString,\n\t\t});\n\t}\n\n\tif (markers.length === 0) {\n\t\treturn null;\n\t}\n\n\t// Within the bounded markers, find the outer closing fence.\n\t// Use the last bare fence (no info string) with >= openTickCount backticks.\n\t// Inner bare fences pair up (open+close) before it; the remaining one is\n\t// the outer close.\n\tfor (let i = markers.length - 1; i >= 0; i--) {\n\t\tconst m = markers[i];\n\t\tif (m.infoString === \"\" && m.tickCount >= openTickCount) {\n\t\t\tconst content = rest.slice(0, m.index);\n\t\t\treturn content.trim();\n\t\t}\n\t}\n\n\t// No valid closing fence found — return null (fall through to other patterns)\n\treturn null;\n}\n\n/**\n * Determines if a code fence info string looks like an artifact file path\n * rather than a code language identifier.\n *\n * Artifact info strings contain '.' (file extension) or '/' (path separator),\n * e.g., \"spec.md\", \"feat-auth/spec.md\", \"plan.json\".\n * Code language info strings are simple identifiers like \"python\", \"bash\", \"json\", \"text\".\n */\nfunction isArtifactInfoString(infoString: string): boolean {\n\treturn infoString.includes(\".\") || infoString.includes(\"/\");\n}\n\n// ─── Skill Search Instructions ───────────────────────────────────────────────\n\n/**\n * Instructions for searching past artifacts to add to specific actions when availableSkills is present.\n * The \"past feature artifacts\" keyword matches the qmd-memory description in Available Skills.\n */\nconst SKILL_SEARCH_INSTRUCTIONS: Readonly<Record<string, string>> = {\n\tplan: \"Before planning, search past feature artifacts for similar features, design patterns, or recurring decisions.\",\n\tdesign: \"Before designing, search past feature artifacts for related design patterns and architectural decisions.\",\n\ttest: \"Search past feature artifacts for related test patterns, integration points, and previously discovered defects before writing tests.\",\n\tregression:\n\t\t\"Search past feature artifacts for areas previously affected by regressions before running regression tests.\",\n\treview: \"Search past feature artifacts for recurring review feedback and common issues before reviewing.\",\n\tinvestigate: \"Search past feature artifacts for similar issues and prior investigation findings.\",\n\tdiagnose: \"Search past feature artifacts for similar bug patterns and fix strategies.\",\n};\n\n// ─── Action Prompt Builder ───────────────────────────────────────────────────\n\n/**\n * Builds the prompt to send to the agent based on the step's agent role and action.\n */\nexport function buildActionPrompt(\n\tstep: PipelineStep,\n\tfeatureId: string,\n\tinputContent: string,\n\tartifactDir: string,\n\tavailableSkills?: string,\n\tbaseBranch?: string,\n\ttestingConfig?: TestingConfig,\n\tprojectRoot?: string,\n): string {\n\tconst parts: string[] = [];\n\n\tparts.push(`You are working on feature \"${featureId}\".`);\n\tif (projectRoot) {\n\t\tparts.push(\n\t\t\t`The project root is \\`${projectRoot}\\`. All tool commands (bash, read, write, edit) ` +\n\t\t\t\t`execute relative to this directory. Do NOT prefix commands with \\`cd\\` to a different base directory.`,\n\t\t);\n\t}\n\tparts.push(\"\");\n\tparts.push(`## Task: ${step.action}`);\n\tparts.push(\"\");\n\tparts.push(getActionInstructions(step.agent, step.action, baseBranch));\n\n\tif (availableSkills) {\n\t\tconst skillInstruction = SKILL_SEARCH_INSTRUCTIONS[step.action];\n\t\tif (skillInstruction) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(skillInstruction);\n\t\t}\n\t}\n\n\tif (inputContent) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Input Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(inputContent);\n\t}\n\n\tif (step.outputs.length > 0) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Output Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(\"You must produce the following artifacts:\");\n\t\tfor (const output of step.outputs) {\n\t\t\tparts.push(`- \\`${output}\\` → \\`${artifactDir}/${output}\\``);\n\t\t}\n\n\t\tif (isReadonlyRole(step.agent)) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"Since you cannot write files directly, output the content of each artifact \" +\n\t\t\t\t\t\"in a markdown code block with the artifact filename as the info string. \" +\n\t\t\t\t\t\"For example: ```spec.md\\\\n(content)\\\\n```\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"Write each artifact directly to the specified file path using your tools.\");\n\t\t}\n\t}\n\n\t// Inject testing config for developer and tester actions\n\tif (testingConfig?.testCommand) {\n\t\tconst shouldInject =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInject) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## Project Test Configuration\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(`- **Test command**: \\`${testingConfig.testCommand}\\``);\n\t\t\tparts.push(`- **Timeout**: ${testingConfig.testTimeout} seconds`);\n\t\t\tparts.push(`- **Run existing tests**: ${testingConfig.runExistingTests}`);\n\t\t\tif (testingConfig.excludePatterns.length > 0) {\n\t\t\t\tparts.push(`- **Exclude patterns**: ${testingConfig.excludePatterns.join(\", \")}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Inject CI checks for developer and tester actions (tester can write/edit files too)\n\tif (testingConfig?.ciChecks && testingConfig.ciChecks.length > 0) {\n\t\tconst shouldInjectCiChecks =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInjectCiChecks) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## CI Verification Commands\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"You MUST run the following checks after implementation. All must pass before the task is complete.\",\n\t\t\t);\n\t\t\tparts.push(\"\");\n\t\t\tfor (const check of testingConfig.ciChecks) {\n\t\t\t\tparts.push(`- **${check.name}**: \\`${check.command}\\``);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n\n/**\n * Returns instructions for the given action.\n */\nfunction getActionInstructions(agent: AgentRole, action: string, baseBranch?: string): string {\n\tswitch (action) {\n\t\tcase \"plan\":\n\t\t\treturn \"Analyze the requirements and decompose them into features. Produce a spec.md for each feature and update plan.json.\";\n\n\t\tcase \"design\":\n\t\t\treturn \"Read the spec and produce a detailed design document with file structure, interfaces, and implementation guide.\";\n\n\t\tcase \"implement\":\n\t\t\treturn \"Implement the feature according to the spec and design documents. Write source code files and ensure they compile.\";\n\n\t\tcase \"fix\":\n\t\t\treturn \"Fix the bug as described in the diagnosis. Apply the minimal change necessary.\";\n\n\t\tcase \"test\":\n\t\t\treturn \"Write comprehensive tests for the feature and run them. Produce a test-report.md with results.\";\n\n\t\tcase \"regression\":\n\t\t\treturn \"Run existing tests to verify no regressions were introduced. Produce a regression-report.md with results.\";\n\n\t\tcase \"review\":\n\t\t\treturn \"Review the implementation for correctness, quality, architecture compliance, and standards compliance. Produce a review.md with your verdict.\";\n\n\t\tcase \"branch\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Create a feature branch from \\`${baseBranch}\\`. Run \\`git checkout ${baseBranch}\\` first, then create the branch.`\n\t\t\t\t: `Create a feature branch for ${agent === \"cicd\" ? \"this feature\" : \"the implementation\"}.`;\n\n\t\tcase \"merge\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Merge the feature branch into \\`${baseBranch}\\` using \\`--no-ff\\`. Run \\`git checkout ${baseBranch}\\` first, then merge. Do NOT run \\`git push\\` — push is handled by the orchestration system.`\n\t\t\t\t: \"Merge the feature branch after all checks pass. Do NOT run `git push`.\";\n\n\t\tcase \"analyze\":\n\t\t\treturn \"Analyze the impact of the proposed change on the existing codebase. Produce an impact-report.md.\";\n\n\t\tcase \"investigate\":\n\t\t\treturn \"Trace through the code to identify the root cause of the issue. Use read and bash tools to explore the codebase, run tests, add debug output if needed. Do not produce any artifacts — this is an exploratory step. Your findings will inform the subsequent diagnosis step.\";\n\n\t\tcase \"diagnose\":\n\t\t\treturn \"Analyze the bug, reproduce it, identify the root cause, and produce a diagnosis.md.\";\n\n\t\tdefault:\n\t\t\treturn `Execute the \"${action}\" task for this feature.`;\n\t}\n}\n\n// ─── Default Step Executor ───────────────────────────────────────────────────\n\n/**\n * Default StepExecutor implementation.\n * Creates a role-specific agent, passes input artifacts as context,\n * runs the agent, and saves the output artifacts.\n */\nexport const defaultStepExecutor: StepExecutor = async (step, featureId, context) => {\n\tconst { store, config, projectRoot } = context;\n\tconst log = createModuleLogger(context.logger ?? noopLogger, \"step-executor\");\n\n\t// 1. Ensure feature directory exists\n\tawait store.ensureFeatureDir(featureId);\n\n\t// 2. Load input artifacts\n\tlog.debug(`Loading input artifacts: [${step.inputs.join(\", \")}]`, { featureId, agent: step.agent });\n\tlet inputContent = await loadInputArtifacts(step.inputs, featureId, context);\n\n\t// 2b. Inject system-design.md for architect and reviewer roles (system-level architecture context)\n\tif ((step.agent === \"architect\" || step.agent === \"reviewer\") && (await store.hasSystemDesign())) {\n\t\tconst systemDesign = await store.readSystemDesign();\n\t\tconst systemDesignSection = `## Input: system-design.md (System Architecture)\\n\\n${systemDesign}`;\n\t\tinputContent = inputContent ? `${inputContent}\\n\\n---\\n\\n${systemDesignSection}` : systemDesignSection;\n\t\tlog.debug(`Injected system-design.md into ${step.agent} context`, { featureId });\n\t}\n\n\t// 3. Get system prompt\n\tconst systemPrompt = getSystemPromptForRole(step.agent);\n\n\t// 4. Artifact directory path\n\tconst artifactDir = store.getFeatureDir(featureId);\n\n\t// 5. Build execution prompt\n\tlet actionPrompt = buildActionPrompt(\n\t\tstep,\n\t\tfeatureId,\n\t\tinputContent,\n\t\tartifactDir,\n\t\tcontext.availableSkills,\n\t\tconfig.baseBranch,\n\t\tconfig.testing,\n\t\tprojectRoot,\n\t);\n\n\t// 6a. Load prior action history for the same role (only when step opts in)\n\tlet initialMessages: import(\"@mariozechner/pi-agent-core\").AgentMessage[] | undefined;\n\tif (step.inheritPriorHistory) {\n\t\tconst priorCheckpoints = await store.loadPriorAgentHistory(featureId, step.agent, step.action);\n\t\tif (priorCheckpoints.length > 0) {\n\t\t\tlog.debug(`Loading prior action history for ${step.agent}: ${priorCheckpoints.length} checkpoint(s)`, {\n\t\t\t\tfeatureId,\n\t\t\t\tagent: step.agent,\n\t\t\t});\n\t\t\tinitialMessages = priorCheckpoints.flatMap((cp) => cp.messages);\n\t\t}\n\t}\n\n\t// 6b. If retry history exists for the current action, append it (checkpoint restoration on retry)\n\tconst hasHistory = await store.hasAgentHistory(featureId, step.agent, step.action);\n\tif (hasHistory) {\n\t\tconst checkpoint = await store.loadAgentHistory(featureId, step.agent, step.action);\n\t\tif (checkpoint) {\n\t\t\tinitialMessages = [...(initialMessages ?? []), ...checkpoint.messages];\n\t\t\tactionPrompt = `[RETRY] Previous attempt for this step exists in your conversation history. Review what went wrong and try a different approach.\\n\\n${actionPrompt}`;\n\t\t}\n\t}\n\n\t// 7. Create agent (inject prior history)\n\tlog.info(`Creating agent: ${step.agent} for action: ${step.action}`, { featureId, hasHistory: !!initialMessages });\n\tconst agent = await createRoleAgent({\n\t\trole: step.agent,\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel: context.model,\n\t\tfeatureContext: inputContent || undefined,\n\t\tgetApiKey: context.getApiKey,\n\t\tinitialMessages,\n\t\tavailableSkills: context.availableSkills,\n\t\tprojectContext: context.projectContext,\n\t});\n\n\t// 8. Agent registration callback\n\tcontext.onAgentCreated?.(agent);\n\n\ttry {\n\t\t// 9. Run agent (with history)\n\t\tlog.info(`Agent executing: ${step.agent}:${step.action}`, { featureId });\n\t\tconst result = await runAgentWithHistory(agent, actionPrompt);\n\n\t\t// 9b. Aggregate token usage\n\t\tcontext.lastStepUsage = aggregateUsage(result.messages);\n\n\t\t// 10. Save history checkpoint\n\t\tawait store.saveAgentHistory(featureId, {\n\t\t\trole: step.agent,\n\t\t\taction: step.action,\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\n\t\t// 11. Save artifacts for readonly roles\n\t\tif (isReadonlyRole(step.agent) && step.outputs.length > 0) {\n\t\t\tconst isSingle = step.outputs.length === 1;\n\t\t\tfor (const output of step.outputs) {\n\t\t\t\tconst content = extractArtifactContent(result.text, output, isSingle);\n\t\t\t\tif (content) {\n\t\t\t\t\tlog.debug(`Extracted artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t\tawait store.writeArtifact(featureId, output as ArtifactName, content);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Failed to extract artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlog.info(`Agent completed: ${step.agent}:${step.action}`, { featureId });\n\t} finally {\n\t\t// 12. Agent release callback\n\t\tcontext.onAgentFinished?.();\n\t}\n};\n"]}
1
+ {"version":3,"file":"step-executor.js","sourceRoot":"","sources":["../src/step-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { createModuleLogger, noopLogger } from \"./logger.js\";\nimport type { StepContext, StepExecutor, StepUsage } from \"./pipeline.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport type { AgentRole, ArtifactName, PipelineStep, TestingConfig } from \"./types.js\";\n\n// ─── Readonly Role Detection ─────────────────────────────────────────────────\n\n/** Roles that cannot write files via tools. Artifacts are extracted from the response and saved to the store. */\nconst READONLY_ROLES: ReadonlySet<AgentRole> = new Set<AgentRole>([\n\t\"planner\",\n\t\"analyzer\",\n\t\"reviewer\",\n\t\"diagnostician\",\n\t\"discovery\",\n\t\"projectAnalyzer\",\n]);\n\n/** Determines whether the role is readonly (cannot write files via tools). */\nexport function isReadonlyRole(role: AgentRole): boolean {\n\treturn READONLY_ROLES.has(role);\n}\n\n// ─── System Design Injection ─────────────────────────────────────────────────\n\n/** Roles that receive system-design.md as additional input context. */\nexport const SYSTEM_DESIGN_ROLES: ReadonlySet<AgentRole> = new Set<AgentRole>([\n\t\"architect\",\n\t\"reviewer\",\n\t\"developer\",\n\t\"tester\",\n\t\"diagnostician\",\n]);\n\n// ─── Usage Aggregation ───────────────────────────────────────────────────────\n\n/**\n * Aggregates token usage from all assistant messages in a conversation.\n * Returns undefined if no assistant messages with usage data are found.\n */\nexport function aggregateUsage(messages: AgentMessage[]): StepUsage | undefined {\n\tlet input = 0;\n\tlet output = 0;\n\tlet cacheRead = 0;\n\tlet cacheWrite = 0;\n\tlet totalTokens = 0;\n\tlet cost = 0;\n\tlet found = false;\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"assistant\" && \"usage\" in msg && msg.usage) {\n\t\t\tconst u = msg.usage as {\n\t\t\t\tinput: number;\n\t\t\t\toutput: number;\n\t\t\t\tcacheRead: number;\n\t\t\t\tcacheWrite: number;\n\t\t\t\ttotalTokens: number;\n\t\t\t\tcost: { total: number };\n\t\t\t};\n\t\t\tfound = true;\n\t\t\tinput += u.input;\n\t\t\toutput += u.output;\n\t\t\tcacheRead += u.cacheRead;\n\t\t\tcacheWrite += u.cacheWrite;\n\t\t\ttotalTokens += u.totalTokens;\n\t\t\tcost += u.cost.total;\n\t\t}\n\t}\n\n\treturn found ? { input, output, cacheRead, cacheWrite, totalTokens, cost } : undefined;\n}\n\n// ─── Input Artifact Loader ───────────────────────────────────────────────────\n\n/**\n * Reads the artifact files specified in step.inputs from the store\n * and combines them into a single context string.\n * Non-existent files are skipped.\n */\nexport async function loadInputArtifacts(inputs: string[], featureId: string, context: StepContext): Promise<string> {\n\tif (inputs.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst sections: string[] = [];\n\n\tfor (const input of inputs) {\n\t\tconst hasFile = await context.store.hasArtifact(featureId, input as ArtifactName);\n\t\tif (!hasFile) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst content = await context.store.readArtifact(featureId, input as ArtifactName);\n\t\tsections.push(`## Input: ${input}\\n\\n${content}`);\n\t}\n\n\treturn sections.join(\"\\n\\n---\\n\\n\");\n}\n\n// ─── Artifact Extraction ─────────────────────────────────────────────────────\n\nfunction escapeRegex(str: string): string {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Extracts artifact content from agent response text.\n * Used when a readonly role outputs markdown artifacts as text.\n *\n * Extraction strategies:\n * 1. Extract from ```artifactName code block (with nested fence pairing)\n * 2. Extract from ## artifactName section\n * 3. Return the entire response if it's a single output\n */\nexport function extractArtifactContent(\n\tresponseText: string,\n\tartifactName: string,\n\tisSingleOutput: boolean = false,\n): string | null {\n\tif (!responseText.trim()) {\n\t\treturn null;\n\t}\n\n\t// Pattern 1: ```artifactName\\n...\\n``` with nested code fence pairing.\n\t// A simple non-greedy regex fails when the content itself contains ``` fences\n\t// (e.g., directory trees or code examples inside a project-context.md artifact).\n\t// Instead, we find the opening fence and then iterate through subsequent fence\n\t// markers, pairing them (inner-open, inner-close) until we find the unpaired\n\t// closing fence for the outer block.\n\tconst content1 = extractFromCodeFence(responseText, artifactName);\n\tif (content1 !== null) {\n\t\treturn content1;\n\t}\n\n\t// Pattern 2: Content after ## artifactName (without m flag so $ matches end of string)\n\tconst pattern2 = new RegExp(`##\\\\s+${escapeRegex(artifactName)}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n##\\\\s|$)`);\n\tconst match2 = pattern2.exec(responseText);\n\tif (match2) {\n\t\treturn match2[1].trim();\n\t}\n\n\t// Pattern 3: Use the entire response if it's a single output\n\tif (isSingleOutput) {\n\t\treturn responseText.trim();\n\t}\n\n\treturn null;\n}\n\n/**\n * Extracts content from a fenced code block that may contain nested code fences.\n *\n * Algorithm:\n * 1. Find the opening fence (``` followed by artifactName)\n * 2. After the opening, scan for all ``` markers on their own lines\n * 3. Inner fences pair up sequentially (open+close). The first unpaired marker\n * is the closing fence of the outer block.\n */\nfunction extractFromCodeFence(text: string, artifactName: string): string | null {\n\t// Match the opening fence line: ```artifactName (possibly with trailing whitespace)\n\tconst openPattern = new RegExp(`^(\\`{3,})${escapeRegex(artifactName)}[ \\\\t]*$`, \"m\");\n\tconst openMatch = openPattern.exec(text);\n\tif (!openMatch) {\n\t\treturn null;\n\t}\n\n\tconst openTickCount = openMatch[1].length;\n\tconst contentStart = openMatch.index + openMatch[0].length + 1; // +1 for the newline\n\n\t// Collect fence markers after the opening fence, stopping at the next\n\t// artifact-level opening fence (a fence whose info string looks like a\n\t// file path — contains '.' or '/'). This prevents consuming fences that\n\t// belong to subsequent artifacts in multi-artifact responses.\n\tconst rest = text.slice(contentStart);\n\tconst fencePattern = /^(`{3,})[ \\t]*(\\S*)?[ \\t]*$/gm;\n\n\tinterface FenceMarker {\n\t\tindex: number;\n\t\ttickCount: number;\n\t\tinfoString: string;\n\t}\n\n\tconst markers: FenceMarker[] = [];\n\tfor (;;) {\n\t\tconst match = fencePattern.exec(rest);\n\t\tif (match === null) break;\n\t\tconst infoString = match[2] || \"\";\n\n\t\t// Stop at the next artifact-level opening fence (file-like info string)\n\t\tif (infoString !== \"\" && isArtifactInfoString(infoString)) {\n\t\t\tbreak;\n\t\t}\n\n\t\tmarkers.push({\n\t\t\tindex: match.index,\n\t\t\ttickCount: match[1].length,\n\t\t\tinfoString,\n\t\t});\n\t}\n\n\tif (markers.length === 0) {\n\t\treturn null;\n\t}\n\n\t// Within the bounded markers, find the outer closing fence.\n\t// Use the last bare fence (no info string) with >= openTickCount backticks.\n\t// Inner bare fences pair up (open+close) before it; the remaining one is\n\t// the outer close.\n\tfor (let i = markers.length - 1; i >= 0; i--) {\n\t\tconst m = markers[i];\n\t\tif (m.infoString === \"\" && m.tickCount >= openTickCount) {\n\t\t\tconst content = rest.slice(0, m.index);\n\t\t\treturn content.trim();\n\t\t}\n\t}\n\n\t// No valid closing fence found — return null (fall through to other patterns)\n\treturn null;\n}\n\n/**\n * Determines if a code fence info string looks like an artifact file path\n * rather than a code language identifier.\n *\n * Artifact info strings contain '.' (file extension) or '/' (path separator),\n * e.g., \"spec.md\", \"feat-auth/spec.md\", \"plan.json\".\n * Code language info strings are simple identifiers like \"python\", \"bash\", \"json\", \"text\".\n */\nfunction isArtifactInfoString(infoString: string): boolean {\n\treturn infoString.includes(\".\") || infoString.includes(\"/\");\n}\n\n// ─── Skill Search Instructions ───────────────────────────────────────────────\n\n/**\n * Instructions for searching past artifacts to add to specific actions when availableSkills is present.\n * The \"past feature artifacts\" keyword matches the qmd-memory description in Available Skills.\n */\nconst SKILL_SEARCH_INSTRUCTIONS: Readonly<Record<string, string>> = {\n\tplan: \"Before planning, search past feature artifacts for similar features, design patterns, or recurring decisions.\",\n\tdesign: \"Before designing, search past feature artifacts for related design patterns and architectural decisions.\",\n\ttest: \"Search past feature artifacts for related test patterns, integration points, and previously discovered defects before writing tests.\",\n\tregression:\n\t\t\"Search past feature artifacts for areas previously affected by regressions before running regression tests.\",\n\treview: \"Search past feature artifacts for recurring review feedback and common issues before reviewing.\",\n\tinvestigate: \"Search past feature artifacts for similar issues and prior investigation findings.\",\n\tdiagnose: \"Search past feature artifacts for similar bug patterns and fix strategies.\",\n\timplement:\n\t\t\"Search past feature artifacts for similar implementation patterns, code conventions, and lessons learned before implementing.\",\n\tfix: \"Search past feature artifacts for similar fixes, related code areas, and previously applied fix strategies.\",\n\tanalyze:\n\t\t\"Search past feature artifacts for prior impact analyses, affected areas, and risk patterns before analyzing.\",\n};\n\n// ─── Action Prompt Builder ───────────────────────────────────────────────────\n\n/**\n * Builds the prompt to send to the agent based on the step's agent role and action.\n */\nexport function buildActionPrompt(\n\tstep: PipelineStep,\n\tfeatureId: string,\n\tinputContent: string,\n\tartifactDir: string,\n\tavailableSkills?: string,\n\tbaseBranch?: string,\n\ttestingConfig?: TestingConfig,\n\tprojectRoot?: string,\n): string {\n\tconst parts: string[] = [];\n\n\tparts.push(`You are working on feature \"${featureId}\".`);\n\tif (projectRoot) {\n\t\tparts.push(\n\t\t\t`The project root is \\`${projectRoot}\\`. All tool commands (bash, read, write, edit) ` +\n\t\t\t\t`execute relative to this directory. Do NOT prefix commands with \\`cd\\` to a different base directory.`,\n\t\t);\n\t}\n\tparts.push(\"\");\n\tparts.push(`## Task: ${step.action}`);\n\tparts.push(\"\");\n\tparts.push(getActionInstructions(step.agent, step.action, baseBranch));\n\n\tif (availableSkills) {\n\t\tconst skillInstruction = SKILL_SEARCH_INSTRUCTIONS[step.action];\n\t\tif (skillInstruction) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(skillInstruction);\n\t\t}\n\t}\n\n\tif (inputContent) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Input Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(inputContent);\n\t}\n\n\tif (step.outputs.length > 0) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Output Artifacts\");\n\t\tparts.push(\"\");\n\t\tparts.push(\"You must produce the following artifacts:\");\n\t\tfor (const output of step.outputs) {\n\t\t\tparts.push(`- \\`${output}\\` → \\`${artifactDir}/${output}\\``);\n\t\t}\n\n\t\tif (isReadonlyRole(step.agent)) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"Since you cannot write files directly, output the content of each artifact \" +\n\t\t\t\t\t\"in a markdown code block with the artifact filename as the info string. \" +\n\t\t\t\t\t\"For example: ```spec.md\\\\n(content)\\\\n```\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"Write each artifact directly to the specified file path using your tools.\");\n\t\t}\n\t}\n\n\t// Inject testing config for developer and tester actions\n\tif (testingConfig?.testCommand) {\n\t\tconst shouldInject =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInject) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## Project Test Configuration\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(`- **Test command**: \\`${testingConfig.testCommand}\\``);\n\t\t\tparts.push(`- **Timeout**: ${testingConfig.testTimeout} seconds`);\n\t\t\tparts.push(`- **Run existing tests**: ${testingConfig.runExistingTests}`);\n\t\t\tif (testingConfig.excludePatterns.length > 0) {\n\t\t\t\tparts.push(`- **Exclude patterns**: ${testingConfig.excludePatterns.join(\", \")}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Inject CI checks for developer and tester actions (tester can write/edit files too)\n\tif (testingConfig?.ciChecks && testingConfig.ciChecks.length > 0) {\n\t\tconst shouldInjectCiChecks =\n\t\t\t(step.agent === \"developer\" && (step.action === \"implement\" || step.action === \"fix\")) ||\n\t\t\t(step.agent === \"tester\" && (step.action === \"test\" || step.action === \"regression\"));\n\n\t\tif (shouldInjectCiChecks) {\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\"## CI Verification Commands\");\n\t\t\tparts.push(\"\");\n\t\t\tparts.push(\n\t\t\t\t\"You MUST run the following checks after implementation. All must pass before the task is complete.\",\n\t\t\t);\n\t\t\tparts.push(\"\");\n\t\t\tfor (const check of testingConfig.ciChecks) {\n\t\t\t\tparts.push(`- **${check.name}**: \\`${check.command}\\``);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n\n/**\n * Returns instructions for the given action.\n */\nfunction getActionInstructions(agent: AgentRole, action: string, baseBranch?: string): string {\n\tswitch (action) {\n\t\tcase \"plan\":\n\t\t\treturn \"Analyze the requirements and decompose them into features. Produce a spec.md for each feature and update plan.json.\";\n\n\t\tcase \"design\":\n\t\t\treturn \"Read the spec and produce a detailed design document with file structure, interfaces, and implementation guide.\";\n\n\t\tcase \"implement\":\n\t\t\treturn \"Implement the feature according to the spec and design documents. Write source code files and ensure they compile.\";\n\n\t\tcase \"fix\":\n\t\t\treturn \"Fix the bug as described in the diagnosis. Apply the minimal change necessary.\";\n\n\t\tcase \"test\":\n\t\t\treturn \"Write comprehensive tests for the feature and run them. Produce a test-report.md with results.\";\n\n\t\tcase \"regression\":\n\t\t\treturn \"Run existing tests to verify no regressions were introduced. Produce a regression-report.md with results.\";\n\n\t\tcase \"review\":\n\t\t\treturn \"Review the implementation for correctness, quality, architecture compliance, and standards compliance. Produce a review.md with your verdict.\";\n\n\t\tcase \"branch\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Create a feature branch from \\`${baseBranch}\\`. Run \\`git checkout ${baseBranch}\\` first, then create the branch.`\n\t\t\t\t: `Create a feature branch for ${agent === \"cicd\" ? \"this feature\" : \"the implementation\"}.`;\n\n\t\tcase \"merge\":\n\t\t\treturn baseBranch\n\t\t\t\t? `Merge the feature branch into \\`${baseBranch}\\` using \\`--no-ff\\`. Run \\`git checkout ${baseBranch}\\` first, then merge. Do NOT run \\`git push\\` — push is handled by the orchestration system.`\n\t\t\t\t: \"Merge the feature branch after all checks pass. Do NOT run `git push`.\";\n\n\t\tcase \"analyze\":\n\t\t\treturn \"Analyze the impact of the proposed change on the existing codebase. Produce an impact-report.md.\";\n\n\t\tcase \"investigate\":\n\t\t\treturn \"Trace through the code to identify the root cause of the issue. Use read and bash tools to explore the codebase, run tests, add debug output if needed. Do not produce any artifacts — this is an exploratory step. Your findings will inform the subsequent diagnosis step.\";\n\n\t\tcase \"diagnose\":\n\t\t\treturn \"Analyze the bug, reproduce it, identify the root cause, and produce a diagnosis.md.\";\n\n\t\tdefault:\n\t\t\treturn `Execute the \"${action}\" task for this feature.`;\n\t}\n}\n\n// ─── Default Step Executor ───────────────────────────────────────────────────\n\n/**\n * Default StepExecutor implementation.\n * Creates a role-specific agent, passes input artifacts as context,\n * runs the agent, and saves the output artifacts.\n */\nexport const defaultStepExecutor: StepExecutor = async (step, featureId, context) => {\n\tconst { store, config, projectRoot } = context;\n\tconst log = createModuleLogger(context.logger ?? noopLogger, \"step-executor\");\n\n\t// 1. Ensure feature directory exists\n\tawait store.ensureFeatureDir(featureId);\n\n\t// 2. Load input artifacts\n\tlog.debug(`Loading input artifacts: [${step.inputs.join(\", \")}]`, { featureId, agent: step.agent });\n\tlet inputContent = await loadInputArtifacts(step.inputs, featureId, context);\n\n\t// 2b. Inject system-design.md for roles that need system-level architecture context\n\tif (SYSTEM_DESIGN_ROLES.has(step.agent) && (await store.hasSystemDesign())) {\n\t\tconst systemDesign = await store.readSystemDesign();\n\t\tconst systemDesignSection = `## Input: system-design.md (System Architecture)\\n\\n${systemDesign}`;\n\t\tinputContent = inputContent ? `${inputContent}\\n\\n---\\n\\n${systemDesignSection}` : systemDesignSection;\n\t\tlog.debug(`Injected system-design.md into ${step.agent} context`, { featureId });\n\t}\n\n\t// 3. Get system prompt\n\tconst systemPrompt = getSystemPromptForRole(step.agent);\n\n\t// 4. Artifact directory path\n\tconst artifactDir = store.getFeatureDir(featureId);\n\n\t// 5. Build execution prompt\n\tlet actionPrompt = buildActionPrompt(\n\t\tstep,\n\t\tfeatureId,\n\t\tinputContent,\n\t\tartifactDir,\n\t\tcontext.availableSkills,\n\t\tconfig.baseBranch,\n\t\tconfig.testing,\n\t\tprojectRoot,\n\t);\n\n\t// 6a. Load prior action history for the same role (only when step opts in)\n\tlet initialMessages: import(\"@mariozechner/pi-agent-core\").AgentMessage[] | undefined;\n\tif (step.inheritPriorHistory) {\n\t\tconst priorCheckpoints = await store.loadPriorAgentHistory(featureId, step.agent, step.action);\n\t\tif (priorCheckpoints.length > 0) {\n\t\t\tlog.debug(`Loading prior action history for ${step.agent}: ${priorCheckpoints.length} checkpoint(s)`, {\n\t\t\t\tfeatureId,\n\t\t\t\tagent: step.agent,\n\t\t\t});\n\t\t\tinitialMessages = priorCheckpoints.flatMap((cp) => cp.messages);\n\t\t}\n\t}\n\n\t// 6b. If retry history exists for the current action, append it (checkpoint restoration on retry)\n\tconst hasHistory = await store.hasAgentHistory(featureId, step.agent, step.action);\n\tif (hasHistory) {\n\t\tconst checkpoint = await store.loadAgentHistory(featureId, step.agent, step.action);\n\t\tif (checkpoint) {\n\t\t\tinitialMessages = [...(initialMessages ?? []), ...checkpoint.messages];\n\t\t\tactionPrompt = `[RETRY] Previous attempt for this step exists in your conversation history. Review what went wrong and try a different approach.\\n\\n${actionPrompt}`;\n\t\t}\n\t}\n\n\t// 7. Create agent (inject prior history)\n\tlog.info(`Creating agent: ${step.agent} for action: ${step.action}`, { featureId, hasHistory: !!initialMessages });\n\tconst agent = await createRoleAgent({\n\t\trole: step.agent,\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel: context.model,\n\t\tfeatureContext: inputContent || undefined,\n\t\tgetApiKey: context.getApiKey,\n\t\tinitialMessages,\n\t\tavailableSkills: context.availableSkills,\n\t});\n\n\t// 8. Agent registration callback\n\tcontext.onAgentCreated?.(agent);\n\n\ttry {\n\t\t// 9. Run agent (with history)\n\t\tlog.info(`Agent executing: ${step.agent}:${step.action}`, { featureId });\n\t\tconst result = await runAgentWithHistory(agent, actionPrompt);\n\n\t\t// 9b. Aggregate token usage and capture response text\n\t\tcontext.lastStepUsage = aggregateUsage(result.messages);\n\t\tcontext.lastStepResponseText = result.text;\n\n\t\t// 10. Save history checkpoint\n\t\tawait store.saveAgentHistory(featureId, {\n\t\t\trole: step.agent,\n\t\t\taction: step.action,\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\n\t\t// 11. Save artifacts for readonly roles\n\t\tif (isReadonlyRole(step.agent) && step.outputs.length > 0) {\n\t\t\tconst isSingle = step.outputs.length === 1;\n\t\t\tfor (const output of step.outputs) {\n\t\t\t\tconst content = extractArtifactContent(result.text, output, isSingle);\n\t\t\t\tif (content) {\n\t\t\t\t\tlog.debug(`Extracted artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t\tawait store.writeArtifact(featureId, output as ArtifactName, content);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Failed to extract artifact: ${output}`, { featureId, agent: step.agent });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlog.info(`Agent completed: ${step.agent}:${step.action}`, { featureId });\n\t} finally {\n\t\t// 12. Agent release callback\n\t\tcontext.onAgentFinished?.();\n\t}\n};\n"]}
package/dist/store.d.ts CHANGED
@@ -164,6 +164,9 @@ export declare class VibeStore {
164
164
  readSkillContent(skillName: string): Promise<string>;
165
165
  /** Extracts only the description from a vibe skill's SKILL.md frontmatter. Returns null if not found. */
166
166
  readSkillDescription(skillName: string): Promise<string | null>;
167
+ /** Deletes the entire .vibe/ directory and re-initializes from scratch. */
168
+ reset(): Promise<void>;
169
+ private ensureRootGitignore;
167
170
  private fileExists;
168
171
  }
169
172
  //# sourceMappingURL=store.d.ts.map