@wizdear/atlas-code 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agent-factory.d.ts +2 -4
- package/dist/agent-factory.d.ts.map +1 -1
- package/dist/agent-factory.js +9 -12
- package/dist/agent-factory.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +64 -16
- package/dist/cli.js.map +1 -1
- package/dist/discovery.d.ts +0 -2
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +0 -1
- package/dist/discovery.js.map +1 -1
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +23 -64
- package/dist/extension.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator.d.ts +0 -2
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +0 -1
- package/dist/orchestrator.js.map +1 -1
- package/dist/pipeline.d.ts +0 -5
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +0 -3
- package/dist/pipeline.js.map +1 -1
- package/dist/planner.d.ts +0 -2
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +0 -6
- package/dist/planner.js.map +1 -1
- package/dist/roles/cicd.d.ts +1 -1
- package/dist/roles/cicd.d.ts.map +1 -1
- package/dist/roles/cicd.js +5 -0
- package/dist/roles/cicd.js.map +1 -1
- package/dist/roles/reviewer.d.ts +1 -1
- package/dist/roles/reviewer.d.ts.map +1 -1
- package/dist/roles/reviewer.js +7 -1
- package/dist/roles/reviewer.js.map +1 -1
- package/dist/roles/standards-enricher.d.ts +1 -1
- package/dist/roles/standards-enricher.d.ts.map +1 -1
- package/dist/roles/standards-enricher.js +8 -0
- package/dist/roles/standards-enricher.js.map +1 -1
- package/dist/roles/tester.d.ts +1 -1
- package/dist/roles/tester.d.ts.map +1 -1
- package/dist/roles/tester.js +7 -0
- package/dist/roles/tester.js.map +1 -1
- package/dist/standards.d.ts +37 -11
- package/dist/standards.d.ts.map +1 -1
- package/dist/standards.js +71 -90
- package/dist/standards.js.map +1 -1
- package/dist/step-executor.d.ts +13 -2
- package/dist/step-executor.d.ts.map +1 -1
- package/dist/step-executor.js +125 -29
- package/dist/step-executor.js.map +1 -1
- package/dist/store.d.ts +0 -10
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +0 -41
- package/dist/store.js.map +1 -1
- package/dist/system-architect.d.ts +0 -2
- package/dist/system-architect.d.ts.map +1 -1
- package/dist/system-architect.js +0 -6
- package/dist/system-architect.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type { CreatePipelineOptions, WorkflowClassification } from "./router.js"
|
|
|
24
24
|
export { bugfixSteps, classifyWorkflow, createPipeline, enhancementSteps, inferWorkflowType, newFeatureSteps, refactorSteps, resolveExecutionOrder, resolveFeatureWorkflowType, } from "./router.js";
|
|
25
25
|
export type { GatePolicy, SdkModelSpec, VibeSession, VibeSessionOptions, VibeSessionResult, WorkflowOptions, } from "./sdk.js";
|
|
26
26
|
export { createVibeSession } from "./sdk.js";
|
|
27
|
-
export {
|
|
27
|
+
export { buildStandardsIndex, formatStandardsIndexPrompt, generateFrontmatter, parseFrontmatter, type StandardsIndexEntry, type StandardsIndexResult, } from "./standards.js";
|
|
28
28
|
export { aggregateUsage, buildActionPrompt, defaultStepExecutor, extractArtifactContent, isReadonlyRole, loadInputArtifacts, } from "./step-executor.js";
|
|
29
29
|
export { VibeStore } from "./store.js";
|
|
30
30
|
export { extractMappedRequirementIds, extractRequirementIds, findUnmappedRequirements } from "./traceability.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,YAAY,EAAE,sBAAsB,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACxG,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,QAAQ,GACR,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAClF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,aAAa,IAAI,OAAO,GACxB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAClG,OAAO,EACN,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5E,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrE,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,uBAAuB,EACvB,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,8BAA8B,EAC9B,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,0BAA0B,GAC1B,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,UAAU,EACV,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,GACf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// @wizdear/atlas-code\n// AI Vibe Engineering System - Multi-agent orchestration for pi-coding-agent\n//\n// Implementation will be added per feature specs in .vibe/features/\n\nexport type { CreateRoleAgentOptions, GetApiKeyFn, RunAgentOptions, ToolSet } from \"./agent-factory.js\";\nexport {\n\tbuildSystemPrompt,\n\tcreateRoleAgent,\n\textractLastAssistantText,\n\tgetToolsForRole,\n\tROLE_TOOL_SETS,\n\trunAgent,\n} from \"./agent-factory.js\";\nexport type { VibeCommand } from \"./cli.js\";\nexport { parseVibeCommand, STANDARD_TEMPLATES, VIBE_SUBCOMMANDS } from \"./cli.js\";\nexport type { DiscoveryOptions, DiscoveryResult } from \"./discovery.js\";\nexport { COMPLETE_MARKER, QUESTION_MARKER, runDiscovery } from \"./discovery.js\";\nexport {\n\tCHAT_VISIBLE_EVENTS,\n\tPHASE_ORDER,\n\tresolveResumePhase,\n\tvibeExtension,\n\tvibeExtension as default,\n} from \"./extension.js\";\nexport type { ApprovalRequestFn, EscalationEvent, EscalationReason, GateResult } from \"./gate.js\";\nexport {\n\tGateChecker,\n\thasTestReportRegexMatch,\n\tparseRegressionVerdict,\n\tparseReviewVerdict,\n\tparseStandardsCompliance,\n\tparseTestReportPassed,\n} from \"./gate.js\";\nexport type { LogLevel, ModuleLogger, VibeLogEntry, VibeLogger } from \"./logger.js\";\nexport { createModuleLogger, formatLogLine, noopLogger } from \"./logger.js\";\nexport type { OrchestrationOptions, OrchestrationResult } from \"./orchestrator.js\";\nexport { findDependents, runOrchestration } from \"./orchestrator.js\";\nexport type { PipelineRunnerOptions, StepContext, StepExecutor, StepUsage } from \"./pipeline.js\";\nexport { agentRoleToFeatureStatus, PipelineRunner } from \"./pipeline.js\";\nexport type { PipelineStepInfo } from \"./pipeline-editor.js\";\nexport { PipelineEditorComponent } from \"./pipeline-editor.js\";\nexport type { PlannerOptions, PlannerResult } from \"./planner.js\";\nexport { runPlanner } from \"./planner.js\";\nexport type { FailureSource, RetryAttempt, RetryContext } from \"./retry.js\";\nexport { RetryManager } from \"./retry.js\";\nexport {\n\tANALYZER_ROLE,\n\tANALYZER_SYSTEM_PROMPT,\n\tARCHITECT_ROLE,\n\tARCHITECT_SYSTEM_PROMPT,\n\tCICD_ROLE,\n\tCICD_SYSTEM_PROMPT,\n\tDEVELOPER_ROLE,\n\tDEVELOPER_SYSTEM_PROMPT,\n\tDIAGNOSTICIAN_ROLE,\n\tDIAGNOSTICIAN_SYSTEM_PROMPT,\n\tDISCOVERY_ROLE,\n\tDISCOVERY_SYSTEM_PROMPT,\n\tgetSystemPromptForRole,\n\tPLANNER_ROLE,\n\tPLANNER_SYSTEM_PROMPT,\n\tPROJECT_ANALYZER_ROLE,\n\tPROJECT_ANALYZER_SYSTEM_PROMPT,\n\tREVIEWER_ROLE,\n\tREVIEWER_SYSTEM_PROMPT,\n\tROLE_SYSTEM_PROMPTS,\n\tTESTER_ROLE,\n\tTESTER_SYSTEM_PROMPT,\n} from \"./roles/index.js\";\nexport type { CreatePipelineOptions, WorkflowClassification } from \"./router.js\";\nexport {\n\tbugfixSteps,\n\tclassifyWorkflow,\n\tcreatePipeline,\n\tenhancementSteps,\n\tinferWorkflowType,\n\tnewFeatureSteps,\n\trefactorSteps,\n\tresolveExecutionOrder,\n\tresolveFeatureWorkflowType,\n} from \"./router.js\";\nexport type {\n\tGatePolicy,\n\tSdkModelSpec,\n\tVibeSession,\n\tVibeSessionOptions,\n\tVibeSessionResult,\n\tWorkflowOptions,\n} from \"./sdk.js\";\nexport { createVibeSession } from \"./sdk.js\";\nexport {\n\tbuildStandardsIndex,\n\tformatStandardsIndexPrompt,\n\tgenerateFrontmatter,\n\tparseFrontmatter,\n\ttype StandardsIndexEntry,\n\ttype StandardsIndexResult,\n} from \"./standards.js\";\nexport {\n\taggregateUsage,\n\tbuildActionPrompt,\n\tdefaultStepExecutor,\n\textractArtifactContent,\n\tisReadonlyRole,\n\tloadInputArtifacts,\n} from \"./step-executor.js\";\nexport { VibeStore } from \"./store.js\";\nexport { extractMappedRequirementIds, extractRequirementIds, findUnmappedRequirements } from \"./traceability.js\";\nexport type {\n\t// Agent\n\tAgentRole,\n\tAgentRoleConfig,\n\tArtifactName,\n\t// Config\n\tAutonomyLevel,\n\tDiscoveryConfig,\n\tFeatureComplexity,\n\tFeaturePipeline,\n\tFeatureStatus,\n\t// Store\n\tFeatureStatusValue,\n\tGateCondition,\n\tGateConditionType,\n\tGateConfig,\n\tNotificationChannel,\n\tNotificationConfig,\n\t// Pipeline\n\tPipelineStatus,\n\tPipelineStep,\n\tPlanData,\n\tPlanFeature,\n\tProjectAnalysisConfig,\n\tRetryConfig,\n\tRoleStandardsMapping,\n\t// Standards\n\tStandardFileName,\n\tStandardsConfig,\n\tVibeConfig,\n\tVibeEvent,\n\t// Events\n\tVibeEventType,\n\tWorkflowDefinition,\n\t// Workflow\n\tWorkflowType,\n} from \"./types.js\";\nexport { formatFeatureDetail, formatPipelineStatus, formatVibeEvent, VIBE_HELP } from \"./ui.js\";\nexport type { RegressionVerdict, ReviewVerdict, TestVerdict } from \"./verdict-extractor.js\";\nexport {\n\textractRegressionVerdictWithLLM,\n\textractReviewVerdictWithLLM,\n\textractTestVerdictWithLLM,\n} from \"./verdict-extractor.js\";\n"]}
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ export { RetryManager } from "./retry.js";
|
|
|
16
16
|
export { ANALYZER_ROLE, ANALYZER_SYSTEM_PROMPT, ARCHITECT_ROLE, ARCHITECT_SYSTEM_PROMPT, CICD_ROLE, CICD_SYSTEM_PROMPT, DEVELOPER_ROLE, DEVELOPER_SYSTEM_PROMPT, DIAGNOSTICIAN_ROLE, DIAGNOSTICIAN_SYSTEM_PROMPT, DISCOVERY_ROLE, DISCOVERY_SYSTEM_PROMPT, getSystemPromptForRole, PLANNER_ROLE, PLANNER_SYSTEM_PROMPT, PROJECT_ANALYZER_ROLE, PROJECT_ANALYZER_SYSTEM_PROMPT, REVIEWER_ROLE, REVIEWER_SYSTEM_PROMPT, ROLE_SYSTEM_PROMPTS, TESTER_ROLE, TESTER_SYSTEM_PROMPT, } from "./roles/index.js";
|
|
17
17
|
export { bugfixSteps, classifyWorkflow, createPipeline, enhancementSteps, inferWorkflowType, newFeatureSteps, refactorSteps, resolveExecutionOrder, resolveFeatureWorkflowType, } from "./router.js";
|
|
18
18
|
export { createVibeSession } from "./sdk.js";
|
|
19
|
-
export {
|
|
19
|
+
export { buildStandardsIndex, formatStandardsIndexPrompt, generateFrontmatter, parseFrontmatter, } from "./standards.js";
|
|
20
20
|
export { aggregateUsage, buildActionPrompt, defaultStepExecutor, extractArtifactContent, isReadonlyRole, loadInputArtifacts, } from "./step-executor.js";
|
|
21
21
|
export { VibeStore } from "./store.js";
|
|
22
22
|
export { extractMappedRequirementIds, extractRequirementIds, findUnmappedRequirements } from "./traceability.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,6EAA6E;AAC7E,EAAE;AACF,oEAAoE;AAGpE,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,QAAQ,GACR,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,aAAa,IAAI,OAAO,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACN,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,GACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,uBAAuB,EACvB,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,8BAA8B,EAC9B,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,0BAA0B,GAC1B,MAAM,aAAa,CAAC;AASrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,6EAA6E;AAC7E,EAAE;AACF,oEAAoE;AAGpE,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,QAAQ,GACR,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,aAAa,IAAI,OAAO,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACN,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,GACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,uBAAuB,EACvB,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,8BAA8B,EAC9B,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,0BAA0B,GAC1B,MAAM,aAAa,CAAC;AASrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,GAGhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,kBAAkB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAsCjH,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEhG,OAAO,EACN,+BAA+B,EAC/B,2BAA2B,EAC3B,yBAAyB,GACzB,MAAM,wBAAwB,CAAC","sourcesContent":["// @wizdear/atlas-code\n// AI Vibe Engineering System - Multi-agent orchestration for pi-coding-agent\n//\n// Implementation will be added per feature specs in .vibe/features/\n\nexport type { CreateRoleAgentOptions, GetApiKeyFn, RunAgentOptions, ToolSet } from \"./agent-factory.js\";\nexport {\n\tbuildSystemPrompt,\n\tcreateRoleAgent,\n\textractLastAssistantText,\n\tgetToolsForRole,\n\tROLE_TOOL_SETS,\n\trunAgent,\n} from \"./agent-factory.js\";\nexport type { VibeCommand } from \"./cli.js\";\nexport { parseVibeCommand, STANDARD_TEMPLATES, VIBE_SUBCOMMANDS } from \"./cli.js\";\nexport type { DiscoveryOptions, DiscoveryResult } from \"./discovery.js\";\nexport { COMPLETE_MARKER, QUESTION_MARKER, runDiscovery } from \"./discovery.js\";\nexport {\n\tCHAT_VISIBLE_EVENTS,\n\tPHASE_ORDER,\n\tresolveResumePhase,\n\tvibeExtension,\n\tvibeExtension as default,\n} from \"./extension.js\";\nexport type { ApprovalRequestFn, EscalationEvent, EscalationReason, GateResult } from \"./gate.js\";\nexport {\n\tGateChecker,\n\thasTestReportRegexMatch,\n\tparseRegressionVerdict,\n\tparseReviewVerdict,\n\tparseStandardsCompliance,\n\tparseTestReportPassed,\n} from \"./gate.js\";\nexport type { LogLevel, ModuleLogger, VibeLogEntry, VibeLogger } from \"./logger.js\";\nexport { createModuleLogger, formatLogLine, noopLogger } from \"./logger.js\";\nexport type { OrchestrationOptions, OrchestrationResult } from \"./orchestrator.js\";\nexport { findDependents, runOrchestration } from \"./orchestrator.js\";\nexport type { PipelineRunnerOptions, StepContext, StepExecutor, StepUsage } from \"./pipeline.js\";\nexport { agentRoleToFeatureStatus, PipelineRunner } from \"./pipeline.js\";\nexport type { PipelineStepInfo } from \"./pipeline-editor.js\";\nexport { PipelineEditorComponent } from \"./pipeline-editor.js\";\nexport type { PlannerOptions, PlannerResult } from \"./planner.js\";\nexport { runPlanner } from \"./planner.js\";\nexport type { FailureSource, RetryAttempt, RetryContext } from \"./retry.js\";\nexport { RetryManager } from \"./retry.js\";\nexport {\n\tANALYZER_ROLE,\n\tANALYZER_SYSTEM_PROMPT,\n\tARCHITECT_ROLE,\n\tARCHITECT_SYSTEM_PROMPT,\n\tCICD_ROLE,\n\tCICD_SYSTEM_PROMPT,\n\tDEVELOPER_ROLE,\n\tDEVELOPER_SYSTEM_PROMPT,\n\tDIAGNOSTICIAN_ROLE,\n\tDIAGNOSTICIAN_SYSTEM_PROMPT,\n\tDISCOVERY_ROLE,\n\tDISCOVERY_SYSTEM_PROMPT,\n\tgetSystemPromptForRole,\n\tPLANNER_ROLE,\n\tPLANNER_SYSTEM_PROMPT,\n\tPROJECT_ANALYZER_ROLE,\n\tPROJECT_ANALYZER_SYSTEM_PROMPT,\n\tREVIEWER_ROLE,\n\tREVIEWER_SYSTEM_PROMPT,\n\tROLE_SYSTEM_PROMPTS,\n\tTESTER_ROLE,\n\tTESTER_SYSTEM_PROMPT,\n} from \"./roles/index.js\";\nexport type { CreatePipelineOptions, WorkflowClassification } from \"./router.js\";\nexport {\n\tbugfixSteps,\n\tclassifyWorkflow,\n\tcreatePipeline,\n\tenhancementSteps,\n\tinferWorkflowType,\n\tnewFeatureSteps,\n\trefactorSteps,\n\tresolveExecutionOrder,\n\tresolveFeatureWorkflowType,\n} from \"./router.js\";\nexport type {\n\tGatePolicy,\n\tSdkModelSpec,\n\tVibeSession,\n\tVibeSessionOptions,\n\tVibeSessionResult,\n\tWorkflowOptions,\n} from \"./sdk.js\";\nexport { createVibeSession } from \"./sdk.js\";\nexport {\n\tbuildStandardsIndex,\n\tformatStandardsIndexPrompt,\n\tgenerateFrontmatter,\n\tparseFrontmatter,\n\ttype StandardsIndexEntry,\n\ttype StandardsIndexResult,\n} from \"./standards.js\";\nexport {\n\taggregateUsage,\n\tbuildActionPrompt,\n\tdefaultStepExecutor,\n\textractArtifactContent,\n\tisReadonlyRole,\n\tloadInputArtifacts,\n} from \"./step-executor.js\";\nexport { VibeStore } from \"./store.js\";\nexport { extractMappedRequirementIds, extractRequirementIds, findUnmappedRequirements } from \"./traceability.js\";\nexport type {\n\t// Agent\n\tAgentRole,\n\tAgentRoleConfig,\n\tArtifactName,\n\t// Config\n\tAutonomyLevel,\n\tDiscoveryConfig,\n\tFeatureComplexity,\n\tFeaturePipeline,\n\tFeatureStatus,\n\t// Store\n\tFeatureStatusValue,\n\tGateCondition,\n\tGateConditionType,\n\tGateConfig,\n\tNotificationChannel,\n\tNotificationConfig,\n\t// Pipeline\n\tPipelineStatus,\n\tPipelineStep,\n\tPlanData,\n\tPlanFeature,\n\tProjectAnalysisConfig,\n\tRetryConfig,\n\tRoleStandardsMapping,\n\t// Standards\n\tStandardFileName,\n\tStandardsConfig,\n\tVibeConfig,\n\tVibeEvent,\n\t// Events\n\tVibeEventType,\n\tWorkflowDefinition,\n\t// Workflow\n\tWorkflowType,\n} from \"./types.js\";\nexport { formatFeatureDetail, formatPipelineStatus, formatVibeEvent, VIBE_HELP } from \"./ui.js\";\nexport type { RegressionVerdict, ReviewVerdict, TestVerdict } from \"./verdict-extractor.js\";\nexport {\n\textractRegressionVerdictWithLLM,\n\textractReviewVerdictWithLLM,\n\textractTestVerdictWithLLM,\n} from \"./verdict-extractor.js\";\n"]}
|
package/dist/orchestrator.d.ts
CHANGED
|
@@ -25,8 +25,6 @@ export interface OrchestrationOptions {
|
|
|
25
25
|
skipCompletedFeatures?: Set<string>;
|
|
26
26
|
/** Logger. Uses noop if not specified. */
|
|
27
27
|
logger?: VibeLogger;
|
|
28
|
-
/** Lightweight skill index. Included in the agent system prompt. */
|
|
29
|
-
availableSkills?: string;
|
|
30
28
|
}
|
|
31
29
|
/** Orchestration execution result */
|
|
32
30
|
export interface OrchestrationResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIlE,sCAAsC;AACtC,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,CAAC,EAAE,iBAAiB,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIlE,sCAAsC;AACtC,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,CAAC,EAAE,iBAAiB,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAaD;;GAEG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAevG;AAID;;;GAGG;AACH,wBAAuB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAAC,SAAS,EAAE,mBAAmB,CAAC,CA4KrH","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { createModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport type { StepExecutor } from \"./pipeline.js\";\nimport { PipelineRunner } from \"./pipeline.js\";\nimport { createPipeline, resolveExecutionOrder, resolveFeatureWorkflowType } from \"./router.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { PlanData, VibeConfig, VibeEvent } from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Orchestration execution options */\nexport interface OrchestrationOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tplan: PlanData;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\tonAgentCreated?: (agent: Agent) => void;\n\tonAgentFinished?: () => void;\n\t/** Parent feature ID for enhancement workflows. Passed to createPipeline. */\n\tparentFeatureId?: string;\n\t/** Specifies already-completed features to skip on resume. */\n\tskipCompletedFeatures?: Set<string>;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n}\n\n/** Orchestration execution result */\nexport interface OrchestrationResult {\n\tcompleted: string[];\n\tfailed: string[];\n\tskipped: string[];\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction createEvent(type: VibeEvent[\"type\"], featureId: string, data?: Record<string, unknown>): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tdata,\n\t};\n}\n\n/**\n * Returns feature IDs that directly or indirectly depend on failedId in the dependency graph.\n */\nexport function findDependents(dependencyGraph: Record<string, string[]>, failedId: string): Set<string> {\n\tconst dependents = new Set<string>();\n\tconst queue = [failedId];\n\n\twhile (queue.length > 0) {\n\t\tconst current = queue.shift()!;\n\t\tfor (const [featureId, deps] of Object.entries(dependencyGraph)) {\n\t\t\tif (deps.includes(current) && !dependents.has(featureId)) {\n\t\t\t\tdependents.add(featureId);\n\t\t\t\tqueue.push(featureId);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dependents;\n}\n\n// ─── Orchestrator ────────────────────────────────────────────────────────────\n\n/**\n * Sequentially executes features from plan.json in dependency graph order.\n * Skips dependent features when a predecessor fails.\n */\nexport async function* runOrchestration(options: OrchestrationOptions): AsyncGenerator<VibeEvent, OrchestrationResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tplan,\n\t\trequestApproval,\n\t\tstepExecutor,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentCreated,\n\t\tonAgentFinished,\n\t\tparentFeatureId,\n\t\tskipCompletedFeatures,\n\t\tlogger,\n\t} = options;\n\n\tconst log = createModuleLogger(logger ?? noopLogger, \"orchestrator\");\n\n\tconst executionOrder = resolveExecutionOrder(plan.dependencyGraph);\n\tlog.info(`Execution order resolved: [${executionOrder.join(\", \")}]`, {\n\t\tfeatureCount: executionOrder.length,\n\t});\n\tconst completed = new Set<string>(skipCompletedFeatures ?? []);\n\tconst failed = new Set<string>();\n\tconst skipped = new Set<string>();\n\n\tyield createEvent(\"orchestration_start\", \"orchestrator\", {\n\t\tfeatureCount: executionOrder.length,\n\t\texecutionOrder,\n\t});\n\n\tfor (const featureId of executionOrder) {\n\t\t// Skip already-completed features (on resume)\n\t\tif (completed.has(featureId)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Features to skip due to dependency failure\n\t\tif (skipped.has(featureId)) {\n\t\t\tlog.warn(`Feature skipped due to dependency failure: ${featureId}`, { featureId });\n\t\t\tconst feature = plan.features.find((f) => f.featureId === featureId);\n\t\t\tyield createEvent(\"feature_skipped\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t\treason: \"dependency failed\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst feature = plan.features.find((f) => f.featureId === featureId);\n\t\tlog.info(`Feature starting: ${featureId}`, { featureId, title: feature?.title });\n\n\t\tyield createEvent(\"feature_start\", featureId, {\n\t\t\ttitle: feature?.title,\n\t\t\tpriority: feature?.priority,\n\t\t});\n\n\t\t// Ensure spec.md exists (must be pre-created by planner)\n\t\tawait store.ensureFeatureDir(featureId);\n\n\t\t// Create per-feature pipeline. Restore currentStep if pipeline.json exists on disk.\n\t\tconst pipeline = createPipeline(resolveFeatureWorkflowType(featureId, plan.workflowType), featureId, {\n\t\t\tmaxRetries: config.retry.maxTestRetries,\n\t\t\tparentFeatureId,\n\t\t});\n\n\t\tconst persisted = await store.loadPipelineState(featureId);\n\t\tif (persisted && persisted.currentStep > 0) {\n\t\t\tlog.info(`Restoring pipeline state: ${featureId} from step ${persisted.currentStep}`, {\n\t\t\t\tfeatureId,\n\t\t\t\tcurrentStep: persisted.currentStep,\n\t\t\t});\n\t\t\tpipeline.currentStep = persisted.currentStep;\n\t\t\tpipeline.retryCount = persisted.retryCount;\n\t\t}\n\n\t\t// Execute pipeline\n\t\tconst runner = new PipelineRunner({\n\t\t\tstore,\n\t\t\tconfig,\n\t\t\tprojectRoot,\n\t\t\trequestApproval,\n\t\t\tstepExecutor,\n\t\t\tgetApiKey,\n\t\t\tmodel,\n\t\t\tonAgentCreated,\n\t\t\tonAgentFinished,\n\t\t\tlogger,\n\t\t});\n\n\t\tlet featureFailed = false;\n\t\tlet featureAborted = false;\n\n\t\tfor await (const event of runner.run(pipeline)) {\n\t\t\tyield event;\n\n\t\t\tif (event.type === \"step_failed\") {\n\t\t\t\tfeatureFailed = true;\n\t\t\t}\n\t\t\tif (event.type === \"feature_aborted\") {\n\t\t\t\tfeatureAborted = true;\n\t\t\t}\n\t\t}\n\n\t\t// Abort: feature artifacts already deleted by PipelineRunner.\n\t\t// Stop orchestration immediately. Completed features are preserved.\n\t\tif (featureAborted || pipeline.status === \"aborted\") {\n\t\t\tlog.error(`Feature aborted: ${featureId}, stopping orchestration`, { featureId });\n\t\t\tyield createEvent(\"orchestration_complete\", \"orchestrator\", {\n\t\t\t\tcompleted: [...completed],\n\t\t\t\tfailed: [...failed],\n\t\t\t\tskipped: [...skipped],\n\t\t\t\tabortedFeature: featureId,\n\t\t\t\ttotal: executionOrder.length,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcompleted: [...completed],\n\t\t\t\tfailed: [...failed],\n\t\t\t\tskipped: [...skipped],\n\t\t\t};\n\t\t}\n\n\t\tif (featureFailed || pipeline.status === \"failed\") {\n\t\t\tlog.warn(`Feature failed: ${featureId}`, { featureId });\n\t\t\tfailed.add(featureId);\n\n\t\t\t// Mark dependent features as skipped\n\t\t\tconst dependents = findDependents(plan.dependencyGraph, featureId);\n\t\t\tfor (const dep of dependents) {\n\t\t\t\tskipped.add(dep);\n\t\t\t}\n\n\t\t\tyield createEvent(\"feature_skipped\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t\treason: \"failed\",\n\t\t\t});\n\t\t} else if (pipeline.status === \"blocked\") {\n\t\t\tfailed.add(featureId);\n\n\t\t\tconst dependents = findDependents(plan.dependencyGraph, featureId);\n\t\t\tfor (const dep of dependents) {\n\t\t\t\tskipped.add(dep);\n\t\t\t}\n\t\t} else {\n\t\t\tlog.info(`Feature completed: ${featureId}`, { featureId });\n\t\t\tcompleted.add(featureId);\n\n\t\t\tyield createEvent(\"feature_complete\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t});\n\t\t}\n\t}\n\n\tlog.info(`Orchestration complete: ${completed.size} completed, ${failed.size} failed, ${skipped.size} skipped`, {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t});\n\n\tyield createEvent(\"orchestration_complete\", \"orchestrator\", {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t\ttotal: executionOrder.length,\n\t});\n\n\treturn {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t};\n}\n"]}
|
package/dist/orchestrator.js
CHANGED
package/dist/orchestrator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { createModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport type { StepExecutor } from \"./pipeline.js\";\nimport { PipelineRunner } from \"./pipeline.js\";\nimport { createPipeline, resolveExecutionOrder, resolveFeatureWorkflowType } from \"./router.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { PlanData, VibeConfig, VibeEvent } from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Orchestration execution options */\nexport interface OrchestrationOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tplan: PlanData;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\tonAgentCreated?: (agent: Agent) => void;\n\tonAgentFinished?: () => void;\n\t/** Parent feature ID for enhancement workflows. Passed to createPipeline. */\n\tparentFeatureId?: string;\n\t/** Specifies already-completed features to skip on resume. */\n\tskipCompletedFeatures?: Set<string>;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n}\n\n/** Orchestration execution result */\nexport interface OrchestrationResult {\n\tcompleted: string[];\n\tfailed: string[];\n\tskipped: string[];\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction createEvent(type: VibeEvent[\"type\"], featureId: string, data?: Record<string, unknown>): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tdata,\n\t};\n}\n\n/**\n * Returns feature IDs that directly or indirectly depend on failedId in the dependency graph.\n */\nexport function findDependents(dependencyGraph: Record<string, string[]>, failedId: string): Set<string> {\n\tconst dependents = new Set<string>();\n\tconst queue = [failedId];\n\n\twhile (queue.length > 0) {\n\t\tconst current = queue.shift()!;\n\t\tfor (const [featureId, deps] of Object.entries(dependencyGraph)) {\n\t\t\tif (deps.includes(current) && !dependents.has(featureId)) {\n\t\t\t\tdependents.add(featureId);\n\t\t\t\tqueue.push(featureId);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dependents;\n}\n\n// ─── Orchestrator ────────────────────────────────────────────────────────────\n\n/**\n * Sequentially executes features from plan.json in dependency graph order.\n * Skips dependent features when a predecessor fails.\n */\nexport async function* runOrchestration(options: OrchestrationOptions): AsyncGenerator<VibeEvent, OrchestrationResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tplan,\n\t\trequestApproval,\n\t\tstepExecutor,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentCreated,\n\t\tonAgentFinished,\n\t\tparentFeatureId,\n\t\tskipCompletedFeatures,\n\t\tlogger,\n\t} = options;\n\n\tconst log = createModuleLogger(logger ?? noopLogger, \"orchestrator\");\n\n\tconst executionOrder = resolveExecutionOrder(plan.dependencyGraph);\n\tlog.info(`Execution order resolved: [${executionOrder.join(\", \")}]`, {\n\t\tfeatureCount: executionOrder.length,\n\t});\n\tconst completed = new Set<string>(skipCompletedFeatures ?? []);\n\tconst failed = new Set<string>();\n\tconst skipped = new Set<string>();\n\n\tyield createEvent(\"orchestration_start\", \"orchestrator\", {\n\t\tfeatureCount: executionOrder.length,\n\t\texecutionOrder,\n\t});\n\n\tfor (const featureId of executionOrder) {\n\t\t// Skip already-completed features (on resume)\n\t\tif (completed.has(featureId)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Features to skip due to dependency failure\n\t\tif (skipped.has(featureId)) {\n\t\t\tlog.warn(`Feature skipped due to dependency failure: ${featureId}`, { featureId });\n\t\t\tconst feature = plan.features.find((f) => f.featureId === featureId);\n\t\t\tyield createEvent(\"feature_skipped\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t\treason: \"dependency failed\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst feature = plan.features.find((f) => f.featureId === featureId);\n\t\tlog.info(`Feature starting: ${featureId}`, { featureId, title: feature?.title });\n\n\t\tyield createEvent(\"feature_start\", featureId, {\n\t\t\ttitle: feature?.title,\n\t\t\tpriority: feature?.priority,\n\t\t});\n\n\t\t// Ensure spec.md exists (must be pre-created by planner)\n\t\tawait store.ensureFeatureDir(featureId);\n\n\t\t// Create per-feature pipeline. Restore currentStep if pipeline.json exists on disk.\n\t\tconst pipeline = createPipeline(resolveFeatureWorkflowType(featureId, plan.workflowType), featureId, {\n\t\t\tmaxRetries: config.retry.maxTestRetries,\n\t\t\tparentFeatureId,\n\t\t});\n\n\t\tconst persisted = await store.loadPipelineState(featureId);\n\t\tif (persisted && persisted.currentStep > 0) {\n\t\t\tlog.info(`Restoring pipeline state: ${featureId} from step ${persisted.currentStep}`, {\n\t\t\t\tfeatureId,\n\t\t\t\tcurrentStep: persisted.currentStep,\n\t\t\t});\n\t\t\tpipeline.currentStep = persisted.currentStep;\n\t\t\tpipeline.retryCount = persisted.retryCount;\n\t\t}\n\n\t\t// Execute pipeline\n\t\tconst runner = new PipelineRunner({\n\t\t\tstore,\n\t\t\tconfig,\n\t\t\tprojectRoot,\n\t\t\trequestApproval,\n\t\t\tstepExecutor,\n\t\t\tgetApiKey,\n\t\t\tmodel,\n\t\t\tonAgentCreated,\n\t\t\tonAgentFinished,\n\t\t\tlogger,\n\t\t\tavailableSkills: options.availableSkills,\n\t\t});\n\n\t\tlet featureFailed = false;\n\t\tlet featureAborted = false;\n\n\t\tfor await (const event of runner.run(pipeline)) {\n\t\t\tyield event;\n\n\t\t\tif (event.type === \"step_failed\") {\n\t\t\t\tfeatureFailed = true;\n\t\t\t}\n\t\t\tif (event.type === \"feature_aborted\") {\n\t\t\t\tfeatureAborted = true;\n\t\t\t}\n\t\t}\n\n\t\t// Abort: feature artifacts already deleted by PipelineRunner.\n\t\t// Stop orchestration immediately. Completed features are preserved.\n\t\tif (featureAborted || pipeline.status === \"aborted\") {\n\t\t\tlog.error(`Feature aborted: ${featureId}, stopping orchestration`, { featureId });\n\t\t\tyield createEvent(\"orchestration_complete\", \"orchestrator\", {\n\t\t\t\tcompleted: [...completed],\n\t\t\t\tfailed: [...failed],\n\t\t\t\tskipped: [...skipped],\n\t\t\t\tabortedFeature: featureId,\n\t\t\t\ttotal: executionOrder.length,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcompleted: [...completed],\n\t\t\t\tfailed: [...failed],\n\t\t\t\tskipped: [...skipped],\n\t\t\t};\n\t\t}\n\n\t\tif (featureFailed || pipeline.status === \"failed\") {\n\t\t\tlog.warn(`Feature failed: ${featureId}`, { featureId });\n\t\t\tfailed.add(featureId);\n\n\t\t\t// Mark dependent features as skipped\n\t\t\tconst dependents = findDependents(plan.dependencyGraph, featureId);\n\t\t\tfor (const dep of dependents) {\n\t\t\t\tskipped.add(dep);\n\t\t\t}\n\n\t\t\tyield createEvent(\"feature_skipped\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t\treason: \"failed\",\n\t\t\t});\n\t\t} else if (pipeline.status === \"blocked\") {\n\t\t\tfailed.add(featureId);\n\n\t\t\tconst dependents = findDependents(plan.dependencyGraph, featureId);\n\t\t\tfor (const dep of dependents) {\n\t\t\t\tskipped.add(dep);\n\t\t\t}\n\t\t} else {\n\t\t\tlog.info(`Feature completed: ${featureId}`, { featureId });\n\t\t\tcompleted.add(featureId);\n\n\t\t\tyield createEvent(\"feature_complete\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t});\n\t\t}\n\t}\n\n\tlog.info(`Orchestration complete: ${completed.size} completed, ${failed.size} failed, ${skipped.size} skipped`, {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t});\n\n\tyield createEvent(\"orchestration_complete\", \"orchestrator\", {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t\ttotal: executionOrder.length,\n\t});\n\n\treturn {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { createModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport type { StepExecutor } from \"./pipeline.js\";\nimport { PipelineRunner } from \"./pipeline.js\";\nimport { createPipeline, resolveExecutionOrder, resolveFeatureWorkflowType } from \"./router.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { PlanData, VibeConfig, VibeEvent } from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Orchestration execution options */\nexport interface OrchestrationOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tplan: PlanData;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\tonAgentCreated?: (agent: Agent) => void;\n\tonAgentFinished?: () => void;\n\t/** Parent feature ID for enhancement workflows. Passed to createPipeline. */\n\tparentFeatureId?: string;\n\t/** Specifies already-completed features to skip on resume. */\n\tskipCompletedFeatures?: Set<string>;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n}\n\n/** Orchestration execution result */\nexport interface OrchestrationResult {\n\tcompleted: string[];\n\tfailed: string[];\n\tskipped: string[];\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction createEvent(type: VibeEvent[\"type\"], featureId: string, data?: Record<string, unknown>): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tdata,\n\t};\n}\n\n/**\n * Returns feature IDs that directly or indirectly depend on failedId in the dependency graph.\n */\nexport function findDependents(dependencyGraph: Record<string, string[]>, failedId: string): Set<string> {\n\tconst dependents = new Set<string>();\n\tconst queue = [failedId];\n\n\twhile (queue.length > 0) {\n\t\tconst current = queue.shift()!;\n\t\tfor (const [featureId, deps] of Object.entries(dependencyGraph)) {\n\t\t\tif (deps.includes(current) && !dependents.has(featureId)) {\n\t\t\t\tdependents.add(featureId);\n\t\t\t\tqueue.push(featureId);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dependents;\n}\n\n// ─── Orchestrator ────────────────────────────────────────────────────────────\n\n/**\n * Sequentially executes features from plan.json in dependency graph order.\n * Skips dependent features when a predecessor fails.\n */\nexport async function* runOrchestration(options: OrchestrationOptions): AsyncGenerator<VibeEvent, OrchestrationResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tplan,\n\t\trequestApproval,\n\t\tstepExecutor,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentCreated,\n\t\tonAgentFinished,\n\t\tparentFeatureId,\n\t\tskipCompletedFeatures,\n\t\tlogger,\n\t} = options;\n\n\tconst log = createModuleLogger(logger ?? noopLogger, \"orchestrator\");\n\n\tconst executionOrder = resolveExecutionOrder(plan.dependencyGraph);\n\tlog.info(`Execution order resolved: [${executionOrder.join(\", \")}]`, {\n\t\tfeatureCount: executionOrder.length,\n\t});\n\tconst completed = new Set<string>(skipCompletedFeatures ?? []);\n\tconst failed = new Set<string>();\n\tconst skipped = new Set<string>();\n\n\tyield createEvent(\"orchestration_start\", \"orchestrator\", {\n\t\tfeatureCount: executionOrder.length,\n\t\texecutionOrder,\n\t});\n\n\tfor (const featureId of executionOrder) {\n\t\t// Skip already-completed features (on resume)\n\t\tif (completed.has(featureId)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Features to skip due to dependency failure\n\t\tif (skipped.has(featureId)) {\n\t\t\tlog.warn(`Feature skipped due to dependency failure: ${featureId}`, { featureId });\n\t\t\tconst feature = plan.features.find((f) => f.featureId === featureId);\n\t\t\tyield createEvent(\"feature_skipped\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t\treason: \"dependency failed\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst feature = plan.features.find((f) => f.featureId === featureId);\n\t\tlog.info(`Feature starting: ${featureId}`, { featureId, title: feature?.title });\n\n\t\tyield createEvent(\"feature_start\", featureId, {\n\t\t\ttitle: feature?.title,\n\t\t\tpriority: feature?.priority,\n\t\t});\n\n\t\t// Ensure spec.md exists (must be pre-created by planner)\n\t\tawait store.ensureFeatureDir(featureId);\n\n\t\t// Create per-feature pipeline. Restore currentStep if pipeline.json exists on disk.\n\t\tconst pipeline = createPipeline(resolveFeatureWorkflowType(featureId, plan.workflowType), featureId, {\n\t\t\tmaxRetries: config.retry.maxTestRetries,\n\t\t\tparentFeatureId,\n\t\t});\n\n\t\tconst persisted = await store.loadPipelineState(featureId);\n\t\tif (persisted && persisted.currentStep > 0) {\n\t\t\tlog.info(`Restoring pipeline state: ${featureId} from step ${persisted.currentStep}`, {\n\t\t\t\tfeatureId,\n\t\t\t\tcurrentStep: persisted.currentStep,\n\t\t\t});\n\t\t\tpipeline.currentStep = persisted.currentStep;\n\t\t\tpipeline.retryCount = persisted.retryCount;\n\t\t}\n\n\t\t// Execute pipeline\n\t\tconst runner = new PipelineRunner({\n\t\t\tstore,\n\t\t\tconfig,\n\t\t\tprojectRoot,\n\t\t\trequestApproval,\n\t\t\tstepExecutor,\n\t\t\tgetApiKey,\n\t\t\tmodel,\n\t\t\tonAgentCreated,\n\t\t\tonAgentFinished,\n\t\t\tlogger,\n\t\t});\n\n\t\tlet featureFailed = false;\n\t\tlet featureAborted = false;\n\n\t\tfor await (const event of runner.run(pipeline)) {\n\t\t\tyield event;\n\n\t\t\tif (event.type === \"step_failed\") {\n\t\t\t\tfeatureFailed = true;\n\t\t\t}\n\t\t\tif (event.type === \"feature_aborted\") {\n\t\t\t\tfeatureAborted = true;\n\t\t\t}\n\t\t}\n\n\t\t// Abort: feature artifacts already deleted by PipelineRunner.\n\t\t// Stop orchestration immediately. Completed features are preserved.\n\t\tif (featureAborted || pipeline.status === \"aborted\") {\n\t\t\tlog.error(`Feature aborted: ${featureId}, stopping orchestration`, { featureId });\n\t\t\tyield createEvent(\"orchestration_complete\", \"orchestrator\", {\n\t\t\t\tcompleted: [...completed],\n\t\t\t\tfailed: [...failed],\n\t\t\t\tskipped: [...skipped],\n\t\t\t\tabortedFeature: featureId,\n\t\t\t\ttotal: executionOrder.length,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcompleted: [...completed],\n\t\t\t\tfailed: [...failed],\n\t\t\t\tskipped: [...skipped],\n\t\t\t};\n\t\t}\n\n\t\tif (featureFailed || pipeline.status === \"failed\") {\n\t\t\tlog.warn(`Feature failed: ${featureId}`, { featureId });\n\t\t\tfailed.add(featureId);\n\n\t\t\t// Mark dependent features as skipped\n\t\t\tconst dependents = findDependents(plan.dependencyGraph, featureId);\n\t\t\tfor (const dep of dependents) {\n\t\t\t\tskipped.add(dep);\n\t\t\t}\n\n\t\t\tyield createEvent(\"feature_skipped\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t\treason: \"failed\",\n\t\t\t});\n\t\t} else if (pipeline.status === \"blocked\") {\n\t\t\tfailed.add(featureId);\n\n\t\t\tconst dependents = findDependents(plan.dependencyGraph, featureId);\n\t\t\tfor (const dep of dependents) {\n\t\t\t\tskipped.add(dep);\n\t\t\t}\n\t\t} else {\n\t\t\tlog.info(`Feature completed: ${featureId}`, { featureId });\n\t\t\tcompleted.add(featureId);\n\n\t\t\tyield createEvent(\"feature_complete\", featureId, {\n\t\t\t\ttitle: feature?.title,\n\t\t\t});\n\t\t}\n\t}\n\n\tlog.info(`Orchestration complete: ${completed.size} completed, ${failed.size} failed, ${skipped.size} skipped`, {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t});\n\n\tyield createEvent(\"orchestration_complete\", \"orchestrator\", {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t\ttotal: executionOrder.length,\n\t});\n\n\treturn {\n\t\tcompleted: [...completed],\n\t\tfailed: [...failed],\n\t\tskipped: [...skipped],\n\t};\n}\n"]}
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -29,8 +29,6 @@ export interface StepContext {
|
|
|
29
29
|
onAgentFinished?: () => void;
|
|
30
30
|
/** Logger. Uses noop if not specified. */
|
|
31
31
|
logger?: VibeLogger;
|
|
32
|
-
/** Lightweight skill index. Included in the agent system prompt. */
|
|
33
|
-
availableSkills?: string;
|
|
34
32
|
/** Mutable. Set by StepExecutor after agent completion. Read by PipelineRunner for event data. */
|
|
35
33
|
lastStepUsage?: StepUsage;
|
|
36
34
|
/** Mutable. Set by StepExecutor after agent completion. Last assistant response text. */
|
|
@@ -54,8 +52,6 @@ export interface PipelineRunnerOptions {
|
|
|
54
52
|
onAgentFinished?: () => void;
|
|
55
53
|
/** Logger. Uses noop if not specified. */
|
|
56
54
|
logger?: VibeLogger;
|
|
57
|
-
/** Lightweight skill index. Included in the agent system prompt. */
|
|
58
|
-
availableSkills?: string;
|
|
59
55
|
/** Custom retry delay function for step execution retries. Defaults to exponential backoff. */
|
|
60
56
|
retryDelayFn?: RetryDelayFn;
|
|
61
57
|
}
|
|
@@ -85,7 +81,6 @@ export declare class PipelineRunner {
|
|
|
85
81
|
private readonly onAgentFinished?;
|
|
86
82
|
private readonly log;
|
|
87
83
|
private readonly logger?;
|
|
88
|
-
private readonly availableSkills?;
|
|
89
84
|
private readonly retryDelayFn;
|
|
90
85
|
private paused;
|
|
91
86
|
private aborted;
|
package/dist/pipeline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAqD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EACX,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,MAAM,YAAY,CAAC;AAIpB,yDAAyD;AACzD,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,mGAAmG;IACnG,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,oGAAoG;IACpG,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kGAAkG;IAClG,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,yFAAyF;IACzF,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,4EAA4E;AAC5E,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1G,iCAAiC;AACjC,MAAM,WAAW,qBAAqB;IACrC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,iBAAiB,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,qGAAqG;IACrG,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+FAA+F;IAC/F,YAAY,CAAC,EAAE,YAAY,CAAC;CAC5B;AAID,gEAAgE;AAChE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,CA+B7F;AAWD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAElE;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED,sCAAsC;AACtC,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;AAqBvD,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,CAWxE;AAID;;GAEG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAoB;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAyB;IACzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IAExB,YAAY,OAAO,EAAE,qBAAqB,EAezC;IAED;;OAEG;IACI,GAAG,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,CAAC,SAAS,CAAC,CA+M/D;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,CAAC,SAAS,CAAC,CAElE;IAED,+CAA+C;IAC/C,KAAK,IAAI,IAAI,CAEZ;IAED,0BAA0B;IAC1B,KAAK,IAAI,IAAI,CAEZ;YAGa,eAAe;CAY7B","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { GateChecker } from \"./gate.js\";\nimport { createModuleLogger, type ModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport { defaultStepExecutor } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type {\n\tAgentRole,\n\tFeaturePipeline,\n\tFeatureStatusValue,\n\tPersistedPipeline,\n\tPipelineStep,\n\tVibeConfig,\n\tVibeEvent,\n} from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Aggregated token usage for a single pipeline step. */\nexport interface StepUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\t/** Total cost in USD. */\n\tcost: number;\n}\n\n/** Context required for step execution */\nexport interface StepContext {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows external code to acquire an Agent reference. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes (success/error). Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n\t/** Mutable. Set by StepExecutor after agent completion. Read by PipelineRunner for event data. */\n\tlastStepUsage?: StepUsage;\n\t/** Mutable. Set by StepExecutor after agent completion. Last assistant response text. */\n\tlastStepResponseText?: string;\n}\n\n/** Step execution function. Called by the pipeline engine for each step. */\nexport type StepExecutor = (step: PipelineStep, featureId: string, context: StepContext) => Promise<void>;\n\n/** Pipeline execution options */\nexport interface PipelineRunnerOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows acquiring an Agent reference during execution. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes. Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n\t/** Custom retry delay function for step execution retries. Defaults to exponential backoff. */\n\tretryDelayFn?: RetryDelayFn;\n}\n\n// ─── Status Mapping ──────────────────────────────────────────────────────────\n\n/** Maps agent role (+ optional action) to FeatureStatusValue */\nexport function agentRoleToFeatureStatus(role: AgentRole, action?: string): FeatureStatusValue {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"planned\";\n\t\tcase \"architect\":\n\t\t\treturn \"designing\";\n\t\tcase \"developer\":\n\t\t\treturn \"implementing\";\n\t\tcase \"tester\":\n\t\t\treturn \"testing\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"reviewing\";\n\t\tcase \"cicd\":\n\t\t\treturn action === \"merge\" ? \"merging\" : \"branching\";\n\t\tcase \"analyzer\":\n\t\t\treturn \"designing\";\n\t\tcase \"diagnostician\":\n\t\t\treturn \"designing\";\n\t\tcase \"discovery\":\n\t\t\treturn \"planned\";\n\t\tcase \"projectAnalyzer\":\n\t\t\treturn \"planned\";\n\t\tcase \"documenter\":\n\t\t\treturn \"done\";\n\t\tcase \"standardsEnricher\":\n\t\t\treturn \"planned\";\n\t\tcase \"systemArchitect\":\n\t\t\treturn \"designing\";\n\t\tcase \"recover\":\n\t\t\treturn \"planned\";\n\t}\n}\n\n// ─── Retry Helpers ───────────────────────────────────────────────────────────\n\n/**\n * Pattern matching transient errors that should be retried.\n * Covers: undici fetch \"terminated\", HTTP 5xx, rate limits, connection errors.\n */\nconst RETRYABLE_ERROR_PATTERN =\n\t/terminated|overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|retry delay|ECONNRESET|ETIMEDOUT|EPIPE|EAI_AGAIN/i;\n\n/** Returns true if the error message indicates a transient failure worth retrying. */\nexport function isRetryableStepError(errorMessage: string): boolean {\n\treturn RETRYABLE_ERROR_PATTERN.test(errorMessage);\n}\n\n/** Default exponential backoff delay in ms: base * 2^attempt, capped at 60s. */\nexport function defaultRetryDelay(attempt: number): number {\n\tconst base = 5000;\n\tconst maxDelay = 60000;\n\treturn Math.min(base * 2 ** attempt, maxDelay);\n}\n\n/** Retry delay function signature. */\nexport type RetryDelayFn = (attempt: number) => number;\n\n// ─── Helper ──────────────────────────────────────────────────────────────────\n\nfunction createEvent(\n\ttype: VibeEvent[\"type\"],\n\tfeatureId: string,\n\tstep?: PipelineStep,\n\tdata?: Record<string, unknown>,\n): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tstep,\n\t\tdata,\n\t};\n}\n\n// ─── Persistence Helpers ─────────────────────────────────────────────────────\n\n/** Creates a PersistedPipeline from a FeaturePipeline. */\nexport function toPersisted(pipeline: FeaturePipeline): PersistedPipeline {\n\treturn {\n\t\tfeatureId: pipeline.featureId,\n\t\tworkflowType: pipeline.workflowType,\n\t\tcurrentStep: pipeline.currentStep,\n\t\tstatus: pipeline.status,\n\t\tretryCount: pipeline.retryCount,\n\t\tmaxRetries: pipeline.maxRetries,\n\t\tparentFeatureId: pipeline.parentFeatureId,\n\t\tissueRef: pipeline.issueRef,\n\t};\n}\n\n// ─── PipelineRunner ──────────────────────────────────────────────────────────\n\n/**\n * Pipeline runner. Sequentially executes FeaturePipeline steps and emits events.\n */\nexport class PipelineRunner {\n\tprivate readonly store: VibeStore;\n\tprivate readonly config: VibeConfig;\n\tprivate readonly projectRoot: string;\n\tprivate readonly requestApproval?: ApprovalRequestFn;\n\tprivate readonly stepExecutor: StepExecutor;\n\tprivate readonly gateChecker: GateChecker;\n\tprivate readonly getApiKey?: GetApiKeyFn;\n\tprivate readonly model?: Model<any>;\n\tprivate readonly onAgentCreated?: (agent: Agent) => void;\n\tprivate readonly onAgentFinished?: () => void;\n\tprivate readonly log: ModuleLogger;\n\tprivate readonly logger?: VibeLogger;\n\tprivate readonly availableSkills?: string;\n\tprivate readonly retryDelayFn: RetryDelayFn;\n\n\tprivate paused = false;\n\tprivate aborted = false;\n\n\tconstructor(options: PipelineRunnerOptions) {\n\t\tthis.store = options.store;\n\t\tthis.config = options.config;\n\t\tthis.projectRoot = options.projectRoot;\n\t\tthis.requestApproval = options.requestApproval;\n\t\tthis.stepExecutor = options.stepExecutor ?? defaultStepExecutor;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.model = options.model;\n\t\tthis.onAgentCreated = options.onAgentCreated;\n\t\tthis.onAgentFinished = options.onAgentFinished;\n\t\tthis.logger = options.logger;\n\t\tthis.availableSkills = options.availableSkills;\n\t\tthis.retryDelayFn = options.retryDelayFn ?? defaultRetryDelay;\n\t\tthis.log = createModuleLogger(options.logger ?? noopLogger, \"pipeline\");\n\t\tthis.gateChecker = new GateChecker(this.store, this.config, this.model, options.logger);\n\t}\n\n\t/**\n\t * Runs the pipeline and yields events.\n\t */\n\tasync *run(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tthis.paused = false;\n\t\tthis.aborted = false;\n\t\tpipeline.status = \"running\";\n\t\tthis.log.info(`Pipeline started: ${pipeline.featureId}`, {\n\t\t\tfeatureId: pipeline.featureId,\n\t\t\tworkflowType: pipeline.workflowType,\n\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\tcurrentStep: pipeline.currentStep,\n\t\t});\n\n\t\tconst context: StepContext = {\n\t\t\tstore: this.store,\n\t\t\tconfig: this.config,\n\t\t\tprojectRoot: this.projectRoot,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tmodel: this.model,\n\t\t\tonAgentCreated: this.onAgentCreated,\n\t\t\tonAgentFinished: this.onAgentFinished,\n\t\t\tlogger: this.logger,\n\t\t\tavailableSkills: this.availableSkills,\n\t\t};\n\n\t\tfor (let i = pipeline.currentStep; i < pipeline.steps.length; i++) {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.log.warn(\"Pipeline aborted\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, pipeline.steps[i], {\n\t\t\t\t\treason: \"aborted\",\n\t\t\t\t\tstepIndex: i,\n\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.paused) {\n\t\t\t\tthis.log.info(\"Pipeline paused\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, pipeline.steps[i], { reason: \"paused\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst step = pipeline.steps[i];\n\n\t\t\t// Handle skip\n\t\t\tif (step.skip) {\n\t\t\t\tpipeline.currentStep = i + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// step_start event\n\t\t\tyield createEvent(\"step_start\", pipeline.featureId, step, {\n\t\t\t\tagent: step.agent,\n\t\t\t\tinputs: step.inputs,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t});\n\n\t\t\t// Update status\n\t\t\tconst featureStatus = agentRoleToFeatureStatus(step.agent, step.action);\n\t\t\ttry {\n\t\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, featureStatus);\n\t\t\t} catch {\n\t\t\t\t// Ignore status transition failure (may already be in this state)\n\t\t\t}\n\n\t\t\t// Execute step (with retry for transient errors)\n\t\t\tthis.log.info(`Step executing: ${step.agent}:${step.action}`, { featureId: pipeline.featureId, step: i });\n\t\t\tconst maxStepRetries = this.config.retry.maxStepRetries ?? 2;\n\t\t\tlet stepAttempt = 0;\n\t\t\tconst startTime = Date.now();\n\n\t\t\twhile (stepAttempt <= maxStepRetries) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.stepExecutor(step, pipeline.featureId, context);\n\t\t\t\t\tbreak;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tconst errorStack = error instanceof Error ? error.stack : undefined;\n\t\t\t\t\tconst errorCause = error instanceof Error ? error.cause : undefined;\n\n\t\t\t\t\tif (stepAttempt < maxStepRetries && isRetryableStepError(errorMsg)) {\n\t\t\t\t\t\tstepAttempt++;\n\t\t\t\t\t\tconst delay = this.retryDelayFn(stepAttempt - 1);\n\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t`Step error (retryable), retry ${stepAttempt}/${maxStepRetries} after ${delay}ms: ${step.agent}:${step.action}: ${errorMsg}`,\n\t\t\t\t\t\t\t{ featureId: pipeline.featureId, step: i, attempt: stepAttempt, cause: errorCause },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tyield createEvent(\"step_retry\", pipeline.featureId, step, {\n\t\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\t\tattempt: stepAttempt,\n\t\t\t\t\t\t\tmaxRetries: maxStepRetries,\n\t\t\t\t\t\t\tdelayMs: delay,\n\t\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.error(`Step failed: ${step.agent}:${step.action}: ${errorMsg}`, {\n\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\tstep: i,\n\t\t\t\t\t\tstack: errorStack,\n\t\t\t\t\t\tcause: errorCause,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, step, {\n\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\tthis.log.info(`Step completed: ${step.agent}:${step.action} (${elapsed}ms)`, {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstep: i,\n\t\t\t});\n\n\t\t\t// Gate validation\n\t\t\tif (step.gate) {\n\t\t\t\tconst gateResult = await this.gateChecker.evaluate(step, pipeline.featureId, this.requestApproval);\n\n\t\t\t\tif (!gateResult.passed) {\n\t\t\t\t\tif (gateResult.action === \"abort\") {\n\t\t\t\t\t\tthis.log.warn(`Gate abort: ${step.gate.type}`, { featureId: pipeline.featureId });\n\t\t\t\t\t\tpipeline.status = \"aborted\";\n\t\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\t\t// Delete feature artifacts\n\t\t\t\t\t\tawait this.store.clearFeatureDir(pipeline.featureId);\n\t\t\t\t\t\tyield createEvent(\"feature_aborted\", pipeline.featureId, step, {\n\t\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t`Gate rejected: ${step.gate.type}, retry ${pipeline.retryCount + 1}/${pipeline.maxRetries}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\t\tpipeline.retryCount++;\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"gate_rejected\", pipeline.featureId, step, {\n\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (pipeline.retryCount >= pipeline.maxRetries) {\n\t\t\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, step, {\n\t\t\t\t\t\t\treason: \"max retries exceeded\",\n\t\t\t\t\t\t\tretryCount: pipeline.retryCount,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// On gate failure, do not increment currentStep so this step is re-executed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Distinguish Skip vs Approve\n\t\t\t\tif (gateResult.action === \"skip\") {\n\t\t\t\t\tyield createEvent(\"gate_skipped\", pipeline.featureId, step);\n\t\t\t\t} else {\n\t\t\t\t\tyield createEvent(\"gate_approved\", pipeline.featureId, step);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// step_complete event\n\t\t\tyield createEvent(\"step_complete\", pipeline.featureId, step, {\n\t\t\t\toutputs: step.outputs,\n\t\t\t\telapsed,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\tusage: context.lastStepUsage,\n\t\t\t\tresponseText: context.lastStepResponseText,\n\t\t\t});\n\t\t\tcontext.lastStepUsage = undefined;\n\t\t\tcontext.lastStepResponseText = undefined;\n\n\t\t\tpipeline.currentStep = i + 1;\n\n\t\t\t// Persist pipeline state on step completion\n\t\t\tawait this.persistPipeline(pipeline);\n\t\t}\n\n\t\t// All steps completed\n\t\tthis.log.info(`Pipeline completed: ${pipeline.featureId}`, { featureId: pipeline.featureId });\n\t\tpipeline.status = \"done\";\n\t\tawait this.persistPipeline(pipeline);\n\t\ttry {\n\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, \"done\");\n\t\t} catch {\n\t\t\t// Ignore status transition failure\n\t\t}\n\t\tyield createEvent(\"pipeline_complete\", pipeline.featureId);\n\t}\n\n\t/**\n\t * Resumes the pipeline. Continues execution from currentStep.\n\t */\n\tasync *resume(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tyield* this.run(pipeline);\n\t}\n\n\t/** Pauses after the current step completes. */\n\tpause(): void {\n\t\tthis.paused = true;\n\t}\n\n\t/** Aborts immediately. */\n\tabort(): void {\n\t\tthis.aborted = true;\n\t}\n\n\t/** Persists the pipeline state to disk. */\n\tprivate async persistPipeline(pipeline: FeaturePipeline): Promise<void> {\n\t\ttry {\n\t\t\tawait this.store.savePipelineState(pipeline.featureId, toPersisted(pipeline));\n\t\t\tthis.log.debug(\"Pipeline state persisted\", {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstatus: pipeline.status,\n\t\t\t\tcurrentStep: pipeline.currentStep,\n\t\t\t});\n\t\t} catch {\n\t\t\tthis.log.warn(\"Pipeline state persistence failed\", { featureId: pipeline.featureId });\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { GateChecker } from \"./gate.js\";\nimport { createModuleLogger, type ModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport { defaultStepExecutor } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type {\n\tAgentRole,\n\tFeaturePipeline,\n\tFeatureStatusValue,\n\tPersistedPipeline,\n\tPipelineStep,\n\tVibeConfig,\n\tVibeEvent,\n} from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Aggregated token usage for a single pipeline step. */\nexport interface StepUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\t/** Total cost in USD. */\n\tcost: number;\n}\n\n/** Context required for step execution */\nexport interface StepContext {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows external code to acquire an Agent reference. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes (success/error). Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Mutable. Set by StepExecutor after agent completion. Read by PipelineRunner for event data. */\n\tlastStepUsage?: StepUsage;\n\t/** Mutable. Set by StepExecutor after agent completion. Last assistant response text. */\n\tlastStepResponseText?: string;\n}\n\n/** Step execution function. Called by the pipeline engine for each step. */\nexport type StepExecutor = (step: PipelineStep, featureId: string, context: StepContext) => Promise<void>;\n\n/** Pipeline execution options */\nexport interface PipelineRunnerOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows acquiring an Agent reference during execution. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes. Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Custom retry delay function for step execution retries. Defaults to exponential backoff. */\n\tretryDelayFn?: RetryDelayFn;\n}\n\n// ─── Status Mapping ──────────────────────────────────────────────────────────\n\n/** Maps agent role (+ optional action) to FeatureStatusValue */\nexport function agentRoleToFeatureStatus(role: AgentRole, action?: string): FeatureStatusValue {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"planned\";\n\t\tcase \"architect\":\n\t\t\treturn \"designing\";\n\t\tcase \"developer\":\n\t\t\treturn \"implementing\";\n\t\tcase \"tester\":\n\t\t\treturn \"testing\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"reviewing\";\n\t\tcase \"cicd\":\n\t\t\treturn action === \"merge\" ? \"merging\" : \"branching\";\n\t\tcase \"analyzer\":\n\t\t\treturn \"designing\";\n\t\tcase \"diagnostician\":\n\t\t\treturn \"designing\";\n\t\tcase \"discovery\":\n\t\t\treturn \"planned\";\n\t\tcase \"projectAnalyzer\":\n\t\t\treturn \"planned\";\n\t\tcase \"documenter\":\n\t\t\treturn \"done\";\n\t\tcase \"standardsEnricher\":\n\t\t\treturn \"planned\";\n\t\tcase \"systemArchitect\":\n\t\t\treturn \"designing\";\n\t\tcase \"recover\":\n\t\t\treturn \"planned\";\n\t}\n}\n\n// ─── Retry Helpers ───────────────────────────────────────────────────────────\n\n/**\n * Pattern matching transient errors that should be retried.\n * Covers: undici fetch \"terminated\", HTTP 5xx, rate limits, connection errors.\n */\nconst RETRYABLE_ERROR_PATTERN =\n\t/terminated|overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|retry delay|ECONNRESET|ETIMEDOUT|EPIPE|EAI_AGAIN/i;\n\n/** Returns true if the error message indicates a transient failure worth retrying. */\nexport function isRetryableStepError(errorMessage: string): boolean {\n\treturn RETRYABLE_ERROR_PATTERN.test(errorMessage);\n}\n\n/** Default exponential backoff delay in ms: base * 2^attempt, capped at 60s. */\nexport function defaultRetryDelay(attempt: number): number {\n\tconst base = 5000;\n\tconst maxDelay = 60000;\n\treturn Math.min(base * 2 ** attempt, maxDelay);\n}\n\n/** Retry delay function signature. */\nexport type RetryDelayFn = (attempt: number) => number;\n\n// ─── Helper ──────────────────────────────────────────────────────────────────\n\nfunction createEvent(\n\ttype: VibeEvent[\"type\"],\n\tfeatureId: string,\n\tstep?: PipelineStep,\n\tdata?: Record<string, unknown>,\n): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tstep,\n\t\tdata,\n\t};\n}\n\n// ─── Persistence Helpers ─────────────────────────────────────────────────────\n\n/** Creates a PersistedPipeline from a FeaturePipeline. */\nexport function toPersisted(pipeline: FeaturePipeline): PersistedPipeline {\n\treturn {\n\t\tfeatureId: pipeline.featureId,\n\t\tworkflowType: pipeline.workflowType,\n\t\tcurrentStep: pipeline.currentStep,\n\t\tstatus: pipeline.status,\n\t\tretryCount: pipeline.retryCount,\n\t\tmaxRetries: pipeline.maxRetries,\n\t\tparentFeatureId: pipeline.parentFeatureId,\n\t\tissueRef: pipeline.issueRef,\n\t};\n}\n\n// ─── PipelineRunner ──────────────────────────────────────────────────────────\n\n/**\n * Pipeline runner. Sequentially executes FeaturePipeline steps and emits events.\n */\nexport class PipelineRunner {\n\tprivate readonly store: VibeStore;\n\tprivate readonly config: VibeConfig;\n\tprivate readonly projectRoot: string;\n\tprivate readonly requestApproval?: ApprovalRequestFn;\n\tprivate readonly stepExecutor: StepExecutor;\n\tprivate readonly gateChecker: GateChecker;\n\tprivate readonly getApiKey?: GetApiKeyFn;\n\tprivate readonly model?: Model<any>;\n\tprivate readonly onAgentCreated?: (agent: Agent) => void;\n\tprivate readonly onAgentFinished?: () => void;\n\tprivate readonly log: ModuleLogger;\n\tprivate readonly logger?: VibeLogger;\n\tprivate readonly retryDelayFn: RetryDelayFn;\n\n\tprivate paused = false;\n\tprivate aborted = false;\n\n\tconstructor(options: PipelineRunnerOptions) {\n\t\tthis.store = options.store;\n\t\tthis.config = options.config;\n\t\tthis.projectRoot = options.projectRoot;\n\t\tthis.requestApproval = options.requestApproval;\n\t\tthis.stepExecutor = options.stepExecutor ?? defaultStepExecutor;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.model = options.model;\n\t\tthis.onAgentCreated = options.onAgentCreated;\n\t\tthis.onAgentFinished = options.onAgentFinished;\n\t\tthis.logger = options.logger;\n\t\tthis.retryDelayFn = options.retryDelayFn ?? defaultRetryDelay;\n\t\tthis.log = createModuleLogger(options.logger ?? noopLogger, \"pipeline\");\n\t\tthis.gateChecker = new GateChecker(this.store, this.config, this.model, options.logger);\n\t}\n\n\t/**\n\t * Runs the pipeline and yields events.\n\t */\n\tasync *run(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tthis.paused = false;\n\t\tthis.aborted = false;\n\t\tpipeline.status = \"running\";\n\t\tthis.log.info(`Pipeline started: ${pipeline.featureId}`, {\n\t\t\tfeatureId: pipeline.featureId,\n\t\t\tworkflowType: pipeline.workflowType,\n\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\tcurrentStep: pipeline.currentStep,\n\t\t});\n\n\t\tconst context: StepContext = {\n\t\t\tstore: this.store,\n\t\t\tconfig: this.config,\n\t\t\tprojectRoot: this.projectRoot,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tmodel: this.model,\n\t\t\tonAgentCreated: this.onAgentCreated,\n\t\t\tonAgentFinished: this.onAgentFinished,\n\t\t\tlogger: this.logger,\n\t\t};\n\n\t\tfor (let i = pipeline.currentStep; i < pipeline.steps.length; i++) {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.log.warn(\"Pipeline aborted\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, pipeline.steps[i], {\n\t\t\t\t\treason: \"aborted\",\n\t\t\t\t\tstepIndex: i,\n\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.paused) {\n\t\t\t\tthis.log.info(\"Pipeline paused\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, pipeline.steps[i], { reason: \"paused\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst step = pipeline.steps[i];\n\n\t\t\t// Handle skip\n\t\t\tif (step.skip) {\n\t\t\t\tpipeline.currentStep = i + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// step_start event\n\t\t\tyield createEvent(\"step_start\", pipeline.featureId, step, {\n\t\t\t\tagent: step.agent,\n\t\t\t\tinputs: step.inputs,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t});\n\n\t\t\t// Update status\n\t\t\tconst featureStatus = agentRoleToFeatureStatus(step.agent, step.action);\n\t\t\ttry {\n\t\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, featureStatus);\n\t\t\t} catch {\n\t\t\t\t// Ignore status transition failure (may already be in this state)\n\t\t\t}\n\n\t\t\t// Execute step (with retry for transient errors)\n\t\t\tthis.log.info(`Step executing: ${step.agent}:${step.action}`, { featureId: pipeline.featureId, step: i });\n\t\t\tconst maxStepRetries = this.config.retry.maxStepRetries ?? 2;\n\t\t\tlet stepAttempt = 0;\n\t\t\tconst startTime = Date.now();\n\n\t\t\twhile (stepAttempt <= maxStepRetries) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.stepExecutor(step, pipeline.featureId, context);\n\t\t\t\t\tbreak;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tconst errorStack = error instanceof Error ? error.stack : undefined;\n\t\t\t\t\tconst errorCause = error instanceof Error ? error.cause : undefined;\n\n\t\t\t\t\tif (stepAttempt < maxStepRetries && isRetryableStepError(errorMsg)) {\n\t\t\t\t\t\tstepAttempt++;\n\t\t\t\t\t\tconst delay = this.retryDelayFn(stepAttempt - 1);\n\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t`Step error (retryable), retry ${stepAttempt}/${maxStepRetries} after ${delay}ms: ${step.agent}:${step.action}: ${errorMsg}`,\n\t\t\t\t\t\t\t{ featureId: pipeline.featureId, step: i, attempt: stepAttempt, cause: errorCause },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tyield createEvent(\"step_retry\", pipeline.featureId, step, {\n\t\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\t\tattempt: stepAttempt,\n\t\t\t\t\t\t\tmaxRetries: maxStepRetries,\n\t\t\t\t\t\t\tdelayMs: delay,\n\t\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.error(`Step failed: ${step.agent}:${step.action}: ${errorMsg}`, {\n\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\tstep: i,\n\t\t\t\t\t\tstack: errorStack,\n\t\t\t\t\t\tcause: errorCause,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, step, {\n\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\tthis.log.info(`Step completed: ${step.agent}:${step.action} (${elapsed}ms)`, {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstep: i,\n\t\t\t});\n\n\t\t\t// Gate validation\n\t\t\tif (step.gate) {\n\t\t\t\tconst gateResult = await this.gateChecker.evaluate(step, pipeline.featureId, this.requestApproval);\n\n\t\t\t\tif (!gateResult.passed) {\n\t\t\t\t\tif (gateResult.action === \"abort\") {\n\t\t\t\t\t\tthis.log.warn(`Gate abort: ${step.gate.type}`, { featureId: pipeline.featureId });\n\t\t\t\t\t\tpipeline.status = \"aborted\";\n\t\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\t\t// Delete feature artifacts\n\t\t\t\t\t\tawait this.store.clearFeatureDir(pipeline.featureId);\n\t\t\t\t\t\tyield createEvent(\"feature_aborted\", pipeline.featureId, step, {\n\t\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t`Gate rejected: ${step.gate.type}, retry ${pipeline.retryCount + 1}/${pipeline.maxRetries}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\t\tpipeline.retryCount++;\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"gate_rejected\", pipeline.featureId, step, {\n\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (pipeline.retryCount >= pipeline.maxRetries) {\n\t\t\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, step, {\n\t\t\t\t\t\t\treason: \"max retries exceeded\",\n\t\t\t\t\t\t\tretryCount: pipeline.retryCount,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// On gate failure, do not increment currentStep so this step is re-executed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Distinguish Skip vs Approve\n\t\t\t\tif (gateResult.action === \"skip\") {\n\t\t\t\t\tyield createEvent(\"gate_skipped\", pipeline.featureId, step);\n\t\t\t\t} else {\n\t\t\t\t\tyield createEvent(\"gate_approved\", pipeline.featureId, step);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// step_complete event\n\t\t\tyield createEvent(\"step_complete\", pipeline.featureId, step, {\n\t\t\t\toutputs: step.outputs,\n\t\t\t\telapsed,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\tusage: context.lastStepUsage,\n\t\t\t\tresponseText: context.lastStepResponseText,\n\t\t\t});\n\t\t\tcontext.lastStepUsage = undefined;\n\t\t\tcontext.lastStepResponseText = undefined;\n\n\t\t\tpipeline.currentStep = i + 1;\n\n\t\t\t// Persist pipeline state on step completion\n\t\t\tawait this.persistPipeline(pipeline);\n\t\t}\n\n\t\t// All steps completed\n\t\tthis.log.info(`Pipeline completed: ${pipeline.featureId}`, { featureId: pipeline.featureId });\n\t\tpipeline.status = \"done\";\n\t\tawait this.persistPipeline(pipeline);\n\t\ttry {\n\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, \"done\");\n\t\t} catch {\n\t\t\t// Ignore status transition failure\n\t\t}\n\t\tyield createEvent(\"pipeline_complete\", pipeline.featureId);\n\t}\n\n\t/**\n\t * Resumes the pipeline. Continues execution from currentStep.\n\t */\n\tasync *resume(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tyield* this.run(pipeline);\n\t}\n\n\t/** Pauses after the current step completes. */\n\tpause(): void {\n\t\tthis.paused = true;\n\t}\n\n\t/** Aborts immediately. */\n\tabort(): void {\n\t\tthis.aborted = true;\n\t}\n\n\t/** Persists the pipeline state to disk. */\n\tprivate async persistPipeline(pipeline: FeaturePipeline): Promise<void> {\n\t\ttry {\n\t\t\tawait this.store.savePipelineState(pipeline.featureId, toPersisted(pipeline));\n\t\t\tthis.log.debug(\"Pipeline state persisted\", {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstatus: pipeline.status,\n\t\t\t\tcurrentStep: pipeline.currentStep,\n\t\t\t});\n\t\t} catch {\n\t\t\tthis.log.warn(\"Pipeline state persistence failed\", { featureId: pipeline.featureId });\n\t\t}\n\t}\n}\n"]}
|
package/dist/pipeline.js
CHANGED
|
@@ -92,7 +92,6 @@ export class PipelineRunner {
|
|
|
92
92
|
onAgentFinished;
|
|
93
93
|
log;
|
|
94
94
|
logger;
|
|
95
|
-
availableSkills;
|
|
96
95
|
retryDelayFn;
|
|
97
96
|
paused = false;
|
|
98
97
|
aborted = false;
|
|
@@ -107,7 +106,6 @@ export class PipelineRunner {
|
|
|
107
106
|
this.onAgentCreated = options.onAgentCreated;
|
|
108
107
|
this.onAgentFinished = options.onAgentFinished;
|
|
109
108
|
this.logger = options.logger;
|
|
110
|
-
this.availableSkills = options.availableSkills;
|
|
111
109
|
this.retryDelayFn = options.retryDelayFn ?? defaultRetryDelay;
|
|
112
110
|
this.log = createModuleLogger(options.logger ?? noopLogger, "pipeline");
|
|
113
111
|
this.gateChecker = new GateChecker(this.store, this.config, this.model, options.logger);
|
|
@@ -134,7 +132,6 @@ export class PipelineRunner {
|
|
|
134
132
|
onAgentCreated: this.onAgentCreated,
|
|
135
133
|
onAgentFinished: this.onAgentFinished,
|
|
136
134
|
logger: this.logger,
|
|
137
|
-
availableSkills: this.availableSkills,
|
|
138
135
|
};
|
|
139
136
|
for (let i = pipeline.currentStep; i < pipeline.steps.length; i++) {
|
|
140
137
|
if (this.aborted) {
|
package/dist/pipeline.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { GateChecker } from \"./gate.js\";\nimport { createModuleLogger, type ModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport { defaultStepExecutor } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type {\n\tAgentRole,\n\tFeaturePipeline,\n\tFeatureStatusValue,\n\tPersistedPipeline,\n\tPipelineStep,\n\tVibeConfig,\n\tVibeEvent,\n} from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Aggregated token usage for a single pipeline step. */\nexport interface StepUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\t/** Total cost in USD. */\n\tcost: number;\n}\n\n/** Context required for step execution */\nexport interface StepContext {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows external code to acquire an Agent reference. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes (success/error). Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n\t/** Mutable. Set by StepExecutor after agent completion. Read by PipelineRunner for event data. */\n\tlastStepUsage?: StepUsage;\n\t/** Mutable. Set by StepExecutor after agent completion. Last assistant response text. */\n\tlastStepResponseText?: string;\n}\n\n/** Step execution function. Called by the pipeline engine for each step. */\nexport type StepExecutor = (step: PipelineStep, featureId: string, context: StepContext) => Promise<void>;\n\n/** Pipeline execution options */\nexport interface PipelineRunnerOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows acquiring an Agent reference during execution. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes. Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n\t/** Custom retry delay function for step execution retries. Defaults to exponential backoff. */\n\tretryDelayFn?: RetryDelayFn;\n}\n\n// ─── Status Mapping ──────────────────────────────────────────────────────────\n\n/** Maps agent role (+ optional action) to FeatureStatusValue */\nexport function agentRoleToFeatureStatus(role: AgentRole, action?: string): FeatureStatusValue {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"planned\";\n\t\tcase \"architect\":\n\t\t\treturn \"designing\";\n\t\tcase \"developer\":\n\t\t\treturn \"implementing\";\n\t\tcase \"tester\":\n\t\t\treturn \"testing\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"reviewing\";\n\t\tcase \"cicd\":\n\t\t\treturn action === \"merge\" ? \"merging\" : \"branching\";\n\t\tcase \"analyzer\":\n\t\t\treturn \"designing\";\n\t\tcase \"diagnostician\":\n\t\t\treturn \"designing\";\n\t\tcase \"discovery\":\n\t\t\treturn \"planned\";\n\t\tcase \"projectAnalyzer\":\n\t\t\treturn \"planned\";\n\t\tcase \"documenter\":\n\t\t\treturn \"done\";\n\t\tcase \"standardsEnricher\":\n\t\t\treturn \"planned\";\n\t\tcase \"systemArchitect\":\n\t\t\treturn \"designing\";\n\t\tcase \"recover\":\n\t\t\treturn \"planned\";\n\t}\n}\n\n// ─── Retry Helpers ───────────────────────────────────────────────────────────\n\n/**\n * Pattern matching transient errors that should be retried.\n * Covers: undici fetch \"terminated\", HTTP 5xx, rate limits, connection errors.\n */\nconst RETRYABLE_ERROR_PATTERN =\n\t/terminated|overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|retry delay|ECONNRESET|ETIMEDOUT|EPIPE|EAI_AGAIN/i;\n\n/** Returns true if the error message indicates a transient failure worth retrying. */\nexport function isRetryableStepError(errorMessage: string): boolean {\n\treturn RETRYABLE_ERROR_PATTERN.test(errorMessage);\n}\n\n/** Default exponential backoff delay in ms: base * 2^attempt, capped at 60s. */\nexport function defaultRetryDelay(attempt: number): number {\n\tconst base = 5000;\n\tconst maxDelay = 60000;\n\treturn Math.min(base * 2 ** attempt, maxDelay);\n}\n\n/** Retry delay function signature. */\nexport type RetryDelayFn = (attempt: number) => number;\n\n// ─── Helper ──────────────────────────────────────────────────────────────────\n\nfunction createEvent(\n\ttype: VibeEvent[\"type\"],\n\tfeatureId: string,\n\tstep?: PipelineStep,\n\tdata?: Record<string, unknown>,\n): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tstep,\n\t\tdata,\n\t};\n}\n\n// ─── Persistence Helpers ─────────────────────────────────────────────────────\n\n/** Creates a PersistedPipeline from a FeaturePipeline. */\nexport function toPersisted(pipeline: FeaturePipeline): PersistedPipeline {\n\treturn {\n\t\tfeatureId: pipeline.featureId,\n\t\tworkflowType: pipeline.workflowType,\n\t\tcurrentStep: pipeline.currentStep,\n\t\tstatus: pipeline.status,\n\t\tretryCount: pipeline.retryCount,\n\t\tmaxRetries: pipeline.maxRetries,\n\t\tparentFeatureId: pipeline.parentFeatureId,\n\t\tissueRef: pipeline.issueRef,\n\t};\n}\n\n// ─── PipelineRunner ──────────────────────────────────────────────────────────\n\n/**\n * Pipeline runner. Sequentially executes FeaturePipeline steps and emits events.\n */\nexport class PipelineRunner {\n\tprivate readonly store: VibeStore;\n\tprivate readonly config: VibeConfig;\n\tprivate readonly projectRoot: string;\n\tprivate readonly requestApproval?: ApprovalRequestFn;\n\tprivate readonly stepExecutor: StepExecutor;\n\tprivate readonly gateChecker: GateChecker;\n\tprivate readonly getApiKey?: GetApiKeyFn;\n\tprivate readonly model?: Model<any>;\n\tprivate readonly onAgentCreated?: (agent: Agent) => void;\n\tprivate readonly onAgentFinished?: () => void;\n\tprivate readonly log: ModuleLogger;\n\tprivate readonly logger?: VibeLogger;\n\tprivate readonly availableSkills?: string;\n\tprivate readonly retryDelayFn: RetryDelayFn;\n\n\tprivate paused = false;\n\tprivate aborted = false;\n\n\tconstructor(options: PipelineRunnerOptions) {\n\t\tthis.store = options.store;\n\t\tthis.config = options.config;\n\t\tthis.projectRoot = options.projectRoot;\n\t\tthis.requestApproval = options.requestApproval;\n\t\tthis.stepExecutor = options.stepExecutor ?? defaultStepExecutor;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.model = options.model;\n\t\tthis.onAgentCreated = options.onAgentCreated;\n\t\tthis.onAgentFinished = options.onAgentFinished;\n\t\tthis.logger = options.logger;\n\t\tthis.availableSkills = options.availableSkills;\n\t\tthis.retryDelayFn = options.retryDelayFn ?? defaultRetryDelay;\n\t\tthis.log = createModuleLogger(options.logger ?? noopLogger, \"pipeline\");\n\t\tthis.gateChecker = new GateChecker(this.store, this.config, this.model, options.logger);\n\t}\n\n\t/**\n\t * Runs the pipeline and yields events.\n\t */\n\tasync *run(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tthis.paused = false;\n\t\tthis.aborted = false;\n\t\tpipeline.status = \"running\";\n\t\tthis.log.info(`Pipeline started: ${pipeline.featureId}`, {\n\t\t\tfeatureId: pipeline.featureId,\n\t\t\tworkflowType: pipeline.workflowType,\n\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\tcurrentStep: pipeline.currentStep,\n\t\t});\n\n\t\tconst context: StepContext = {\n\t\t\tstore: this.store,\n\t\t\tconfig: this.config,\n\t\t\tprojectRoot: this.projectRoot,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tmodel: this.model,\n\t\t\tonAgentCreated: this.onAgentCreated,\n\t\t\tonAgentFinished: this.onAgentFinished,\n\t\t\tlogger: this.logger,\n\t\t\tavailableSkills: this.availableSkills,\n\t\t};\n\n\t\tfor (let i = pipeline.currentStep; i < pipeline.steps.length; i++) {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.log.warn(\"Pipeline aborted\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, pipeline.steps[i], {\n\t\t\t\t\treason: \"aborted\",\n\t\t\t\t\tstepIndex: i,\n\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.paused) {\n\t\t\t\tthis.log.info(\"Pipeline paused\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, pipeline.steps[i], { reason: \"paused\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst step = pipeline.steps[i];\n\n\t\t\t// Handle skip\n\t\t\tif (step.skip) {\n\t\t\t\tpipeline.currentStep = i + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// step_start event\n\t\t\tyield createEvent(\"step_start\", pipeline.featureId, step, {\n\t\t\t\tagent: step.agent,\n\t\t\t\tinputs: step.inputs,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t});\n\n\t\t\t// Update status\n\t\t\tconst featureStatus = agentRoleToFeatureStatus(step.agent, step.action);\n\t\t\ttry {\n\t\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, featureStatus);\n\t\t\t} catch {\n\t\t\t\t// Ignore status transition failure (may already be in this state)\n\t\t\t}\n\n\t\t\t// Execute step (with retry for transient errors)\n\t\t\tthis.log.info(`Step executing: ${step.agent}:${step.action}`, { featureId: pipeline.featureId, step: i });\n\t\t\tconst maxStepRetries = this.config.retry.maxStepRetries ?? 2;\n\t\t\tlet stepAttempt = 0;\n\t\t\tconst startTime = Date.now();\n\n\t\t\twhile (stepAttempt <= maxStepRetries) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.stepExecutor(step, pipeline.featureId, context);\n\t\t\t\t\tbreak;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tconst errorStack = error instanceof Error ? error.stack : undefined;\n\t\t\t\t\tconst errorCause = error instanceof Error ? error.cause : undefined;\n\n\t\t\t\t\tif (stepAttempt < maxStepRetries && isRetryableStepError(errorMsg)) {\n\t\t\t\t\t\tstepAttempt++;\n\t\t\t\t\t\tconst delay = this.retryDelayFn(stepAttempt - 1);\n\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t`Step error (retryable), retry ${stepAttempt}/${maxStepRetries} after ${delay}ms: ${step.agent}:${step.action}: ${errorMsg}`,\n\t\t\t\t\t\t\t{ featureId: pipeline.featureId, step: i, attempt: stepAttempt, cause: errorCause },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tyield createEvent(\"step_retry\", pipeline.featureId, step, {\n\t\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\t\tattempt: stepAttempt,\n\t\t\t\t\t\t\tmaxRetries: maxStepRetries,\n\t\t\t\t\t\t\tdelayMs: delay,\n\t\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.error(`Step failed: ${step.agent}:${step.action}: ${errorMsg}`, {\n\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\tstep: i,\n\t\t\t\t\t\tstack: errorStack,\n\t\t\t\t\t\tcause: errorCause,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, step, {\n\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\tthis.log.info(`Step completed: ${step.agent}:${step.action} (${elapsed}ms)`, {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstep: i,\n\t\t\t});\n\n\t\t\t// Gate validation\n\t\t\tif (step.gate) {\n\t\t\t\tconst gateResult = await this.gateChecker.evaluate(step, pipeline.featureId, this.requestApproval);\n\n\t\t\t\tif (!gateResult.passed) {\n\t\t\t\t\tif (gateResult.action === \"abort\") {\n\t\t\t\t\t\tthis.log.warn(`Gate abort: ${step.gate.type}`, { featureId: pipeline.featureId });\n\t\t\t\t\t\tpipeline.status = \"aborted\";\n\t\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\t\t// Delete feature artifacts\n\t\t\t\t\t\tawait this.store.clearFeatureDir(pipeline.featureId);\n\t\t\t\t\t\tyield createEvent(\"feature_aborted\", pipeline.featureId, step, {\n\t\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t`Gate rejected: ${step.gate.type}, retry ${pipeline.retryCount + 1}/${pipeline.maxRetries}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\t\tpipeline.retryCount++;\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"gate_rejected\", pipeline.featureId, step, {\n\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (pipeline.retryCount >= pipeline.maxRetries) {\n\t\t\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, step, {\n\t\t\t\t\t\t\treason: \"max retries exceeded\",\n\t\t\t\t\t\t\tretryCount: pipeline.retryCount,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// On gate failure, do not increment currentStep so this step is re-executed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Distinguish Skip vs Approve\n\t\t\t\tif (gateResult.action === \"skip\") {\n\t\t\t\t\tyield createEvent(\"gate_skipped\", pipeline.featureId, step);\n\t\t\t\t} else {\n\t\t\t\t\tyield createEvent(\"gate_approved\", pipeline.featureId, step);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// step_complete event\n\t\t\tyield createEvent(\"step_complete\", pipeline.featureId, step, {\n\t\t\t\toutputs: step.outputs,\n\t\t\t\telapsed,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\tusage: context.lastStepUsage,\n\t\t\t\tresponseText: context.lastStepResponseText,\n\t\t\t});\n\t\t\tcontext.lastStepUsage = undefined;\n\t\t\tcontext.lastStepResponseText = undefined;\n\n\t\t\tpipeline.currentStep = i + 1;\n\n\t\t\t// Persist pipeline state on step completion\n\t\t\tawait this.persistPipeline(pipeline);\n\t\t}\n\n\t\t// All steps completed\n\t\tthis.log.info(`Pipeline completed: ${pipeline.featureId}`, { featureId: pipeline.featureId });\n\t\tpipeline.status = \"done\";\n\t\tawait this.persistPipeline(pipeline);\n\t\ttry {\n\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, \"done\");\n\t\t} catch {\n\t\t\t// Ignore status transition failure\n\t\t}\n\t\tyield createEvent(\"pipeline_complete\", pipeline.featureId);\n\t}\n\n\t/**\n\t * Resumes the pipeline. Continues execution from currentStep.\n\t */\n\tasync *resume(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tyield* this.run(pipeline);\n\t}\n\n\t/** Pauses after the current step completes. */\n\tpause(): void {\n\t\tthis.paused = true;\n\t}\n\n\t/** Aborts immediately. */\n\tabort(): void {\n\t\tthis.aborted = true;\n\t}\n\n\t/** Persists the pipeline state to disk. */\n\tprivate async persistPipeline(pipeline: FeaturePipeline): Promise<void> {\n\t\ttry {\n\t\t\tawait this.store.savePipelineState(pipeline.featureId, toPersisted(pipeline));\n\t\t\tthis.log.debug(\"Pipeline state persisted\", {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstatus: pipeline.status,\n\t\t\t\tcurrentStep: pipeline.currentStep,\n\t\t\t});\n\t\t} catch {\n\t\t\tthis.log.warn(\"Pipeline state persistence failed\", { featureId: pipeline.featureId });\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport type { ApprovalRequestFn } from \"./gate.js\";\nimport { GateChecker } from \"./gate.js\";\nimport { createModuleLogger, type ModuleLogger, noopLogger, type VibeLogger } from \"./logger.js\";\nimport { defaultStepExecutor } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type {\n\tAgentRole,\n\tFeaturePipeline,\n\tFeatureStatusValue,\n\tPersistedPipeline,\n\tPipelineStep,\n\tVibeConfig,\n\tVibeEvent,\n} from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Aggregated token usage for a single pipeline step. */\nexport interface StepUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\t/** Total cost in USD. */\n\tcost: number;\n}\n\n/** Context required for step execution */\nexport interface StepContext {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows external code to acquire an Agent reference. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes (success/error). Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Mutable. Set by StepExecutor after agent completion. Read by PipelineRunner for event data. */\n\tlastStepUsage?: StepUsage;\n\t/** Mutable. Set by StepExecutor after agent completion. Last assistant response text. */\n\tlastStepResponseText?: string;\n}\n\n/** Step execution function. Called by the pipeline engine for each step. */\nexport type StepExecutor = (step: PipelineStep, featureId: string, context: StepContext) => Promise<void>;\n\n/** Pipeline execution options */\nexport interface PipelineRunnerOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequestApproval?: ApprovalRequestFn;\n\tstepExecutor?: StepExecutor;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Called immediately after agent creation. Allows acquiring an Agent reference during execution. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Called after agent execution completes. Allows releasing the Agent reference. */\n\tonAgentFinished?: () => void;\n\t/** Logger. Uses noop if not specified. */\n\tlogger?: VibeLogger;\n\t/** Custom retry delay function for step execution retries. Defaults to exponential backoff. */\n\tretryDelayFn?: RetryDelayFn;\n}\n\n// ─── Status Mapping ──────────────────────────────────────────────────────────\n\n/** Maps agent role (+ optional action) to FeatureStatusValue */\nexport function agentRoleToFeatureStatus(role: AgentRole, action?: string): FeatureStatusValue {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"planned\";\n\t\tcase \"architect\":\n\t\t\treturn \"designing\";\n\t\tcase \"developer\":\n\t\t\treturn \"implementing\";\n\t\tcase \"tester\":\n\t\t\treturn \"testing\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"reviewing\";\n\t\tcase \"cicd\":\n\t\t\treturn action === \"merge\" ? \"merging\" : \"branching\";\n\t\tcase \"analyzer\":\n\t\t\treturn \"designing\";\n\t\tcase \"diagnostician\":\n\t\t\treturn \"designing\";\n\t\tcase \"discovery\":\n\t\t\treturn \"planned\";\n\t\tcase \"projectAnalyzer\":\n\t\t\treturn \"planned\";\n\t\tcase \"documenter\":\n\t\t\treturn \"done\";\n\t\tcase \"standardsEnricher\":\n\t\t\treturn \"planned\";\n\t\tcase \"systemArchitect\":\n\t\t\treturn \"designing\";\n\t\tcase \"recover\":\n\t\t\treturn \"planned\";\n\t}\n}\n\n// ─── Retry Helpers ───────────────────────────────────────────────────────────\n\n/**\n * Pattern matching transient errors that should be retried.\n * Covers: undici fetch \"terminated\", HTTP 5xx, rate limits, connection errors.\n */\nconst RETRYABLE_ERROR_PATTERN =\n\t/terminated|overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|retry delay|ECONNRESET|ETIMEDOUT|EPIPE|EAI_AGAIN/i;\n\n/** Returns true if the error message indicates a transient failure worth retrying. */\nexport function isRetryableStepError(errorMessage: string): boolean {\n\treturn RETRYABLE_ERROR_PATTERN.test(errorMessage);\n}\n\n/** Default exponential backoff delay in ms: base * 2^attempt, capped at 60s. */\nexport function defaultRetryDelay(attempt: number): number {\n\tconst base = 5000;\n\tconst maxDelay = 60000;\n\treturn Math.min(base * 2 ** attempt, maxDelay);\n}\n\n/** Retry delay function signature. */\nexport type RetryDelayFn = (attempt: number) => number;\n\n// ─── Helper ──────────────────────────────────────────────────────────────────\n\nfunction createEvent(\n\ttype: VibeEvent[\"type\"],\n\tfeatureId: string,\n\tstep?: PipelineStep,\n\tdata?: Record<string, unknown>,\n): VibeEvent {\n\treturn {\n\t\ttype,\n\t\tfeatureId,\n\t\ttimestamp: new Date().toISOString(),\n\t\tstep,\n\t\tdata,\n\t};\n}\n\n// ─── Persistence Helpers ─────────────────────────────────────────────────────\n\n/** Creates a PersistedPipeline from a FeaturePipeline. */\nexport function toPersisted(pipeline: FeaturePipeline): PersistedPipeline {\n\treturn {\n\t\tfeatureId: pipeline.featureId,\n\t\tworkflowType: pipeline.workflowType,\n\t\tcurrentStep: pipeline.currentStep,\n\t\tstatus: pipeline.status,\n\t\tretryCount: pipeline.retryCount,\n\t\tmaxRetries: pipeline.maxRetries,\n\t\tparentFeatureId: pipeline.parentFeatureId,\n\t\tissueRef: pipeline.issueRef,\n\t};\n}\n\n// ─── PipelineRunner ──────────────────────────────────────────────────────────\n\n/**\n * Pipeline runner. Sequentially executes FeaturePipeline steps and emits events.\n */\nexport class PipelineRunner {\n\tprivate readonly store: VibeStore;\n\tprivate readonly config: VibeConfig;\n\tprivate readonly projectRoot: string;\n\tprivate readonly requestApproval?: ApprovalRequestFn;\n\tprivate readonly stepExecutor: StepExecutor;\n\tprivate readonly gateChecker: GateChecker;\n\tprivate readonly getApiKey?: GetApiKeyFn;\n\tprivate readonly model?: Model<any>;\n\tprivate readonly onAgentCreated?: (agent: Agent) => void;\n\tprivate readonly onAgentFinished?: () => void;\n\tprivate readonly log: ModuleLogger;\n\tprivate readonly logger?: VibeLogger;\n\tprivate readonly retryDelayFn: RetryDelayFn;\n\n\tprivate paused = false;\n\tprivate aborted = false;\n\n\tconstructor(options: PipelineRunnerOptions) {\n\t\tthis.store = options.store;\n\t\tthis.config = options.config;\n\t\tthis.projectRoot = options.projectRoot;\n\t\tthis.requestApproval = options.requestApproval;\n\t\tthis.stepExecutor = options.stepExecutor ?? defaultStepExecutor;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.model = options.model;\n\t\tthis.onAgentCreated = options.onAgentCreated;\n\t\tthis.onAgentFinished = options.onAgentFinished;\n\t\tthis.logger = options.logger;\n\t\tthis.retryDelayFn = options.retryDelayFn ?? defaultRetryDelay;\n\t\tthis.log = createModuleLogger(options.logger ?? noopLogger, \"pipeline\");\n\t\tthis.gateChecker = new GateChecker(this.store, this.config, this.model, options.logger);\n\t}\n\n\t/**\n\t * Runs the pipeline and yields events.\n\t */\n\tasync *run(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tthis.paused = false;\n\t\tthis.aborted = false;\n\t\tpipeline.status = \"running\";\n\t\tthis.log.info(`Pipeline started: ${pipeline.featureId}`, {\n\t\t\tfeatureId: pipeline.featureId,\n\t\t\tworkflowType: pipeline.workflowType,\n\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\tcurrentStep: pipeline.currentStep,\n\t\t});\n\n\t\tconst context: StepContext = {\n\t\t\tstore: this.store,\n\t\t\tconfig: this.config,\n\t\t\tprojectRoot: this.projectRoot,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tmodel: this.model,\n\t\t\tonAgentCreated: this.onAgentCreated,\n\t\t\tonAgentFinished: this.onAgentFinished,\n\t\t\tlogger: this.logger,\n\t\t};\n\n\t\tfor (let i = pipeline.currentStep; i < pipeline.steps.length; i++) {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.log.warn(\"Pipeline aborted\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, pipeline.steps[i], {\n\t\t\t\t\treason: \"aborted\",\n\t\t\t\t\tstepIndex: i,\n\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.paused) {\n\t\t\t\tthis.log.info(\"Pipeline paused\", { featureId: pipeline.featureId, step: i });\n\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, pipeline.steps[i], { reason: \"paused\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst step = pipeline.steps[i];\n\n\t\t\t// Handle skip\n\t\t\tif (step.skip) {\n\t\t\t\tpipeline.currentStep = i + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// step_start event\n\t\t\tyield createEvent(\"step_start\", pipeline.featureId, step, {\n\t\t\t\tagent: step.agent,\n\t\t\t\tinputs: step.inputs,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t});\n\n\t\t\t// Update status\n\t\t\tconst featureStatus = agentRoleToFeatureStatus(step.agent, step.action);\n\t\t\ttry {\n\t\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, featureStatus);\n\t\t\t} catch {\n\t\t\t\t// Ignore status transition failure (may already be in this state)\n\t\t\t}\n\n\t\t\t// Execute step (with retry for transient errors)\n\t\t\tthis.log.info(`Step executing: ${step.agent}:${step.action}`, { featureId: pipeline.featureId, step: i });\n\t\t\tconst maxStepRetries = this.config.retry.maxStepRetries ?? 2;\n\t\t\tlet stepAttempt = 0;\n\t\t\tconst startTime = Date.now();\n\n\t\t\twhile (stepAttempt <= maxStepRetries) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.stepExecutor(step, pipeline.featureId, context);\n\t\t\t\t\tbreak;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tconst errorStack = error instanceof Error ? error.stack : undefined;\n\t\t\t\t\tconst errorCause = error instanceof Error ? error.cause : undefined;\n\n\t\t\t\t\tif (stepAttempt < maxStepRetries && isRetryableStepError(errorMsg)) {\n\t\t\t\t\t\tstepAttempt++;\n\t\t\t\t\t\tconst delay = this.retryDelayFn(stepAttempt - 1);\n\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t`Step error (retryable), retry ${stepAttempt}/${maxStepRetries} after ${delay}ms: ${step.agent}:${step.action}: ${errorMsg}`,\n\t\t\t\t\t\t\t{ featureId: pipeline.featureId, step: i, attempt: stepAttempt, cause: errorCause },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tyield createEvent(\"step_retry\", pipeline.featureId, step, {\n\t\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\t\tattempt: stepAttempt,\n\t\t\t\t\t\t\tmaxRetries: maxStepRetries,\n\t\t\t\t\t\t\tdelayMs: delay,\n\t\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.error(`Step failed: ${step.agent}:${step.action}: ${errorMsg}`, {\n\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\tstep: i,\n\t\t\t\t\t\tstack: errorStack,\n\t\t\t\t\t\tcause: errorCause,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\tpipeline.status = \"failed\";\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"step_failed\", pipeline.featureId, step, {\n\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\tstepIndex: i,\n\t\t\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\t\t\tattempts: stepAttempt + 1,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\tthis.log.info(`Step completed: ${step.agent}:${step.action} (${elapsed}ms)`, {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstep: i,\n\t\t\t});\n\n\t\t\t// Gate validation\n\t\t\tif (step.gate) {\n\t\t\t\tconst gateResult = await this.gateChecker.evaluate(step, pipeline.featureId, this.requestApproval);\n\n\t\t\t\tif (!gateResult.passed) {\n\t\t\t\t\tif (gateResult.action === \"abort\") {\n\t\t\t\t\t\tthis.log.warn(`Gate abort: ${step.gate.type}`, { featureId: pipeline.featureId });\n\t\t\t\t\t\tpipeline.status = \"aborted\";\n\t\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\t\t// Delete feature artifacts\n\t\t\t\t\t\tawait this.store.clearFeatureDir(pipeline.featureId);\n\t\t\t\t\t\tyield createEvent(\"feature_aborted\", pipeline.featureId, step, {\n\t\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t`Gate rejected: ${step.gate.type}, retry ${pipeline.retryCount + 1}/${pipeline.maxRetries}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tpipeline.status = \"blocked\";\n\t\t\t\t\tpipeline.retryCount++;\n\t\t\t\t\tawait this.persistPipeline(pipeline);\n\t\t\t\t\tyield createEvent(\"gate_rejected\", pipeline.featureId, step, {\n\t\t\t\t\t\taction: gateResult.action,\n\t\t\t\t\t\tfeedback: gateResult.feedback,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (pipeline.retryCount >= pipeline.maxRetries) {\n\t\t\t\t\t\tyield createEvent(\"blocked\", pipeline.featureId, step, {\n\t\t\t\t\t\t\treason: \"max retries exceeded\",\n\t\t\t\t\t\t\tretryCount: pipeline.retryCount,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// On gate failure, do not increment currentStep so this step is re-executed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Distinguish Skip vs Approve\n\t\t\t\tif (gateResult.action === \"skip\") {\n\t\t\t\t\tyield createEvent(\"gate_skipped\", pipeline.featureId, step);\n\t\t\t\t} else {\n\t\t\t\t\tyield createEvent(\"gate_approved\", pipeline.featureId, step);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// step_complete event\n\t\t\tyield createEvent(\"step_complete\", pipeline.featureId, step, {\n\t\t\t\toutputs: step.outputs,\n\t\t\t\telapsed,\n\t\t\t\tstepIndex: i,\n\t\t\t\ttotalSteps: pipeline.steps.length,\n\t\t\t\tusage: context.lastStepUsage,\n\t\t\t\tresponseText: context.lastStepResponseText,\n\t\t\t});\n\t\t\tcontext.lastStepUsage = undefined;\n\t\t\tcontext.lastStepResponseText = undefined;\n\n\t\t\tpipeline.currentStep = i + 1;\n\n\t\t\t// Persist pipeline state on step completion\n\t\t\tawait this.persistPipeline(pipeline);\n\t\t}\n\n\t\t// All steps completed\n\t\tthis.log.info(`Pipeline completed: ${pipeline.featureId}`, { featureId: pipeline.featureId });\n\t\tpipeline.status = \"done\";\n\t\tawait this.persistPipeline(pipeline);\n\t\ttry {\n\t\t\tawait this.store.updateFeatureStatus(pipeline.featureId, \"done\");\n\t\t} catch {\n\t\t\t// Ignore status transition failure\n\t\t}\n\t\tyield createEvent(\"pipeline_complete\", pipeline.featureId);\n\t}\n\n\t/**\n\t * Resumes the pipeline. Continues execution from currentStep.\n\t */\n\tasync *resume(pipeline: FeaturePipeline): AsyncGenerator<VibeEvent> {\n\t\tyield* this.run(pipeline);\n\t}\n\n\t/** Pauses after the current step completes. */\n\tpause(): void {\n\t\tthis.paused = true;\n\t}\n\n\t/** Aborts immediately. */\n\tabort(): void {\n\t\tthis.aborted = true;\n\t}\n\n\t/** Persists the pipeline state to disk. */\n\tprivate async persistPipeline(pipeline: FeaturePipeline): Promise<void> {\n\t\ttry {\n\t\t\tawait this.store.savePipelineState(pipeline.featureId, toPersisted(pipeline));\n\t\t\tthis.log.debug(\"Pipeline state persisted\", {\n\t\t\t\tfeatureId: pipeline.featureId,\n\t\t\t\tstatus: pipeline.status,\n\t\t\t\tcurrentStep: pipeline.currentStep,\n\t\t\t});\n\t\t} catch {\n\t\t\tthis.log.warn(\"Pipeline state persistence failed\", { featureId: pipeline.featureId });\n\t\t}\n\t}\n}\n"]}
|
package/dist/planner.d.ts
CHANGED
|
@@ -17,8 +17,6 @@ export interface PlannerOptions {
|
|
|
17
17
|
onMessage?: (message: string) => void;
|
|
18
18
|
/** User feedback on rejection. Regenerates the existing plan with feedback applied. */
|
|
19
19
|
feedback?: string;
|
|
20
|
-
/** Lightweight skill index. Included in the agent system prompt. */
|
|
21
|
-
availableSkills?: string;
|
|
22
20
|
/** Callback invoked when the agent is created. Used for abort wiring, etc. */
|
|
23
21
|
onAgentCreated?: (agent: Agent) => void;
|
|
24
22
|
/** Callback invoked when the agent finishes execution. */
|