@nathapp/nax 0.50.3 → 0.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +177 -104
- package/dist/nax.js +417 -213
- package/package.json +1 -3
- package/bin/nax.ts +0 -1195
- package/src/acceptance/fix-generator.ts +0 -322
- package/src/acceptance/generator.ts +0 -415
- package/src/acceptance/index.ts +0 -42
- package/src/acceptance/refinement.ts +0 -224
- package/src/acceptance/templates/cli.ts +0 -47
- package/src/acceptance/templates/component.ts +0 -78
- package/src/acceptance/templates/e2e.ts +0 -43
- package/src/acceptance/templates/index.ts +0 -21
- package/src/acceptance/templates/snapshot.ts +0 -50
- package/src/acceptance/templates/unit.ts +0 -48
- package/src/acceptance/types.ts +0 -138
- package/src/agents/acp/adapter.ts +0 -888
- package/src/agents/acp/cost.ts +0 -9
- package/src/agents/acp/index.ts +0 -7
- package/src/agents/acp/interaction-bridge.ts +0 -126
- package/src/agents/acp/parser.ts +0 -119
- package/src/agents/acp/spawn-client.ts +0 -373
- package/src/agents/acp/types.ts +0 -22
- package/src/agents/aider/adapter.ts +0 -135
- package/src/agents/claude/adapter.ts +0 -258
- package/src/agents/claude/complete.ts +0 -80
- package/src/agents/claude/cost.ts +0 -16
- package/src/agents/claude/execution.ts +0 -215
- package/src/agents/claude/index.ts +0 -3
- package/src/agents/claude/interactive.ts +0 -77
- package/src/agents/claude/plan.ts +0 -179
- package/src/agents/codex/adapter.ts +0 -153
- package/src/agents/cost/calculate.ts +0 -154
- package/src/agents/cost/index.ts +0 -10
- package/src/agents/cost/parse.ts +0 -97
- package/src/agents/cost/pricing.ts +0 -59
- package/src/agents/cost/types.ts +0 -45
- package/src/agents/gemini/adapter.ts +0 -177
- package/src/agents/index.ts +0 -18
- package/src/agents/opencode/adapter.ts +0 -106
- package/src/agents/registry.ts +0 -136
- package/src/agents/shared/decompose.ts +0 -154
- package/src/agents/shared/model-resolution.ts +0 -43
- package/src/agents/shared/types-extended.ts +0 -164
- package/src/agents/shared/validation.ts +0 -69
- package/src/agents/shared/version-detection.ts +0 -109
- package/src/agents/types.ts +0 -205
- package/src/analyze/classifier.ts +0 -282
- package/src/analyze/index.ts +0 -16
- package/src/analyze/scanner.ts +0 -171
- package/src/analyze/types.ts +0 -51
- package/src/cli/accept.ts +0 -108
- package/src/cli/agents.ts +0 -87
- package/src/cli/analyze-parser.ts +0 -291
- package/src/cli/analyze.ts +0 -352
- package/src/cli/config-descriptions.ts +0 -219
- package/src/cli/config-diff.ts +0 -103
- package/src/cli/config-display.ts +0 -285
- package/src/cli/config-get.ts +0 -55
- package/src/cli/config.ts +0 -14
- package/src/cli/constitution.ts +0 -17
- package/src/cli/diagnose-analysis.ts +0 -159
- package/src/cli/diagnose-formatter.ts +0 -87
- package/src/cli/diagnose.ts +0 -203
- package/src/cli/generate.ts +0 -250
- package/src/cli/index.ts +0 -42
- package/src/cli/init-context.ts +0 -405
- package/src/cli/init-detect.ts +0 -303
- package/src/cli/init.ts +0 -296
- package/src/cli/interact.ts +0 -295
- package/src/cli/plan.ts +0 -509
- package/src/cli/plugins.ts +0 -122
- package/src/cli/prompts-export.ts +0 -58
- package/src/cli/prompts-init.ts +0 -200
- package/src/cli/prompts-main.ts +0 -183
- package/src/cli/prompts-shared.ts +0 -70
- package/src/cli/prompts-tdd.ts +0 -88
- package/src/cli/prompts.ts +0 -17
- package/src/cli/runs.ts +0 -174
- package/src/cli/status-cost.ts +0 -151
- package/src/cli/status-features.ts +0 -405
- package/src/cli/status.ts +0 -13
- package/src/commands/common.ts +0 -171
- package/src/commands/diagnose.ts +0 -17
- package/src/commands/index.ts +0 -9
- package/src/commands/logs-formatter.ts +0 -201
- package/src/commands/logs-reader.ts +0 -171
- package/src/commands/logs.ts +0 -103
- package/src/commands/precheck.ts +0 -86
- package/src/commands/runs.ts +0 -220
- package/src/commands/unlock.ts +0 -96
- package/src/config/defaults.ts +0 -218
- package/src/config/index.ts +0 -22
- package/src/config/loader.ts +0 -143
- package/src/config/merge.ts +0 -106
- package/src/config/merger.ts +0 -147
- package/src/config/path-security.ts +0 -121
- package/src/config/paths.ts +0 -27
- package/src/config/permissions.ts +0 -63
- package/src/config/runtime-types.ts +0 -522
- package/src/config/schema-types.ts +0 -53
- package/src/config/schema.ts +0 -60
- package/src/config/schemas.ts +0 -426
- package/src/config/test-strategy.ts +0 -71
- package/src/config/types.ts +0 -57
- package/src/config/validate.ts +0 -103
- package/src/constitution/generator.ts +0 -158
- package/src/constitution/generators/aider.ts +0 -41
- package/src/constitution/generators/claude.ts +0 -35
- package/src/constitution/generators/cursor.ts +0 -36
- package/src/constitution/generators/opencode.ts +0 -38
- package/src/constitution/generators/types.ts +0 -33
- package/src/constitution/generators/windsurf.ts +0 -36
- package/src/constitution/index.ts +0 -11
- package/src/constitution/loader.ts +0 -121
- package/src/constitution/types.ts +0 -31
- package/src/context/auto-detect.ts +0 -228
- package/src/context/builder.ts +0 -299
- package/src/context/elements.ts +0 -122
- package/src/context/formatter.ts +0 -107
- package/src/context/generator.ts +0 -343
- package/src/context/generators/aider.ts +0 -34
- package/src/context/generators/claude.ts +0 -28
- package/src/context/generators/codex.ts +0 -28
- package/src/context/generators/cursor.ts +0 -28
- package/src/context/generators/gemini.ts +0 -28
- package/src/context/generators/opencode.ts +0 -30
- package/src/context/generators/windsurf.ts +0 -28
- package/src/context/greenfield.ts +0 -114
- package/src/context/index.ts +0 -34
- package/src/context/injector.ts +0 -279
- package/src/context/parent-context.ts +0 -39
- package/src/context/test-scanner.ts +0 -370
- package/src/context/types.ts +0 -98
- package/src/decompose/apply.ts +0 -50
- package/src/decompose/builder.ts +0 -181
- package/src/decompose/index.ts +0 -8
- package/src/decompose/sections/codebase.ts +0 -26
- package/src/decompose/sections/constraints.ts +0 -32
- package/src/decompose/sections/index.ts +0 -4
- package/src/decompose/sections/sibling-stories.ts +0 -25
- package/src/decompose/sections/target-story.ts +0 -31
- package/src/decompose/types.ts +0 -55
- package/src/decompose/validators/complexity.ts +0 -45
- package/src/decompose/validators/coverage.ts +0 -134
- package/src/decompose/validators/dependency.ts +0 -91
- package/src/decompose/validators/index.ts +0 -35
- package/src/decompose/validators/overlap.ts +0 -128
- package/src/errors.ts +0 -67
- package/src/execution/batching.ts +0 -157
- package/src/execution/crash-heartbeat.ts +0 -77
- package/src/execution/crash-recovery.ts +0 -79
- package/src/execution/crash-signals.ts +0 -165
- package/src/execution/crash-writer.ts +0 -154
- package/src/execution/deferred-review.ts +0 -105
- package/src/execution/dry-run.ts +0 -81
- package/src/execution/escalation/escalation.ts +0 -46
- package/src/execution/escalation/index.ts +0 -13
- package/src/execution/escalation/tier-escalation.ts +0 -346
- package/src/execution/escalation/tier-outcome.ts +0 -143
- package/src/execution/executor-types.ts +0 -73
- package/src/execution/helpers.ts +0 -38
- package/src/execution/index.ts +0 -27
- package/src/execution/iteration-runner.ts +0 -160
- package/src/execution/lifecycle/acceptance-loop.ts +0 -309
- package/src/execution/lifecycle/headless-formatter.ts +0 -83
- package/src/execution/lifecycle/index.ts +0 -11
- package/src/execution/lifecycle/parallel-lifecycle.ts +0 -101
- package/src/execution/lifecycle/precheck-runner.ts +0 -140
- package/src/execution/lifecycle/run-cleanup.ts +0 -81
- package/src/execution/lifecycle/run-completion.ts +0 -247
- package/src/execution/lifecycle/run-initialization.ts +0 -187
- package/src/execution/lifecycle/run-regression.ts +0 -305
- package/src/execution/lifecycle/run-setup.ts +0 -240
- package/src/execution/lifecycle/story-size-prompts.ts +0 -123
- package/src/execution/lock.ts +0 -129
- package/src/execution/parallel-coordinator.ts +0 -281
- package/src/execution/parallel-executor-rectification-pass.ts +0 -117
- package/src/execution/parallel-executor-rectify.ts +0 -136
- package/src/execution/parallel-executor.ts +0 -330
- package/src/execution/parallel-worker.ts +0 -149
- package/src/execution/parallel.ts +0 -13
- package/src/execution/pid-registry.ts +0 -275
- package/src/execution/pipeline-result-handler.ts +0 -221
- package/src/execution/progress.ts +0 -27
- package/src/execution/queue-handler.ts +0 -109
- package/src/execution/runner-completion.ts +0 -171
- package/src/execution/runner-execution.ts +0 -243
- package/src/execution/runner-setup.ts +0 -86
- package/src/execution/runner.ts +0 -265
- package/src/execution/sequential-executor.ts +0 -219
- package/src/execution/status-file.ts +0 -264
- package/src/execution/status-writer.ts +0 -181
- package/src/execution/story-context.ts +0 -266
- package/src/execution/story-selector.ts +0 -76
- package/src/execution/test-output-parser.ts +0 -14
- package/src/execution/timeout-handler.ts +0 -100
- package/src/hooks/index.ts +0 -2
- package/src/hooks/runner.ts +0 -280
- package/src/hooks/types.ts +0 -79
- package/src/interaction/chain.ts +0 -170
- package/src/interaction/index.ts +0 -61
- package/src/interaction/init.ts +0 -84
- package/src/interaction/plugins/auto.ts +0 -243
- package/src/interaction/plugins/cli.ts +0 -300
- package/src/interaction/plugins/telegram.ts +0 -384
- package/src/interaction/plugins/webhook.ts +0 -286
- package/src/interaction/state.ts +0 -171
- package/src/interaction/triggers.ts +0 -250
- package/src/interaction/types.ts +0 -170
- package/src/logger/formatters.ts +0 -84
- package/src/logger/index.ts +0 -16
- package/src/logger/logger.ts +0 -296
- package/src/logger/types.ts +0 -48
- package/src/logging/formatter.ts +0 -355
- package/src/logging/index.ts +0 -22
- package/src/logging/types.ts +0 -93
- package/src/metrics/aggregator.ts +0 -191
- package/src/metrics/index.ts +0 -14
- package/src/metrics/tracker.ts +0 -200
- package/src/metrics/types.ts +0 -115
- package/src/optimizer/index.ts +0 -63
- package/src/optimizer/noop.optimizer.ts +0 -24
- package/src/optimizer/rule-based.optimizer.ts +0 -248
- package/src/optimizer/types.ts +0 -53
- package/src/pipeline/event-bus.ts +0 -297
- package/src/pipeline/events.ts +0 -130
- package/src/pipeline/index.ts +0 -19
- package/src/pipeline/runner.ts +0 -149
- package/src/pipeline/stages/acceptance-setup.ts +0 -144
- package/src/pipeline/stages/acceptance.ts +0 -215
- package/src/pipeline/stages/autofix.ts +0 -262
- package/src/pipeline/stages/completion.ts +0 -110
- package/src/pipeline/stages/constitution.ts +0 -63
- package/src/pipeline/stages/context.ts +0 -122
- package/src/pipeline/stages/execution.ts +0 -359
- package/src/pipeline/stages/index.ts +0 -86
- package/src/pipeline/stages/optimizer.ts +0 -74
- package/src/pipeline/stages/prompt.ts +0 -79
- package/src/pipeline/stages/queue-check.ts +0 -103
- package/src/pipeline/stages/rectify.ts +0 -101
- package/src/pipeline/stages/regression.ts +0 -99
- package/src/pipeline/stages/review.ts +0 -94
- package/src/pipeline/stages/routing.ts +0 -276
- package/src/pipeline/stages/verify.ts +0 -286
- package/src/pipeline/subscribers/events-writer.ts +0 -135
- package/src/pipeline/subscribers/hooks.ts +0 -179
- package/src/pipeline/subscribers/interaction.ts +0 -103
- package/src/pipeline/subscribers/registry.ts +0 -73
- package/src/pipeline/subscribers/reporters.ts +0 -174
- package/src/pipeline/types.ts +0 -220
- package/src/plugins/extensions.ts +0 -225
- package/src/plugins/index.ts +0 -33
- package/src/plugins/loader.ts +0 -352
- package/src/plugins/plugin-logger.ts +0 -41
- package/src/plugins/registry.ts +0 -168
- package/src/plugins/types.ts +0 -206
- package/src/plugins/validator.ts +0 -352
- package/src/prd/index.ts +0 -220
- package/src/prd/schema.ts +0 -268
- package/src/prd/types.ts +0 -273
- package/src/prd/validate.ts +0 -41
- package/src/precheck/checks-agents.ts +0 -63
- package/src/precheck/checks-blockers.ts +0 -23
- package/src/precheck/checks-cli.ts +0 -68
- package/src/precheck/checks-config.ts +0 -102
- package/src/precheck/checks-git.ts +0 -117
- package/src/precheck/checks-system.ts +0 -101
- package/src/precheck/checks-warnings.ts +0 -221
- package/src/precheck/checks.ts +0 -36
- package/src/precheck/index.ts +0 -374
- package/src/precheck/story-size-gate.ts +0 -144
- package/src/precheck/types.ts +0 -31
- package/src/prompts/builder.ts +0 -166
- package/src/prompts/index.ts +0 -2
- package/src/prompts/loader.ts +0 -43
- package/src/prompts/sections/conventions.ts +0 -19
- package/src/prompts/sections/hermetic.ts +0 -41
- package/src/prompts/sections/index.ts +0 -12
- package/src/prompts/sections/isolation.ts +0 -70
- package/src/prompts/sections/role-task.ts +0 -182
- package/src/prompts/sections/story.ts +0 -55
- package/src/prompts/sections/verdict.ts +0 -70
- package/src/prompts/types.ts +0 -21
- package/src/queue/index.ts +0 -2
- package/src/queue/manager.ts +0 -254
- package/src/queue/types.ts +0 -54
- package/src/review/index.ts +0 -8
- package/src/review/orchestrator.ts +0 -154
- package/src/review/runner.ts +0 -303
- package/src/review/types.ts +0 -70
- package/src/routing/batch-route.ts +0 -35
- package/src/routing/builder.ts +0 -81
- package/src/routing/chain.ts +0 -75
- package/src/routing/content-hash.ts +0 -25
- package/src/routing/index.ts +0 -20
- package/src/routing/loader.ts +0 -62
- package/src/routing/router.ts +0 -305
- package/src/routing/strategies/adaptive.ts +0 -215
- package/src/routing/strategies/index.ts +0 -8
- package/src/routing/strategies/keyword.ts +0 -180
- package/src/routing/strategies/llm-prompts.ts +0 -224
- package/src/routing/strategies/llm.ts +0 -320
- package/src/routing/strategies/manual.ts +0 -50
- package/src/routing/strategy.ts +0 -102
- package/src/tdd/cleanup.ts +0 -120
- package/src/tdd/index.ts +0 -22
- package/src/tdd/isolation.ts +0 -117
- package/src/tdd/orchestrator.ts +0 -406
- package/src/tdd/prompts.ts +0 -40
- package/src/tdd/rectification-gate.ts +0 -274
- package/src/tdd/session-runner.ts +0 -263
- package/src/tdd/types.ts +0 -84
- package/src/tdd/verdict-reader.ts +0 -266
- package/src/tdd/verdict.ts +0 -152
- package/src/tui/App.tsx +0 -265
- package/src/tui/components/AgentPanel.tsx +0 -75
- package/src/tui/components/CostOverlay.tsx +0 -118
- package/src/tui/components/HelpOverlay.tsx +0 -107
- package/src/tui/components/StatusBar.tsx +0 -63
- package/src/tui/components/StoriesPanel.tsx +0 -177
- package/src/tui/hooks/useKeyboard.ts +0 -142
- package/src/tui/hooks/useLayout.ts +0 -137
- package/src/tui/hooks/usePipelineEvents.ts +0 -183
- package/src/tui/hooks/usePty.ts +0 -189
- package/src/tui/index.tsx +0 -38
- package/src/tui/types.ts +0 -76
- package/src/utils/errors.ts +0 -12
- package/src/utils/git.ts +0 -245
- package/src/utils/json-file.ts +0 -72
- package/src/utils/log-test-output.ts +0 -25
- package/src/utils/path-security.ts +0 -73
- package/src/utils/queue-writer.ts +0 -54
- package/src/verification/crash-detector.ts +0 -34
- package/src/verification/executor.ts +0 -250
- package/src/verification/index.ts +0 -12
- package/src/verification/orchestrator-types.ts +0 -154
- package/src/verification/orchestrator.ts +0 -76
- package/src/verification/parser.ts +0 -220
- package/src/verification/rectification-loop.ts +0 -172
- package/src/verification/rectification.ts +0 -108
- package/src/verification/runners.ts +0 -129
- package/src/verification/smart-runner.ts +0 -307
- package/src/verification/strategies/acceptance.ts +0 -136
- package/src/verification/strategies/regression.ts +0 -90
- package/src/verification/strategies/scoped.ts +0 -154
- package/src/verification/types.ts +0 -117
- package/src/version.ts +0 -40
- package/src/worktree/dispatcher.ts +0 -6
- package/src/worktree/index.ts +0 -2
- package/src/worktree/manager.ts +0 -193
- package/src/worktree/merge.ts +0 -302
- package/src/worktree/types.ts +0 -4
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* Pipeline Event Bus (ADR-005, Phase 1)
|
|
4
|
-
*
|
|
5
|
-
* Typed publish/subscribe event bus for pipeline lifecycle events.
|
|
6
|
-
* Replaces 20+ scattered fireHook() calls and 5+ getReporters() calls
|
|
7
|
-
* with a single wiring point. Subscribers are registered once at startup.
|
|
8
|
-
*
|
|
9
|
-
* Phase 1: bus is created and exported. Existing hook/reporter calls
|
|
10
|
-
* are NOT replaced until Phase 3 (subscriber consolidation).
|
|
11
|
-
*
|
|
12
|
-
* Design principles:
|
|
13
|
-
* - Synchronous publish (fire-and-forget) — subscribers run async but bus
|
|
14
|
-
* does not await them, matching current fireHook() behavior
|
|
15
|
-
* - Typed events via discriminated union
|
|
16
|
-
* - Error isolation: one subscriber failure doesn't break others
|
|
17
|
-
* - Zero dependencies on pipeline internals
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { getLogger } from "../logger";
|
|
21
|
-
import type { UserStory } from "../prd";
|
|
22
|
-
import type { VerifyResult } from "../verification/orchestrator-types";
|
|
23
|
-
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
// Event types
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
|
|
28
|
-
export interface StoryStartedEvent {
|
|
29
|
-
type: "story:started";
|
|
30
|
-
storyId: string;
|
|
31
|
-
story: UserStory;
|
|
32
|
-
workdir: string;
|
|
33
|
-
/** Optional: passed by executor for hook subscriber */
|
|
34
|
-
modelTier?: string;
|
|
35
|
-
agent?: string;
|
|
36
|
-
iteration?: number;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface StoryCompletedEvent {
|
|
40
|
-
type: "story:completed";
|
|
41
|
-
storyId: string;
|
|
42
|
-
story: UserStory;
|
|
43
|
-
passed: boolean;
|
|
44
|
-
runElapsedMs: number;
|
|
45
|
-
/** Optional: passed by executor/stage for hook/reporter subscribers */
|
|
46
|
-
cost?: number;
|
|
47
|
-
modelTier?: string;
|
|
48
|
-
testStrategy?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface StoryFailedEvent {
|
|
52
|
-
type: "story:failed";
|
|
53
|
-
storyId: string;
|
|
54
|
-
story: UserStory;
|
|
55
|
-
reason: string;
|
|
56
|
-
countsTowardEscalation: boolean;
|
|
57
|
-
/** Optional: passed by executor for interaction subscriber */
|
|
58
|
-
feature?: string;
|
|
59
|
-
attempts?: number;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface VerifyCompletedEvent {
|
|
63
|
-
type: "verify:completed";
|
|
64
|
-
storyId: string;
|
|
65
|
-
result: VerifyResult;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface RectifyStartedEvent {
|
|
69
|
-
type: "rectify:started";
|
|
70
|
-
storyId: string;
|
|
71
|
-
attempt: number;
|
|
72
|
-
testOutput: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export interface RectifyCompletedEvent {
|
|
76
|
-
type: "rectify:completed";
|
|
77
|
-
storyId: string;
|
|
78
|
-
attempt: number;
|
|
79
|
-
fixed: boolean;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface AutofixStartedEvent {
|
|
83
|
-
type: "autofix:started";
|
|
84
|
-
storyId: string;
|
|
85
|
-
command: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface AutofixCompletedEvent {
|
|
89
|
-
type: "autofix:completed";
|
|
90
|
-
storyId: string;
|
|
91
|
-
fixed: boolean;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export interface RegressionDetectedEvent {
|
|
95
|
-
type: "regression:detected";
|
|
96
|
-
storyId: string;
|
|
97
|
-
failedTests: number;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export interface RunCompletedEvent {
|
|
101
|
-
type: "run:completed";
|
|
102
|
-
totalStories: number;
|
|
103
|
-
passedStories: number;
|
|
104
|
-
failedStories: number;
|
|
105
|
-
durationMs: number;
|
|
106
|
-
totalCost?: number;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface HumanReviewRequestedEvent {
|
|
110
|
-
type: "human-review:requested";
|
|
111
|
-
storyId: string;
|
|
112
|
-
reason: string;
|
|
113
|
-
feature?: string;
|
|
114
|
-
attempts?: number;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export interface RunStartedEvent {
|
|
118
|
-
type: "run:started";
|
|
119
|
-
feature: string;
|
|
120
|
-
totalStories: number;
|
|
121
|
-
workdir: string;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export interface RunPausedEvent {
|
|
125
|
-
type: "run:paused";
|
|
126
|
-
reason: string;
|
|
127
|
-
storyId?: string;
|
|
128
|
-
cost: number;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export interface StoryPausedEvent {
|
|
132
|
-
type: "story:paused";
|
|
133
|
-
storyId: string;
|
|
134
|
-
reason: string;
|
|
135
|
-
cost: number;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export interface StoryDecomposedEvent {
|
|
139
|
-
type: "story:decomposed";
|
|
140
|
-
storyId: string;
|
|
141
|
-
story: UserStory;
|
|
142
|
-
subStoryCount: number;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface RunResumedEvent {
|
|
146
|
-
type: "run:resumed";
|
|
147
|
-
feature: string;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface RunErroredEvent {
|
|
151
|
-
type: "run:errored";
|
|
152
|
-
reason: string;
|
|
153
|
-
feature?: string;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/** Discriminated union of all pipeline events. */
|
|
157
|
-
export type PipelineEvent =
|
|
158
|
-
| StoryStartedEvent
|
|
159
|
-
| StoryCompletedEvent
|
|
160
|
-
| StoryFailedEvent
|
|
161
|
-
| VerifyCompletedEvent
|
|
162
|
-
| RectifyStartedEvent
|
|
163
|
-
| RectifyCompletedEvent
|
|
164
|
-
| AutofixStartedEvent
|
|
165
|
-
| AutofixCompletedEvent
|
|
166
|
-
| RegressionDetectedEvent
|
|
167
|
-
| RunCompletedEvent
|
|
168
|
-
| HumanReviewRequestedEvent
|
|
169
|
-
| RunStartedEvent
|
|
170
|
-
| RunPausedEvent
|
|
171
|
-
| StoryPausedEvent
|
|
172
|
-
| RunResumedEvent
|
|
173
|
-
| RunErroredEvent
|
|
174
|
-
| StoryDecomposedEvent;
|
|
175
|
-
|
|
176
|
-
export type PipelineEventType = PipelineEvent["type"];
|
|
177
|
-
|
|
178
|
-
// ---------------------------------------------------------------------------
|
|
179
|
-
// Subscriber types
|
|
180
|
-
// ---------------------------------------------------------------------------
|
|
181
|
-
|
|
182
|
-
export type EventSubscriber<T extends PipelineEvent = PipelineEvent> = (event: T) => void | Promise<void>;
|
|
183
|
-
|
|
184
|
-
type SubscriberMap = Map<string, EventSubscriber[]>;
|
|
185
|
-
|
|
186
|
-
// ---------------------------------------------------------------------------
|
|
187
|
-
// Bus implementation
|
|
188
|
-
// ---------------------------------------------------------------------------
|
|
189
|
-
|
|
190
|
-
export class PipelineEventBus {
|
|
191
|
-
private readonly subscribers: SubscriberMap = new Map();
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Subscribe to a specific event type.
|
|
195
|
-
*
|
|
196
|
-
* @returns Unsubscribe function
|
|
197
|
-
*/
|
|
198
|
-
on<T extends PipelineEventType>(
|
|
199
|
-
eventType: T,
|
|
200
|
-
subscriber: EventSubscriber<Extract<PipelineEvent, { type: T }>>,
|
|
201
|
-
): () => void {
|
|
202
|
-
const list = this.subscribers.get(eventType) ?? [];
|
|
203
|
-
list.push(subscriber as EventSubscriber);
|
|
204
|
-
this.subscribers.set(eventType, list);
|
|
205
|
-
|
|
206
|
-
return () => {
|
|
207
|
-
const current = this.subscribers.get(eventType) ?? [];
|
|
208
|
-
this.subscribers.set(
|
|
209
|
-
eventType,
|
|
210
|
-
current.filter((s) => s !== subscriber),
|
|
211
|
-
);
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Subscribe to all events.
|
|
217
|
-
*
|
|
218
|
-
* @returns Unsubscribe function
|
|
219
|
-
*/
|
|
220
|
-
onAll(subscriber: EventSubscriber): () => void {
|
|
221
|
-
const list = this.subscribers.get("*") ?? [];
|
|
222
|
-
list.push(subscriber);
|
|
223
|
-
this.subscribers.set("*", list);
|
|
224
|
-
|
|
225
|
-
return () => {
|
|
226
|
-
const current = this.subscribers.get("*") ?? [];
|
|
227
|
-
this.subscribers.set(
|
|
228
|
-
"*",
|
|
229
|
-
current.filter((s) => s !== subscriber),
|
|
230
|
-
);
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Publish an event to all matching subscribers.
|
|
236
|
-
*
|
|
237
|
-
* Fire-and-forget: async subscribers are not awaited.
|
|
238
|
-
* Subscriber errors are caught and logged — one failure doesn't block others.
|
|
239
|
-
*/
|
|
240
|
-
emit(event: PipelineEvent): void {
|
|
241
|
-
const logger = getLogger();
|
|
242
|
-
|
|
243
|
-
const specific = this.subscribers.get(event.type) ?? [];
|
|
244
|
-
const all = this.subscribers.get("*") ?? [];
|
|
245
|
-
const targets = [...specific, ...all];
|
|
246
|
-
|
|
247
|
-
for (const sub of targets) {
|
|
248
|
-
try {
|
|
249
|
-
const result = sub(event);
|
|
250
|
-
if (result instanceof Promise) {
|
|
251
|
-
result.catch((err) => {
|
|
252
|
-
logger.warn("event-bus", `Subscriber error on ${event.type}`, { error: String(err) });
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
} catch (err) {
|
|
256
|
-
logger.warn("event-bus", `Subscriber threw on ${event.type}`, { error: String(err) });
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Publish an event and await all async subscribers.
|
|
263
|
-
*
|
|
264
|
-
* Use this when you need to ensure subscribers have completed before proceeding
|
|
265
|
-
* (e.g., for interaction subscribers that block on human input).
|
|
266
|
-
*/
|
|
267
|
-
async emitAsync(event: PipelineEvent): Promise<void> {
|
|
268
|
-
const logger = getLogger();
|
|
269
|
-
|
|
270
|
-
const specific = this.subscribers.get(event.type) ?? [];
|
|
271
|
-
const all = this.subscribers.get("*") ?? [];
|
|
272
|
-
const targets = [...specific, ...all];
|
|
273
|
-
|
|
274
|
-
await Promise.allSettled(
|
|
275
|
-
targets.map(async (sub) => {
|
|
276
|
-
try {
|
|
277
|
-
await sub(event);
|
|
278
|
-
} catch (err) {
|
|
279
|
-
logger.warn("event-bus", `Subscriber error on ${event.type}`, { error: String(err) });
|
|
280
|
-
}
|
|
281
|
-
}),
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/** Remove all subscribers (useful in tests). */
|
|
286
|
-
clear(): void {
|
|
287
|
-
this.subscribers.clear();
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/** Number of subscribers for a given event type. */
|
|
291
|
-
subscriberCount(eventType: PipelineEventType | "*"): number {
|
|
292
|
-
return (this.subscribers.get(eventType) ?? []).length;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/** Singleton pipeline event bus instance. */
|
|
297
|
-
export const pipelineEventBus = new PipelineEventBus();
|
package/src/pipeline/events.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pipeline Event Emitter
|
|
3
|
-
*
|
|
4
|
-
* Typed event emitter for TUI integration. Emits lifecycle events during
|
|
5
|
-
* pipeline execution so the TUI can display real-time progress.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { EventEmitter } from "node:events";
|
|
9
|
-
import type { UserStory } from "../prd/types";
|
|
10
|
-
import type { RoutingResult, StageResult } from "./types";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Summary of a completed run.
|
|
14
|
-
*/
|
|
15
|
-
export interface RunSummary {
|
|
16
|
-
/** Total number of stories processed */
|
|
17
|
-
storiesProcessed: number;
|
|
18
|
-
/** Number of stories completed successfully */
|
|
19
|
-
storiesCompleted: number;
|
|
20
|
-
/** Number of stories failed */
|
|
21
|
-
storiesFailed: number;
|
|
22
|
-
/** Number of stories skipped */
|
|
23
|
-
storiesSkipped: number;
|
|
24
|
-
/** Total cost in USD */
|
|
25
|
-
totalCost: number;
|
|
26
|
-
/** Total duration in milliseconds */
|
|
27
|
-
durationMs: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Pipeline event types matching v0.6 spec.
|
|
32
|
-
*
|
|
33
|
-
* Events:
|
|
34
|
-
* - story:start — Story execution begins
|
|
35
|
-
* - story:complete — Story execution ends (success/fail/skip)
|
|
36
|
-
* - story:escalate — Story escalated to higher tier
|
|
37
|
-
* - stage:enter — Pipeline stage starts
|
|
38
|
-
* - stage:exit — Pipeline stage finishes
|
|
39
|
-
* - run:complete — Full run completes
|
|
40
|
-
*/
|
|
41
|
-
export interface PipelineEvents {
|
|
42
|
-
"story:start": (story: UserStory, routing: RoutingResult) => void;
|
|
43
|
-
"story:complete": (story: UserStory, result: StageResult) => void;
|
|
44
|
-
"story:escalate": (story: UserStory, fromTier: string, toTier: string) => void;
|
|
45
|
-
"stage:enter": (stage: string, story: UserStory) => void;
|
|
46
|
-
"stage:exit": (stage: string, result: StageResult) => void;
|
|
47
|
-
"run:complete": (summary: RunSummary) => void;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Typed event emitter for pipeline events.
|
|
52
|
-
*
|
|
53
|
-
* Wraps Node.js EventEmitter with TypeScript types for pipeline lifecycle
|
|
54
|
-
* events. The TUI subscribes to these events to update UI state in real-time.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* const emitter = new PipelineEventEmitter();
|
|
59
|
-
*
|
|
60
|
-
* emitter.on('story:start', (story, routing) => {
|
|
61
|
-
* // Handle story start: ${story.id} with ${routing.modelTier}
|
|
62
|
-
* });
|
|
63
|
-
*
|
|
64
|
-
* emitter.on('story:complete', (story, result) => {
|
|
65
|
-
* // Handle story completion: ${story.id} - ${result.action}
|
|
66
|
-
* });
|
|
67
|
-
*
|
|
68
|
-
* // In pipeline runner:
|
|
69
|
-
* emitter.emit('story:start', story, routing);
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
export class PipelineEventEmitter {
|
|
73
|
-
private emitter = new EventEmitter();
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Subscribe to a pipeline event.
|
|
77
|
-
*
|
|
78
|
-
* @param event - Event name
|
|
79
|
-
* @param listener - Event handler
|
|
80
|
-
*/
|
|
81
|
-
on<E extends keyof PipelineEvents>(event: E, listener: PipelineEvents[E]): void {
|
|
82
|
-
this.emitter.on(event, listener as (...args: unknown[]) => void);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Subscribe to an event once (auto-unsubscribe after first emission).
|
|
87
|
-
*
|
|
88
|
-
* @param event - Event name
|
|
89
|
-
* @param listener - Event handler
|
|
90
|
-
*/
|
|
91
|
-
once<E extends keyof PipelineEvents>(event: E, listener: PipelineEvents[E]): void {
|
|
92
|
-
this.emitter.once(event, listener as (...args: unknown[]) => void);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Unsubscribe from an event.
|
|
97
|
-
*
|
|
98
|
-
* @param event - Event name
|
|
99
|
-
* @param listener - Event handler to remove
|
|
100
|
-
*/
|
|
101
|
-
off<E extends keyof PipelineEvents>(event: E, listener: PipelineEvents[E]): void {
|
|
102
|
-
this.emitter.off(event, listener as (...args: unknown[]) => void);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Emit a pipeline event.
|
|
107
|
-
*
|
|
108
|
-
* Called internally by the pipeline runner. External code should only
|
|
109
|
-
* subscribe to events, not emit them.
|
|
110
|
-
*
|
|
111
|
-
* @param event - Event name
|
|
112
|
-
* @param args - Event arguments
|
|
113
|
-
*/
|
|
114
|
-
emit<E extends keyof PipelineEvents>(event: E, ...args: Parameters<PipelineEvents[E]>): void {
|
|
115
|
-
this.emitter.emit(event, ...args);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Remove all listeners for a specific event or all events.
|
|
120
|
-
*
|
|
121
|
-
* @param event - Optional event name (if not provided, removes all listeners)
|
|
122
|
-
*/
|
|
123
|
-
removeAllListeners(event?: keyof PipelineEvents): void {
|
|
124
|
-
if (event) {
|
|
125
|
-
this.emitter.removeAllListeners(event);
|
|
126
|
-
} else {
|
|
127
|
-
this.emitter.removeAllListeners();
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
package/src/pipeline/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pipeline Module
|
|
3
|
-
*
|
|
4
|
-
* Composable stage-based execution pipeline.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export type {
|
|
8
|
-
PipelineContext,
|
|
9
|
-
PipelineStage,
|
|
10
|
-
StageResult,
|
|
11
|
-
StageAction,
|
|
12
|
-
RoutingResult,
|
|
13
|
-
} from "./types";
|
|
14
|
-
|
|
15
|
-
export { runPipeline } from "./runner";
|
|
16
|
-
export type { PipelineRunResult } from "./runner";
|
|
17
|
-
|
|
18
|
-
export { PipelineEventEmitter } from "./events";
|
|
19
|
-
export type { PipelineEvents, RunSummary } from "./events";
|
package/src/pipeline/runner.ts
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pipeline Runner
|
|
3
|
-
*
|
|
4
|
-
* Executes a sequence of pipeline stages, handling stage results and
|
|
5
|
-
* controlling the flow (continue/skip/fail/escalate/pause/retry).
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { getLogger } from "../logger";
|
|
9
|
-
import { errorMessage } from "../utils/errors";
|
|
10
|
-
import type { PipelineEventEmitter } from "./events";
|
|
11
|
-
import type { PipelineContext, PipelineStage, StageResult } from "./types";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Pipeline execution result.
|
|
15
|
-
*/
|
|
16
|
-
export interface PipelineRunResult {
|
|
17
|
-
/** Whether the pipeline completed successfully (reached the end) */
|
|
18
|
-
success: boolean;
|
|
19
|
-
/** Final action taken */
|
|
20
|
-
finalAction: "complete" | "skip" | "decomposed" | "fail" | "escalate" | "pause";
|
|
21
|
-
/** Reason for non-complete outcomes */
|
|
22
|
-
reason?: string;
|
|
23
|
-
/** Number of sub-stories created (only set when finalAction === "decomposed") */
|
|
24
|
-
subStoryCount?: number;
|
|
25
|
-
/** Stage where the pipeline stopped (if not completed) */
|
|
26
|
-
stoppedAtStage?: string;
|
|
27
|
-
/** Updated context after pipeline execution */
|
|
28
|
-
context: PipelineContext;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Maximum number of retries per stage to prevent infinite loops. */
|
|
32
|
-
export const MAX_STAGE_RETRIES = 5;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Run a pipeline of stages against a context.
|
|
36
|
-
*
|
|
37
|
-
* Supports a `retry` action that jumps back to a named stage (used by
|
|
38
|
-
* rectify/autofix stages). Retry count per target stage is tracked;
|
|
39
|
-
* exceeding MAX_STAGE_RETRIES converts to a `fail`.
|
|
40
|
-
*
|
|
41
|
-
* **Context Mutation:** This function mutates the input context in-place.
|
|
42
|
-
*/
|
|
43
|
-
export async function runPipeline(
|
|
44
|
-
stages: PipelineStage[],
|
|
45
|
-
context: PipelineContext,
|
|
46
|
-
eventEmitter?: PipelineEventEmitter,
|
|
47
|
-
): Promise<PipelineRunResult> {
|
|
48
|
-
const logger = getLogger();
|
|
49
|
-
const retryCountMap = new Map<string, number>();
|
|
50
|
-
let i = 0;
|
|
51
|
-
|
|
52
|
-
while (i < stages.length) {
|
|
53
|
-
const stage = stages[i];
|
|
54
|
-
|
|
55
|
-
// Skip disabled stages
|
|
56
|
-
if (!stage.enabled(context)) {
|
|
57
|
-
const reason = stage.skipReason?.(context) ?? "disabled";
|
|
58
|
-
logger.debug("pipeline", `Stage "${stage.name}" skipped (${reason})`);
|
|
59
|
-
i++;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
eventEmitter?.emit("stage:enter", stage.name, context.story);
|
|
64
|
-
|
|
65
|
-
let result: StageResult;
|
|
66
|
-
try {
|
|
67
|
-
result = await stage.execute(context);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
const failResult: StageResult = {
|
|
70
|
-
action: "fail",
|
|
71
|
-
reason: `Stage "${stage.name}" threw error: ${errorMessage(error)}`,
|
|
72
|
-
};
|
|
73
|
-
eventEmitter?.emit("stage:exit", stage.name, failResult);
|
|
74
|
-
return { success: false, finalAction: "fail", reason: failResult.reason, stoppedAtStage: stage.name, context };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
eventEmitter?.emit("stage:exit", stage.name, result);
|
|
78
|
-
|
|
79
|
-
switch (result.action) {
|
|
80
|
-
case "continue":
|
|
81
|
-
i++;
|
|
82
|
-
continue;
|
|
83
|
-
|
|
84
|
-
case "skip":
|
|
85
|
-
return { success: false, finalAction: "skip", reason: result.reason, stoppedAtStage: stage.name, context };
|
|
86
|
-
|
|
87
|
-
case "decomposed":
|
|
88
|
-
return {
|
|
89
|
-
success: false,
|
|
90
|
-
finalAction: "decomposed",
|
|
91
|
-
reason: result.reason,
|
|
92
|
-
subStoryCount: result.subStoryCount,
|
|
93
|
-
stoppedAtStage: stage.name,
|
|
94
|
-
context,
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
case "fail":
|
|
98
|
-
return { success: false, finalAction: "fail", reason: result.reason, stoppedAtStage: stage.name, context };
|
|
99
|
-
|
|
100
|
-
case "escalate":
|
|
101
|
-
return {
|
|
102
|
-
success: false,
|
|
103
|
-
finalAction: "escalate",
|
|
104
|
-
reason: result.reason ?? "Stage requested escalation to higher tier",
|
|
105
|
-
stoppedAtStage: stage.name,
|
|
106
|
-
context,
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
case "pause":
|
|
110
|
-
return { success: false, finalAction: "pause", reason: result.reason, stoppedAtStage: stage.name, context };
|
|
111
|
-
|
|
112
|
-
case "retry": {
|
|
113
|
-
const retries = (retryCountMap.get(result.fromStage) ?? 0) + 1;
|
|
114
|
-
if (retries > MAX_STAGE_RETRIES) {
|
|
115
|
-
logger.warn("pipeline", `Stage retry limit reached for "${result.fromStage}" (max ${MAX_STAGE_RETRIES})`);
|
|
116
|
-
return {
|
|
117
|
-
success: false,
|
|
118
|
-
finalAction: "fail",
|
|
119
|
-
reason: `Stage "${stage.name}" exceeded max retries (${MAX_STAGE_RETRIES}) for "${result.fromStage}"`,
|
|
120
|
-
stoppedAtStage: stage.name,
|
|
121
|
-
context,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
retryCountMap.set(result.fromStage, retries);
|
|
125
|
-
const targetIndex = stages.findIndex((s) => s.name === result.fromStage);
|
|
126
|
-
if (targetIndex === -1) {
|
|
127
|
-
logger.warn("pipeline", `Retry target stage "${result.fromStage}" not found — escalating`);
|
|
128
|
-
return {
|
|
129
|
-
success: false,
|
|
130
|
-
finalAction: "escalate",
|
|
131
|
-
reason: `Retry target stage "${result.fromStage}" not found`,
|
|
132
|
-
stoppedAtStage: stage.name,
|
|
133
|
-
context,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
logger.debug("pipeline", `Retrying from stage "${result.fromStage}" (attempt ${retries}/${MAX_STAGE_RETRIES})`);
|
|
137
|
-
i = targetIndex;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
default: {
|
|
142
|
-
const _exhaustive: never = result;
|
|
143
|
-
throw new Error(`Unknown stage action: ${JSON.stringify(_exhaustive)}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return { success: true, finalAction: "complete", context };
|
|
149
|
-
}
|