@generacy-ai/orchestrator 0.6.0 → 0.8.0
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/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +32 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +436 -7
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/launcher/agent-launcher.d.ts +15 -16
- package/dist/launcher/agent-launcher.d.ts.map +1 -1
- package/dist/launcher/agent-launcher.js +54 -23
- package/dist/launcher/agent-launcher.js.map +1 -1
- package/dist/launcher/constants.d.ts +5 -0
- package/dist/launcher/constants.d.ts.map +1 -0
- package/dist/launcher/constants.js +5 -0
- package/dist/launcher/constants.js.map +1 -0
- package/dist/launcher/errors.d.ts +15 -0
- package/dist/launcher/errors.d.ts.map +1 -0
- package/dist/launcher/errors.js +25 -0
- package/dist/launcher/errors.js.map +1 -0
- package/dist/launcher/generic-subprocess-plugin.d.ts +1 -0
- package/dist/launcher/generic-subprocess-plugin.d.ts.map +1 -1
- package/dist/launcher/generic-subprocess-plugin.js +2 -0
- package/dist/launcher/generic-subprocess-plugin.js.map +1 -1
- package/dist/launcher/index.d.ts +2 -1
- package/dist/launcher/index.d.ts.map +1 -1
- package/dist/launcher/index.js +1 -0
- package/dist/launcher/index.js.map +1 -1
- package/dist/launcher/types.d.ts +81 -4
- package/dist/launcher/types.d.ts.map +1 -1
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +5 -0
- package/dist/routes/health.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +130 -26
- package/dist/server.js.map +1 -1
- package/dist/services/base-advance-monitor-service.d.ts +78 -0
- package/dist/services/base-advance-monitor-service.d.ts.map +1 -0
- package/dist/services/base-advance-monitor-service.js +233 -0
- package/dist/services/base-advance-monitor-service.js.map +1 -0
- package/dist/services/boot-resume-service.d.ts +19 -0
- package/dist/services/boot-resume-service.d.ts.map +1 -0
- package/dist/services/boot-resume-service.js +87 -0
- package/dist/services/boot-resume-service.js.map +1 -0
- package/dist/services/epic-completion-monitor-service.d.ts.map +1 -1
- package/dist/services/epic-completion-monitor-service.js +2 -0
- package/dist/services/epic-completion-monitor-service.js.map +1 -1
- package/dist/services/in-memory-queue-adapter.d.ts +4 -0
- package/dist/services/in-memory-queue-adapter.d.ts.map +1 -1
- package/dist/services/in-memory-queue-adapter.js +30 -3
- package/dist/services/in-memory-queue-adapter.js.map +1 -1
- package/dist/services/label-monitor-service.d.ts +3 -3
- package/dist/services/label-monitor-service.d.ts.map +1 -1
- package/dist/services/label-monitor-service.js +58 -41
- package/dist/services/label-monitor-service.js.map +1 -1
- package/dist/services/label-sync-service.d.ts.map +1 -1
- package/dist/services/label-sync-service.js +45 -10
- package/dist/services/label-sync-service.js.map +1 -1
- package/dist/services/merge-conflict-monitor-service.d.ts +73 -0
- package/dist/services/merge-conflict-monitor-service.d.ts.map +1 -0
- package/dist/services/merge-conflict-monitor-service.js +295 -0
- package/dist/services/merge-conflict-monitor-service.js.map +1 -0
- package/dist/services/orchestrator-version.d.ts +2 -0
- package/dist/services/orchestrator-version.d.ts.map +1 -0
- package/dist/services/orchestrator-version.js +23 -0
- package/dist/services/orchestrator-version.js.map +1 -0
- package/dist/services/phase-tracker-service.d.ts +10 -0
- package/dist/services/phase-tracker-service.d.ts.map +1 -1
- package/dist/services/phase-tracker-service.js +38 -0
- package/dist/services/phase-tracker-service.js.map +1 -1
- package/dist/services/post-activation-dispatch.d.ts +18 -0
- package/dist/services/post-activation-dispatch.d.ts.map +1 -0
- package/dist/services/post-activation-dispatch.js +30 -0
- package/dist/services/post-activation-dispatch.js.map +1 -0
- package/dist/services/post-activation-retry.d.ts +3 -0
- package/dist/services/post-activation-retry.d.ts.map +1 -1
- package/dist/services/post-activation-retry.js +34 -2
- package/dist/services/post-activation-retry.js.map +1 -1
- package/dist/services/pr-feedback-monitor-service.d.ts +13 -4
- package/dist/services/pr-feedback-monitor-service.d.ts.map +1 -1
- package/dist/services/pr-feedback-monitor-service.js +212 -26
- package/dist/services/pr-feedback-monitor-service.js.map +1 -1
- package/dist/services/redis-queue-adapter.d.ts +4 -0
- package/dist/services/redis-queue-adapter.d.ts.map +1 -1
- package/dist/services/redis-queue-adapter.js +90 -10
- package/dist/services/redis-queue-adapter.js.map +1 -1
- package/dist/services/worker-dispatcher.d.ts +14 -2
- package/dist/services/worker-dispatcher.d.ts.map +1 -1
- package/dist/services/worker-dispatcher.js +55 -2
- package/dist/services/worker-dispatcher.js.map +1 -1
- package/dist/types/api.d.ts +3 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/api.js +1 -0
- package/dist/types/api.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/monitor.d.ts +72 -4
- package/dist/types/monitor.d.ts.map +1 -1
- package/dist/worker/base-merge.d.ts +54 -0
- package/dist/worker/base-merge.d.ts.map +1 -0
- package/dist/worker/base-merge.js +99 -0
- package/dist/worker/base-merge.js.map +1 -0
- package/dist/worker/clarification-markers.d.ts +29 -0
- package/dist/worker/clarification-markers.d.ts.map +1 -0
- package/dist/worker/clarification-markers.js +44 -0
- package/dist/worker/clarification-markers.js.map +1 -0
- package/dist/worker/clarification-poster.d.ts.map +1 -1
- package/dist/worker/clarification-poster.js +266 -25
- package/dist/worker/clarification-poster.js.map +1 -1
- package/dist/worker/claude-cli-worker.d.ts +21 -2
- package/dist/worker/claude-cli-worker.d.ts.map +1 -1
- package/dist/worker/claude-cli-worker.js +150 -4
- package/dist/worker/claude-cli-worker.js.map +1 -1
- package/dist/worker/cli-spawner.d.ts +4 -0
- package/dist/worker/cli-spawner.d.ts.map +1 -1
- package/dist/worker/cli-spawner.js +53 -7
- package/dist/worker/cli-spawner.js.map +1 -1
- package/dist/worker/config.d.ts +420 -8
- package/dist/worker/config.d.ts.map +1 -1
- package/dist/worker/config.js +179 -2
- package/dist/worker/config.js.map +1 -1
- package/dist/worker/evidence-hash.d.ts +32 -0
- package/dist/worker/evidence-hash.d.ts.map +1 -0
- package/dist/worker/evidence-hash.js +139 -0
- package/dist/worker/evidence-hash.js.map +1 -0
- package/dist/worker/handler-outcome-assertion.d.ts +38 -0
- package/dist/worker/handler-outcome-assertion.d.ts.map +1 -0
- package/dist/worker/handler-outcome-assertion.js +58 -0
- package/dist/worker/handler-outcome-assertion.js.map +1 -0
- package/dist/worker/handler-outcome.d.ts +50 -0
- package/dist/worker/handler-outcome.d.ts.map +1 -0
- package/dist/worker/handler-outcome.js +2 -0
- package/dist/worker/handler-outcome.js.map +1 -0
- package/dist/worker/label-manager.d.ts +58 -2
- package/dist/worker/label-manager.d.ts.map +1 -1
- package/dist/worker/label-manager.js +225 -27
- package/dist/worker/label-manager.js.map +1 -1
- package/dist/worker/merge-conflict-handler.d.ts +141 -0
- package/dist/worker/merge-conflict-handler.d.ts.map +1 -0
- package/dist/worker/merge-conflict-handler.js +642 -0
- package/dist/worker/merge-conflict-handler.js.map +1 -0
- package/dist/worker/merge-conflict-prompt.d.ts +35 -0
- package/dist/worker/merge-conflict-prompt.d.ts.map +1 -0
- package/dist/worker/merge-conflict-prompt.js +71 -0
- package/dist/worker/merge-conflict-prompt.js.map +1 -0
- package/dist/worker/merge-conflict-remedy.d.ts +42 -0
- package/dist/worker/merge-conflict-remedy.d.ts.map +1 -0
- package/dist/worker/merge-conflict-remedy.js +28 -0
- package/dist/worker/merge-conflict-remedy.js.map +1 -0
- package/dist/worker/output-tail-synthesis.d.ts +15 -0
- package/dist/worker/output-tail-synthesis.d.ts.map +1 -0
- package/dist/worker/output-tail-synthesis.js +25 -0
- package/dist/worker/output-tail-synthesis.js.map +1 -0
- package/dist/worker/output-tail.d.ts +13 -0
- package/dist/worker/output-tail.d.ts.map +1 -0
- package/dist/worker/output-tail.js +31 -0
- package/dist/worker/output-tail.js.map +1 -0
- package/dist/worker/pause-context.d.ts +30 -0
- package/dist/worker/pause-context.d.ts.map +1 -0
- package/dist/worker/pause-context.js +98 -0
- package/dist/worker/pause-context.js.map +1 -0
- package/dist/worker/phase-loop.d.ts +66 -0
- package/dist/worker/phase-loop.d.ts.map +1 -1
- package/dist/worker/phase-loop.js +329 -30
- package/dist/worker/phase-loop.js.map +1 -1
- package/dist/worker/pr-feedback-handler.d.ts +46 -46
- package/dist/worker/pr-feedback-handler.d.ts.map +1 -1
- package/dist/worker/pr-feedback-handler.js +286 -108
- package/dist/worker/pr-feedback-handler.js.map +1 -1
- package/dist/worker/pr-manager.d.ts +5 -0
- package/dist/worker/pr-manager.d.ts.map +1 -1
- package/dist/worker/pr-manager.js +7 -0
- package/dist/worker/pr-manager.js.map +1 -1
- package/dist/worker/product-diff.d.ts +39 -0
- package/dist/worker/product-diff.d.ts.map +1 -0
- package/dist/worker/product-diff.js +43 -0
- package/dist/worker/product-diff.js.map +1 -0
- package/dist/worker/provisioning-failure.d.ts +14 -0
- package/dist/worker/provisioning-failure.d.ts.map +1 -0
- package/dist/worker/provisioning-failure.js +2 -0
- package/dist/worker/provisioning-failure.js.map +1 -0
- package/dist/worker/repo-checkout.d.ts +14 -0
- package/dist/worker/repo-checkout.d.ts.map +1 -1
- package/dist/worker/repo-checkout.js +19 -1
- package/dist/worker/repo-checkout.js.map +1 -1
- package/dist/worker/stage-comment-manager.d.ts +42 -1
- package/dist/worker/stage-comment-manager.d.ts.map +1 -1
- package/dist/worker/stage-comment-manager.js +205 -1
- package/dist/worker/stage-comment-manager.js.map +1 -1
- package/dist/worker/terminal-label-op-error.d.ts +23 -0
- package/dist/worker/terminal-label-op-error.d.ts.map +1 -0
- package/dist/worker/terminal-label-op-error.js +27 -0
- package/dist/worker/terminal-label-op-error.js.map +1 -0
- package/dist/worker/types.d.ts +181 -2
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/types.js +11 -0
- package/dist/worker/types.js.map +1 -1
- package/dist/worker/validate-fix-handler.d.ts +79 -0
- package/dist/worker/validate-fix-handler.d.ts.map +1 -0
- package/dist/worker/validate-fix-handler.js +320 -0
- package/dist/worker/validate-fix-handler.js.map +1 -0
- package/dist/worker/worker-result.d.ts +39 -0
- package/dist/worker/worker-result.d.ts.map +1 -0
- package/dist/worker/worker-result.js +10 -0
- package/dist/worker/worker-result.js.map +1 -0
- package/package.json +12 -7
package/dist/worker/config.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { AgentsConfigSchema } from '@generacy-ai/config';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in provider fallback used by `resolveAgentForPhase` when no tier of
|
|
5
|
+
* the precedence chain (config, repo `defaults.agent`, or env) supplies a
|
|
6
|
+
* provider name.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_PROVIDER = 'claude-code';
|
|
2
9
|
/**
|
|
3
10
|
* Gate definition schema for pausing workflow at review checkpoints
|
|
4
11
|
*/
|
|
@@ -8,7 +15,7 @@ export const GateDefinitionSchema = z.object({
|
|
|
8
15
|
/** Label to add when gate is active */
|
|
9
16
|
gateLabel: z.string(),
|
|
10
17
|
/** When to activate the gate */
|
|
11
|
-
condition: z.enum(['always', 'on-request', 'on-questions', 'on-failure', 'on-sibling-review']),
|
|
18
|
+
condition: z.enum(['always', 'on-request', 'on-questions', 'on-failure', 'on-sibling-review', 'on-merge-conflict']),
|
|
12
19
|
});
|
|
13
20
|
/**
|
|
14
21
|
* Per-phase wall-clock timeout overrides (milliseconds).
|
|
@@ -50,21 +57,39 @@ export const WorkerConfigSchema = z.object({
|
|
|
50
57
|
/** Command to run during the validate phase */
|
|
51
58
|
validateCommand: z.string().default('pnpm test && pnpm build'),
|
|
52
59
|
/** Command to run before validation to install dependencies (empty string to skip) */
|
|
53
|
-
preValidateCommand: z
|
|
60
|
+
preValidateCommand: z
|
|
61
|
+
.string()
|
|
62
|
+
.default("pnpm install && if [ -f pnpm-workspace.yaml ] && ls packages/*/package.json >/dev/null 2>&1; then pnpm -r --filter './packages/*' build; fi"),
|
|
54
63
|
/** Maximum retries for implement phase when partial progress is detected */
|
|
55
64
|
maxImplementRetries: z.number().int().min(0).max(5).default(2),
|
|
56
65
|
/** Credential role from .generacy/config.yaml defaults.role — when set, credentials are populated on launch requests */
|
|
57
66
|
credentialRole: z.string().optional(),
|
|
67
|
+
/**
|
|
68
|
+
* Per-workflow-phase `{ provider, model }` selection. See `AgentsConfigSchema`
|
|
69
|
+
* for the shape. Repo-level overrides from `.generacy/config.yaml` are merged
|
|
70
|
+
* onto this via `applyRepoAgentOverrides`.
|
|
71
|
+
*/
|
|
72
|
+
agents: AgentsConfigSchema.optional(),
|
|
73
|
+
/**
|
|
74
|
+
* Repo-level default provider from `.generacy/config.yaml` `defaults.agent`.
|
|
75
|
+
* Provider-only — `defaults.agent` is a single string, not an `AgentEntry`.
|
|
76
|
+
* Consumed by `resolveAgentForPhase` as the tier below `agents.default`.
|
|
77
|
+
*/
|
|
78
|
+
defaultsAgent: z.string().min(1).optional(),
|
|
58
79
|
/** Gate definitions keyed by issue label */
|
|
59
80
|
gates: z.record(z.string(), z.array(GateDefinitionSchema)).default({
|
|
60
81
|
'speckit-feature': [
|
|
61
82
|
{ phase: 'clarify', gateLabel: 'waiting-for:clarification', condition: 'on-questions' },
|
|
62
83
|
{ phase: 'implement', gateLabel: 'waiting-for:implementation-review', condition: 'always' },
|
|
63
84
|
{ phase: 'implement', gateLabel: 'waiting-for:sibling-review', condition: 'on-sibling-review' },
|
|
85
|
+
{ phase: 'implement', gateLabel: 'waiting-for:merge-conflicts', condition: 'on-merge-conflict' },
|
|
86
|
+
{ phase: 'validate', gateLabel: 'waiting-for:merge-conflicts', condition: 'on-merge-conflict' },
|
|
64
87
|
],
|
|
65
88
|
'speckit-bugfix': [
|
|
66
89
|
{ phase: 'clarify', gateLabel: 'waiting-for:clarification', condition: 'on-questions' },
|
|
67
90
|
{ phase: 'implement', gateLabel: 'waiting-for:implementation-review', condition: 'on-request' },
|
|
91
|
+
{ phase: 'implement', gateLabel: 'waiting-for:merge-conflicts', condition: 'on-merge-conflict' },
|
|
92
|
+
{ phase: 'validate', gateLabel: 'waiting-for:merge-conflicts', condition: 'on-merge-conflict' },
|
|
68
93
|
],
|
|
69
94
|
'speckit-epic': [
|
|
70
95
|
{ phase: 'clarify', gateLabel: 'waiting-for:clarification', condition: 'on-questions' },
|
|
@@ -72,6 +97,35 @@ export const WorkerConfigSchema = z.object({
|
|
|
72
97
|
],
|
|
73
98
|
}),
|
|
74
99
|
});
|
|
100
|
+
/**
|
|
101
|
+
* Merge per-repo validate-command overrides onto the global worker config.
|
|
102
|
+
*
|
|
103
|
+
* The target repo's `.generacy/config.yaml` `orchestrator` block may set
|
|
104
|
+
* `validateCommand` / `preValidateCommand`. The global defaults are
|
|
105
|
+
* monorepo-shaped (`pnpm test && pnpm build`); single-package repos (e.g. an
|
|
106
|
+
* Astro site with only a `build` script) override them so the validate phase
|
|
107
|
+
* doesn't fail on a missing `test` script before it can reach the build.
|
|
108
|
+
*
|
|
109
|
+
* Only those two fields are overridable per-repo. An explicit empty
|
|
110
|
+
* `preValidateCommand` is preserved (it means "skip the install step"). Returns
|
|
111
|
+
* the original config object unchanged when there are no applicable overrides,
|
|
112
|
+
* so callers can cheaply detect "no override" via reference equality.
|
|
113
|
+
*/
|
|
114
|
+
export function applyRepoValidateOverrides(config, settings) {
|
|
115
|
+
if (settings == null ||
|
|
116
|
+
(settings.validateCommand === undefined && settings.preValidateCommand === undefined)) {
|
|
117
|
+
return config;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
...config,
|
|
121
|
+
...(settings.validateCommand !== undefined
|
|
122
|
+
? { validateCommand: settings.validateCommand }
|
|
123
|
+
: {}),
|
|
124
|
+
...(settings.preValidateCommand !== undefined
|
|
125
|
+
? { preValidateCommand: settings.preValidateCommand }
|
|
126
|
+
: {}),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
75
129
|
/**
|
|
76
130
|
* Resolve the wall-clock timeout (ms) for a CLI phase: the per-phase override
|
|
77
131
|
* if one is configured, otherwise the flat `phaseTimeoutMs` fallback.
|
|
@@ -81,4 +135,127 @@ export function resolvePhaseTimeoutMs(config, phase) {
|
|
|
81
135
|
// Zod and may omit phaseTimeoutOverrides entirely.
|
|
82
136
|
return config.phaseTimeoutOverrides?.[phase] ?? config.phaseTimeoutMs;
|
|
83
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Field-by-field merge of two `AgentEntry` objects. Target-repo values overlay
|
|
140
|
+
* cluster-default values; missing fields on the target preserve the cluster
|
|
141
|
+
* default (`{ provider: 'X' }` on target keeps cluster's `model`).
|
|
142
|
+
*/
|
|
143
|
+
function mergeAgentEntry(base, override) {
|
|
144
|
+
if (base === undefined)
|
|
145
|
+
return override;
|
|
146
|
+
if (override === undefined)
|
|
147
|
+
return base;
|
|
148
|
+
return {
|
|
149
|
+
...(base.provider !== undefined || override.provider !== undefined
|
|
150
|
+
? { provider: override.provider ?? base.provider }
|
|
151
|
+
: {}),
|
|
152
|
+
...(base.model !== undefined || override.model !== undefined
|
|
153
|
+
? { model: override.model ?? base.model }
|
|
154
|
+
: {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Deep merge two `AgentsConfig` values. Merge semantics:
|
|
159
|
+
* - `agents.default`: field-by-field on `{ provider, model }`.
|
|
160
|
+
* - `agents.workflows.<name>.default`: same field-by-field merge.
|
|
161
|
+
* - `agents.workflows.<name>.phases.<phase>`: same field-by-field merge.
|
|
162
|
+
* - Workflow names present only on the target pass through untouched; workflow
|
|
163
|
+
* names present only on the base survive when the target adds new ones.
|
|
164
|
+
*/
|
|
165
|
+
function mergeAgentsConfig(base, override) {
|
|
166
|
+
if (base === undefined)
|
|
167
|
+
return override;
|
|
168
|
+
if (override === undefined)
|
|
169
|
+
return base;
|
|
170
|
+
const merged = {};
|
|
171
|
+
const mergedDefault = mergeAgentEntry(base.default, override.default);
|
|
172
|
+
if (mergedDefault !== undefined)
|
|
173
|
+
merged.default = mergedDefault;
|
|
174
|
+
const baseWorkflows = base.workflows ?? {};
|
|
175
|
+
const overrideWorkflows = override.workflows ?? {};
|
|
176
|
+
const workflowNames = new Set([
|
|
177
|
+
...Object.keys(baseWorkflows),
|
|
178
|
+
...Object.keys(overrideWorkflows),
|
|
179
|
+
]);
|
|
180
|
+
if (workflowNames.size > 0) {
|
|
181
|
+
const workflows = {};
|
|
182
|
+
for (const name of workflowNames) {
|
|
183
|
+
const b = baseWorkflows[name];
|
|
184
|
+
const o = overrideWorkflows[name];
|
|
185
|
+
if (b === undefined && o !== undefined) {
|
|
186
|
+
workflows[name] = o;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (o === undefined && b !== undefined) {
|
|
190
|
+
workflows[name] = b;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
// Both defined — merge default + phases field-by-field
|
|
194
|
+
const mergedWorkflowDefault = mergeAgentEntry(b?.default, o?.default);
|
|
195
|
+
const phaseKeys = ['specify', 'clarify', 'plan', 'tasks', 'implement', 'validate'];
|
|
196
|
+
const mergedPhases = {};
|
|
197
|
+
let anyPhase = false;
|
|
198
|
+
for (const phase of phaseKeys) {
|
|
199
|
+
const bp = b?.phases?.[phase];
|
|
200
|
+
const op = o?.phases?.[phase];
|
|
201
|
+
const mp = mergeAgentEntry(bp, op);
|
|
202
|
+
if (mp !== undefined) {
|
|
203
|
+
mergedPhases[phase] = mp;
|
|
204
|
+
anyPhase = true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const entry = {};
|
|
208
|
+
if (mergedWorkflowDefault !== undefined)
|
|
209
|
+
entry.default = mergedWorkflowDefault;
|
|
210
|
+
if (anyPhase)
|
|
211
|
+
entry.phases = mergedPhases;
|
|
212
|
+
workflows[name] = entry;
|
|
213
|
+
}
|
|
214
|
+
merged.workflows = workflows;
|
|
215
|
+
}
|
|
216
|
+
return merged;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Sibling of `applyRepoValidateOverrides` — merges the target repo's
|
|
220
|
+
* `orchestrator.agents` block onto the cluster-default `agents` block on
|
|
221
|
+
* `WorkerConfig`. Field-by-field so partial `{ provider }`-only or
|
|
222
|
+
* `{ model }`-only overrides preserve missing sibling fields from the base.
|
|
223
|
+
*
|
|
224
|
+
* Returns the original config unchanged when `settings.agents` is absent so
|
|
225
|
+
* callers can cheaply detect "no override" via reference equality.
|
|
226
|
+
*/
|
|
227
|
+
export function applyRepoAgentOverrides(config, settings) {
|
|
228
|
+
if (settings == null || settings.agents === undefined) {
|
|
229
|
+
return config;
|
|
230
|
+
}
|
|
231
|
+
const merged = mergeAgentsConfig(config.agents, settings.agents);
|
|
232
|
+
return { ...config, agents: merged };
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Resolve `{ provider, model }` for a phase within a workflow. Provider and
|
|
236
|
+
* model resolve INDEPENDENTLY over the same tier list — a phase override may
|
|
237
|
+
* set only `model` while `provider` falls through from a lower tier.
|
|
238
|
+
*
|
|
239
|
+
* Precedence:
|
|
240
|
+
* 1. `config.agents.workflows[workflowName].phases[phase]`
|
|
241
|
+
* 2. `config.agents.workflows[workflowName].default`
|
|
242
|
+
* 3. `config.agents.default` (cluster env folds into this tier via loader)
|
|
243
|
+
* 4. `config.defaultsAgent` (**provider only** — `defaults.agent` is a bare string)
|
|
244
|
+
* 5. Built-in `DEFAULT_PROVIDER = 'claude-code'` (**provider only**)
|
|
245
|
+
*
|
|
246
|
+
* The `model` walk terminates at tier 3 returning `undefined` (no built-in
|
|
247
|
+
* model default). The `provider` walk always returns a value.
|
|
248
|
+
*/
|
|
249
|
+
export function resolveAgentForPhase(config, workflowName, phase) {
|
|
250
|
+
const workflowEntry = config.agents?.workflows?.[workflowName];
|
|
251
|
+
const tiers = [
|
|
252
|
+
workflowEntry?.phases?.[phase],
|
|
253
|
+
workflowEntry?.default,
|
|
254
|
+
config.agents?.default,
|
|
255
|
+
];
|
|
256
|
+
const providerFromTiers = tiers.find((t) => t?.provider !== undefined)?.provider;
|
|
257
|
+
const provider = providerFromTiers ?? config.defaultsAgent ?? DEFAULT_PROVIDER;
|
|
258
|
+
const model = tiers.find((t) => t?.model !== undefined)?.model;
|
|
259
|
+
return model !== undefined ? { provider, model } : { provider };
|
|
260
|
+
}
|
|
84
261
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/worker/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/worker/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured extract from failing validate CLI stdout.
|
|
3
|
+
* Sorted by `id` (lexicographic) for hash stability.
|
|
4
|
+
* See specs/892-found-during-cockpit-v1/contracts/evidence-hash.md.
|
|
5
|
+
*/
|
|
6
|
+
export interface EvidenceExtract {
|
|
7
|
+
failures: Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
firstError: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Result of hashing validate CLI stdout — SHA-256 hex identity plus the
|
|
14
|
+
* canonical `extract` that was hashed (surfaces in prompt + logs).
|
|
15
|
+
*/
|
|
16
|
+
export interface EvidenceHashResult {
|
|
17
|
+
/** 64-character lower-case hex SHA-256. */
|
|
18
|
+
hash: string;
|
|
19
|
+
/** Canonical input to the hash; included in the fix prompt for debuggability. */
|
|
20
|
+
extract: EvidenceExtract;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Hash validate CLI stdout into a stable identity (#892).
|
|
24
|
+
*
|
|
25
|
+
* Extract categories are tried in order: next-build missing-module, next-build
|
|
26
|
+
* type-error, vitest failures. If none match, falls back to a whole-transcript
|
|
27
|
+
* hash so every stdout produces a well-defined result.
|
|
28
|
+
*
|
|
29
|
+
* See specs/892-found-during-cockpit-v1/contracts/evidence-hash.md.
|
|
30
|
+
*/
|
|
31
|
+
export declare function hashValidationEvidence(stdout: string): EvidenceHashResult;
|
|
32
|
+
//# sourceMappingURL=evidence-hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-hash.d.ts","sourceRoot":"","sources":["../../src/worker/evidence-hash.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,EAAE,eAAe,CAAC;CAC1B;AA+HD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAmBzE"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Normalization pipeline applied to raw stdout before extraction (#892).
|
|
4
|
+
*
|
|
5
|
+
* Idempotent by construction — running the pipeline on already-normalized
|
|
6
|
+
* text yields the same output. Ordering matters: ANSI first (so downstream
|
|
7
|
+
* regexes see clean text), timestamps before paths (so ISO-8601 doesn't
|
|
8
|
+
* partially match path regex), paths before PIDs (so bracket sequences in
|
|
9
|
+
* paths aren't mistaken for PIDs).
|
|
10
|
+
*/
|
|
11
|
+
function normalize(stdout) {
|
|
12
|
+
let out = stdout;
|
|
13
|
+
// 1. ANSI escapes (CSI + OSC). Matching the ESC/BEL control chars is the
|
|
14
|
+
// whole point here, so the no-control-regex rule is intentionally disabled.
|
|
15
|
+
// eslint-disable-next-line no-control-regex
|
|
16
|
+
out = out.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
|
|
17
|
+
// eslint-disable-next-line no-control-regex
|
|
18
|
+
out = out.replace(/\x1b\][^\x07]*\x07/g, '');
|
|
19
|
+
// 2. ISO-8601 timestamps → <TS>.
|
|
20
|
+
out = out.replace(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?/g, '<TS>');
|
|
21
|
+
// 3. Absolute paths → <PATH>. Only strip paths whose leading '/' is at a
|
|
22
|
+
// non-alphanumeric boundary — this preserves import specifiers like
|
|
23
|
+
// `@/components/CopyButton` and relative paths like `src/app/foo.ts` /
|
|
24
|
+
// `./src/foo.ts` while normalizing true absolute paths like
|
|
25
|
+
// `/home/node/workspaces/sniplink/src/app/foo.ts`.
|
|
26
|
+
out = out.replace(/(?<![\w@.])(\/[a-zA-Z0-9._-]+)+/g, '<PATH>');
|
|
27
|
+
// 4. PIDs → <PID>. Three forms: pid=<n>, PID: <n>, [<n>] where n >= 4 digits.
|
|
28
|
+
out = out.replace(/\bpid=\d+\b/g, 'pid=<PID>');
|
|
29
|
+
out = out.replace(/\bPID:\s*\d+\b/g, 'PID: <PID>');
|
|
30
|
+
out = out.replace(/\[\d{4,}\]/g, '[<PID>]');
|
|
31
|
+
// 5. Test-runner tmp identifiers → <TMP>. Absolute /tmp/... already
|
|
32
|
+
// reduced by step 3; T-<hex>{8+} form is the vitest/jest one.
|
|
33
|
+
out = out.replace(/T-[a-zA-Z0-9]{8,}/g, '<TMP>');
|
|
34
|
+
// 6. Ports on localhost/127.0.0.1 → <PORT>.
|
|
35
|
+
out = out.replace(/\b(localhost|127\.0\.0\.1):\d+\b/g, '$1:<PORT>');
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Extract next-build "Cannot find module" failures.
|
|
40
|
+
*/
|
|
41
|
+
function extractNextBuildMissingModule(normalized) {
|
|
42
|
+
const failures = [];
|
|
43
|
+
const re = /Cannot find module '([^']+)'/g;
|
|
44
|
+
let m;
|
|
45
|
+
while ((m = re.exec(normalized)) !== null) {
|
|
46
|
+
const modulePath = m[1];
|
|
47
|
+
failures.push({
|
|
48
|
+
id: `module:${modulePath}`,
|
|
49
|
+
firstError: m[0],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return failures;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract next-build "Type error" failures.
|
|
56
|
+
*/
|
|
57
|
+
function extractNextBuildTypeError(normalized) {
|
|
58
|
+
const failures = [];
|
|
59
|
+
// Type error line followed (within the same block) by a File: <path> line.
|
|
60
|
+
const re = /Type error: (.+?)(?:\r?\n)[\s\S]{0,200}?File: (\S+)/g;
|
|
61
|
+
let m;
|
|
62
|
+
while ((m = re.exec(normalized)) !== null) {
|
|
63
|
+
const summary = m[1].trim();
|
|
64
|
+
const filePath = m[2];
|
|
65
|
+
failures.push({
|
|
66
|
+
id: `type:${filePath}:${summary.slice(0, 80)}`,
|
|
67
|
+
firstError: `Type error: ${summary}`,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return failures;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Extract vitest failing test lines (` × <name>`).
|
|
74
|
+
* `firstError` is the first indented (≥2 space) line following the × line.
|
|
75
|
+
*/
|
|
76
|
+
function extractVitestFailures(normalized) {
|
|
77
|
+
const failures = [];
|
|
78
|
+
const lines = normalized.split('\n');
|
|
79
|
+
const failedLineRe = /^\s*×\s+(.+?)(?:\s+\d+ms)?$/;
|
|
80
|
+
for (let i = 0; i < lines.length; i++) {
|
|
81
|
+
const m = failedLineRe.exec(lines[i]);
|
|
82
|
+
if (!m)
|
|
83
|
+
continue;
|
|
84
|
+
const testName = m[1].trim();
|
|
85
|
+
let firstError = '';
|
|
86
|
+
for (let j = i + 1; j < Math.min(lines.length, i + 11); j++) {
|
|
87
|
+
const l = lines[j];
|
|
88
|
+
if (/^\s{2,}\S/.test(l)) {
|
|
89
|
+
firstError = l.trim();
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
failures.push({
|
|
94
|
+
id: `test:${testName}`,
|
|
95
|
+
firstError,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return failures;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Fallback path when no known pattern matches.
|
|
102
|
+
* `id` = `hash:<first 16 hex of SHA-256 of full normalized transcript>`.
|
|
103
|
+
* `firstError` = first non-empty line of normalized transcript.
|
|
104
|
+
*/
|
|
105
|
+
function fallbackExtract(normalized) {
|
|
106
|
+
const digest = createHash('sha256').update(normalized, 'utf8').digest('hex');
|
|
107
|
+
const firstLine = normalized.split('\n').find((l) => l.length > 0) ?? '';
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
id: `hash:${digest.slice(0, 16)}`,
|
|
111
|
+
firstError: firstLine,
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Hash validate CLI stdout into a stable identity (#892).
|
|
117
|
+
*
|
|
118
|
+
* Extract categories are tried in order: next-build missing-module, next-build
|
|
119
|
+
* type-error, vitest failures. If none match, falls back to a whole-transcript
|
|
120
|
+
* hash so every stdout produces a well-defined result.
|
|
121
|
+
*
|
|
122
|
+
* See specs/892-found-during-cockpit-v1/contracts/evidence-hash.md.
|
|
123
|
+
*/
|
|
124
|
+
export function hashValidationEvidence(stdout) {
|
|
125
|
+
const normalized = normalize(stdout);
|
|
126
|
+
const raw = [
|
|
127
|
+
...extractNextBuildMissingModule(normalized),
|
|
128
|
+
...extractNextBuildTypeError(normalized),
|
|
129
|
+
...extractVitestFailures(normalized),
|
|
130
|
+
];
|
|
131
|
+
const failures = raw.length > 0 ? raw : fallbackExtract(normalized);
|
|
132
|
+
// Sort by id for determinism (localeCompare with 'variant' avoids locale drift).
|
|
133
|
+
failures.sort((a, b) => a.id.localeCompare(b.id, undefined, { sensitivity: 'variant' }));
|
|
134
|
+
const extract = { failures };
|
|
135
|
+
const canonical = JSON.stringify({ failures: extract.failures });
|
|
136
|
+
const hash = createHash('sha256').update(canonical, 'utf8').digest('hex');
|
|
137
|
+
return { hash, extract };
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=evidence-hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-hash.js","sourceRoot":"","sources":["../../src/worker/evidence-hash.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `assertHandlerOutcomeMatchesWorld` (#902 FR-006).
|
|
3
|
+
*
|
|
4
|
+
* Post-exit runtime assertion that reads a snapshot of the *real* world
|
|
5
|
+
* (labels + queue state) and refuses to accept "the handler said X" as
|
|
6
|
+
* evidence. Load-bearing enforcement half of the terminal-outcome invariant.
|
|
7
|
+
*
|
|
8
|
+
* Compile-time exhaustiveness would have passed the broken #898 handler
|
|
9
|
+
* (which had a `void` return that ran through the success path without
|
|
10
|
+
* setting anything). The type alone cannot catch this bug class.
|
|
11
|
+
*
|
|
12
|
+
* Pure function — fixture code snapshots the world, then calls the helper.
|
|
13
|
+
* Callable from prod code as a dev-mode assertion (not enabled by default).
|
|
14
|
+
*/
|
|
15
|
+
import type { HandlerOutcome } from './handler-outcome.js';
|
|
16
|
+
import type { QueueItem } from '../types/index.js';
|
|
17
|
+
export interface QueueSnapshot {
|
|
18
|
+
readonly inFlight: boolean;
|
|
19
|
+
readonly pendingItems: readonly Pick<QueueItem, 'command' | 'metadata' | 'workflowName'>[];
|
|
20
|
+
}
|
|
21
|
+
export type AssertionResult = {
|
|
22
|
+
readonly ok: true;
|
|
23
|
+
} | {
|
|
24
|
+
readonly ok: false;
|
|
25
|
+
readonly mismatch: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Assert the returned `HandlerOutcome` matches the real world.
|
|
29
|
+
*
|
|
30
|
+
* Rules per variant:
|
|
31
|
+
* - `re-armed`: `queueSnapshot.pendingItems` contains an entry with
|
|
32
|
+
* `command === 'continue'` and `metadata?.startPhase === outcome.startPhase`.
|
|
33
|
+
* - `gated`: `labels` contains a matching `waiting-for:*` label.
|
|
34
|
+
* - `failed`: `labels` contains a `blocked:*` or `failed:*` marker.
|
|
35
|
+
* - `done`: `labels` contains no `waiting-for:*` and no `blocked:*` / `failed:*`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function assertHandlerOutcomeMatchesWorld(outcome: HandlerOutcome, labels: readonly string[], queueSnapshot: QueueSnapshot): AssertionResult;
|
|
38
|
+
//# sourceMappingURL=handler-outcome-assertion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-outcome-assertion.d.ts","sourceRoot":"","sources":["../../src/worker/handler-outcome-assertion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,SAAS,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,cAAc,CAAC,EAAE,CAAC;CAC5F;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GACrB;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,aAAa,EAAE,aAAa,GAC3B,eAAe,CAwDjB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assert the returned `HandlerOutcome` matches the real world.
|
|
3
|
+
*
|
|
4
|
+
* Rules per variant:
|
|
5
|
+
* - `re-armed`: `queueSnapshot.pendingItems` contains an entry with
|
|
6
|
+
* `command === 'continue'` and `metadata?.startPhase === outcome.startPhase`.
|
|
7
|
+
* - `gated`: `labels` contains a matching `waiting-for:*` label.
|
|
8
|
+
* - `failed`: `labels` contains a `blocked:*` or `failed:*` marker.
|
|
9
|
+
* - `done`: `labels` contains no `waiting-for:*` and no `blocked:*` / `failed:*`.
|
|
10
|
+
*/
|
|
11
|
+
export function assertHandlerOutcomeMatchesWorld(outcome, labels, queueSnapshot) {
|
|
12
|
+
switch (outcome.outcome) {
|
|
13
|
+
case 're-armed': {
|
|
14
|
+
const match = queueSnapshot.pendingItems.find((i) => i.command === 'continue' &&
|
|
15
|
+
i.metadata?.startPhase === outcome.startPhase);
|
|
16
|
+
if (!match) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
mismatch: `re-armed(${outcome.startPhase}): no matching pending item found in queue`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return { ok: true };
|
|
23
|
+
}
|
|
24
|
+
case 'gated': {
|
|
25
|
+
const hasMatchingWaitingFor = labels.some((l) => l === outcome.gateLabel && l.startsWith('waiting-for:'));
|
|
26
|
+
if (!hasMatchingWaitingFor) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
mismatch: `gated(${outcome.gateLabel}): no matching waiting-for:* label on issue`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return { ok: true };
|
|
33
|
+
}
|
|
34
|
+
case 'failed': {
|
|
35
|
+
const hasBlockedOrFailed = labels.some((l) => l.startsWith('blocked:') || l.startsWith('failed:'));
|
|
36
|
+
if (!hasBlockedOrFailed) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
mismatch: `failed: no blocked:* or failed:* marker on issue`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return { ok: true };
|
|
43
|
+
}
|
|
44
|
+
case 'done': {
|
|
45
|
+
const terminalBlockers = labels.filter((l) => l.startsWith('waiting-for:') ||
|
|
46
|
+
l.startsWith('blocked:') ||
|
|
47
|
+
l.startsWith('failed:'));
|
|
48
|
+
if (terminalBlockers.length > 0) {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
mismatch: `done: unexpected terminal-blocker label(s): ${terminalBlockers.join(', ')}`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return { ok: true };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=handler-outcome-assertion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-outcome-assertion.js","sourceRoot":"","sources":["../../src/worker/handler-outcome-assertion.ts"],"names":[],"mappings":"AA0BA;;;;;;;;;GASG;AACH,MAAM,UAAU,gCAAgC,CAC9C,OAAuB,EACvB,MAAyB,EACzB,aAA4B;IAE5B,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;QACxB,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,KAAK,GAAG,aAAa,CAAC,YAAY,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,OAAO,KAAK,UAAU;gBACvB,CAAC,CAAC,QAAgD,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CACzF,CAAC;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,QAAQ,EAAE,YAAY,OAAO,CAAC,UAAU,4CAA4C;iBACrF,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,qBAAqB,GAAG,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAC/D,CAAC;YACF,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3B,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,QAAQ,EAAE,SAAS,OAAO,CAAC,SAAS,6CAA6C;iBAClF,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAC3D,CAAC;YACF,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,QAAQ,EAAE,kDAAkD;iBAC7D,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC;gBAC5B,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;gBACxB,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAC1B,CAAC;YACF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,QAAQ,EAAE,+CAA+C,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACvF,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `HandlerOutcome` discriminated union (#902 FR-005).
|
|
3
|
+
*
|
|
4
|
+
* The only legal return shape for `MergeConflictHandler.handle`. Every
|
|
5
|
+
* terminal exit path in the handler maps to exactly one variant; compile-time
|
|
6
|
+
* exhaustiveness enforces this at the type layer.
|
|
7
|
+
*
|
|
8
|
+
* The load-bearing enforcement half is the runtime helper
|
|
9
|
+
* `assertHandlerOutcomeMatchesWorld` in `./handler-outcome-assertion.ts`.
|
|
10
|
+
*
|
|
11
|
+
* Semantics:
|
|
12
|
+
* - `re-armed` — the interrupted phase must be re-entered. Dispatcher enqueues
|
|
13
|
+
* `{command: 'continue', startPhase}` for the same itemKey after
|
|
14
|
+
* `queue.complete()` fires on the current handler item.
|
|
15
|
+
* - `gated` — the issue is now sitting at a `waiting-for:*` label matching
|
|
16
|
+
* `gateLabel`. Detector will pick it up naturally.
|
|
17
|
+
* - `failed` — the issue is now sitting at a `blocked:*` or `failed:*` marker.
|
|
18
|
+
* Operator intervention required.
|
|
19
|
+
* - `done` — the issue is terminal (closed / merged / withdrawn). No detector
|
|
20
|
+
* pickup expected.
|
|
21
|
+
*/
|
|
22
|
+
import type { WorkflowPhase } from './types.js';
|
|
23
|
+
import type { BlockedStuckMergeConflictsEvidence } from './merge-conflict-handler.js';
|
|
24
|
+
export interface ReArmedOutcome {
|
|
25
|
+
readonly outcome: 're-armed';
|
|
26
|
+
/** Phase the interrupted worker should resume at. Threaded to enqueue. */
|
|
27
|
+
readonly startPhase: WorkflowPhase;
|
|
28
|
+
}
|
|
29
|
+
export interface GatedOutcome {
|
|
30
|
+
readonly outcome: 'gated';
|
|
31
|
+
/**
|
|
32
|
+
* The `waiting-for:*` label that MUST be present on the issue at return.
|
|
33
|
+
* Enforced by `assertHandlerOutcomeMatchesWorld`.
|
|
34
|
+
*/
|
|
35
|
+
readonly gateLabel: string;
|
|
36
|
+
}
|
|
37
|
+
export interface FailedOutcome {
|
|
38
|
+
readonly outcome: 'failed';
|
|
39
|
+
/**
|
|
40
|
+
* Evidence blob rendered into the operator-facing stage comment.
|
|
41
|
+
* Shape is handler-specific; `MergeConflictHandler` uses
|
|
42
|
+
* `BlockedStuckMergeConflictsEvidence`.
|
|
43
|
+
*/
|
|
44
|
+
readonly evidence: BlockedStuckMergeConflictsEvidence;
|
|
45
|
+
}
|
|
46
|
+
export interface DoneOutcome {
|
|
47
|
+
readonly outcome: 'done';
|
|
48
|
+
}
|
|
49
|
+
export type HandlerOutcome = ReArmedOutcome | GatedOutcome | FailedOutcome | DoneOutcome;
|
|
50
|
+
//# sourceMappingURL=handler-outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-outcome.d.ts","sourceRoot":"","sources":["../../src/worker/handler-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AAEtF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,kCAAkC,CAAC;CACvD;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,YAAY,GACZ,aAAa,GACb,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-outcome.js","sourceRoot":"","sources":["../../src/worker/handler-outcome.ts"],"names":[],"mappings":""}
|