@generacy-ai/orchestrator 0.0.0-preview-20260304013206
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/LICENSE +191 -0
- package/dist/auth/api-key.d.ts +63 -0
- package/dist/auth/api-key.d.ts.map +1 -0
- package/dist/auth/api-key.js +102 -0
- package/dist/auth/api-key.js.map +1 -0
- package/dist/auth/github-oauth.d.ts +29 -0
- package/dist/auth/github-oauth.d.ts.map +1 -0
- package/dist/auth/github-oauth.js +136 -0
- package/dist/auth/github-oauth.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +9 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/jwt.d.ts +34 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +74 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/middleware.d.ts +43 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +101 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +5 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +21 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +295 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +733 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +174 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +30 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +173 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/index.d.ts +4 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +4 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +32 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +92 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-logger.d.ts +31 -0
- package/dist/middleware/request-logger.d.ts.map +1 -0
- package/dist/middleware/request-logger.js +89 -0
- package/dist/middleware/request-logger.js.map +1 -0
- package/dist/routes/agents.d.ts +7 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +78 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/dispatch.d.ts +8 -0
- package/dist/routes/dispatch.d.ts.map +1 -0
- package/dist/routes/dispatch.js +46 -0
- package/dist/routes/dispatch.js.map +1 -0
- package/dist/routes/events.d.ts +14 -0
- package/dist/routes/events.d.ts.map +1 -0
- package/dist/routes/events.js +240 -0
- package/dist/routes/events.js.map +1 -0
- package/dist/routes/health.d.ts +14 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +132 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +36 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +34 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/integrations.d.ts +34 -0
- package/dist/routes/integrations.d.ts.map +1 -0
- package/dist/routes/integrations.js +81 -0
- package/dist/routes/integrations.js.map +1 -0
- package/dist/routes/metrics.d.ts +31 -0
- package/dist/routes/metrics.d.ts.map +1 -0
- package/dist/routes/metrics.js +157 -0
- package/dist/routes/metrics.js.map +1 -0
- package/dist/routes/pr-webhooks.d.ts +15 -0
- package/dist/routes/pr-webhooks.d.ts.map +1 -0
- package/dist/routes/pr-webhooks.js +114 -0
- package/dist/routes/pr-webhooks.js.map +1 -0
- package/dist/routes/queue.d.ts +7 -0
- package/dist/routes/queue.d.ts.map +1 -0
- package/dist/routes/queue.js +94 -0
- package/dist/routes/queue.js.map +1 -0
- package/dist/routes/webhooks.d.ts +15 -0
- package/dist/routes/webhooks.d.ts.map +1 -0
- package/dist/routes/webhooks.js +117 -0
- package/dist/routes/webhooks.js.map +1 -0
- package/dist/routes/workflows.d.ts +7 -0
- package/dist/routes/workflows.d.ts.map +1 -0
- package/dist/routes/workflows.js +138 -0
- package/dist/routes/workflows.js.map +1 -0
- package/dist/server.d.ts +35 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +264 -0
- package/dist/server.js.map +1 -0
- package/dist/services/agent-registry.d.ts +89 -0
- package/dist/services/agent-registry.d.ts.map +1 -0
- package/dist/services/agent-registry.js +173 -0
- package/dist/services/agent-registry.js.map +1 -0
- package/dist/services/epic-completion-monitor-service.d.ts +69 -0
- package/dist/services/epic-completion-monitor-service.d.ts.map +1 -0
- package/dist/services/epic-completion-monitor-service.js +200 -0
- package/dist/services/epic-completion-monitor-service.js.map +1 -0
- package/dist/services/identity.d.ts +41 -0
- package/dist/services/identity.d.ts.map +1 -0
- package/dist/services/identity.js +91 -0
- package/dist/services/identity.js.map +1 -0
- package/dist/services/index.d.ts +13 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +13 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/label-monitor-service.d.ts +95 -0
- package/dist/services/label-monitor-service.d.ts.map +1 -0
- package/dist/services/label-monitor-service.js +414 -0
- package/dist/services/label-monitor-service.js.map +1 -0
- package/dist/services/label-sync-service.d.ts +76 -0
- package/dist/services/label-sync-service.d.ts.map +1 -0
- package/dist/services/label-sync-service.js +108 -0
- package/dist/services/label-sync-service.js.map +1 -0
- package/dist/services/phase-tracker-service.d.ts +32 -0
- package/dist/services/phase-tracker-service.d.ts.map +1 -0
- package/dist/services/phase-tracker-service.js +82 -0
- package/dist/services/phase-tracker-service.js.map +1 -0
- package/dist/services/pr-feedback-monitor-service.d.ts +86 -0
- package/dist/services/pr-feedback-monitor-service.d.ts.map +1 -0
- package/dist/services/pr-feedback-monitor-service.js +423 -0
- package/dist/services/pr-feedback-monitor-service.js.map +1 -0
- package/dist/services/queue-service.d.ts +62 -0
- package/dist/services/queue-service.d.ts.map +1 -0
- package/dist/services/queue-service.js +147 -0
- package/dist/services/queue-service.js.map +1 -0
- package/dist/services/redis-queue-adapter.d.ts +35 -0
- package/dist/services/redis-queue-adapter.d.ts.map +1 -0
- package/dist/services/redis-queue-adapter.js +218 -0
- package/dist/services/redis-queue-adapter.js.map +1 -0
- package/dist/services/smee-receiver.d.ts +87 -0
- package/dist/services/smee-receiver.d.ts.map +1 -0
- package/dist/services/smee-receiver.js +225 -0
- package/dist/services/smee-receiver.js.map +1 -0
- package/dist/services/webhook-setup-service.d.ts +253 -0
- package/dist/services/webhook-setup-service.d.ts.map +1 -0
- package/dist/services/webhook-setup-service.js +369 -0
- package/dist/services/webhook-setup-service.js.map +1 -0
- package/dist/services/worker-dispatcher.d.ts +57 -0
- package/dist/services/worker-dispatcher.d.ts.map +1 -0
- package/dist/services/worker-dispatcher.js +211 -0
- package/dist/services/worker-dispatcher.js.map +1 -0
- package/dist/services/workflow-service.d.ts +65 -0
- package/dist/services/workflow-service.d.ts.map +1 -0
- package/dist/services/workflow-service.js +164 -0
- package/dist/services/workflow-service.js.map +1 -0
- package/dist/sse/events.d.ts +50 -0
- package/dist/sse/events.d.ts.map +1 -0
- package/dist/sse/events.js +152 -0
- package/dist/sse/events.js.map +1 -0
- package/dist/sse/index.d.ts +4 -0
- package/dist/sse/index.d.ts.map +1 -0
- package/dist/sse/index.js +7 -0
- package/dist/sse/index.js.map +1 -0
- package/dist/sse/stream.d.ts +109 -0
- package/dist/sse/stream.d.ts.map +1 -0
- package/dist/sse/stream.js +239 -0
- package/dist/sse/stream.js.map +1 -0
- package/dist/sse/subscriptions.d.ts +91 -0
- package/dist/sse/subscriptions.d.ts.map +1 -0
- package/dist/sse/subscriptions.js +299 -0
- package/dist/sse/subscriptions.js.map +1 -0
- package/dist/types/api.d.ts +651 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +169 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +27 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/monitor.d.ts +243 -0
- package/dist/types/monitor.d.ts.map +1 -0
- package/dist/types/monitor.js +2 -0
- package/dist/types/monitor.js.map +1 -0
- package/dist/types/problem-details.d.ts +63 -0
- package/dist/types/problem-details.d.ts.map +1 -0
- package/dist/types/problem-details.js +37 -0
- package/dist/types/problem-details.js.map +1 -0
- package/dist/types/sse.d.ts +224 -0
- package/dist/types/sse.d.ts.map +1 -0
- package/dist/types/sse.js +103 -0
- package/dist/types/sse.js.map +1 -0
- package/dist/types/webhook.d.ts +59 -0
- package/dist/types/webhook.d.ts.map +1 -0
- package/dist/types/webhook.js +2 -0
- package/dist/types/webhook.js.map +1 -0
- package/dist/utils/correlation.d.ts +30 -0
- package/dist/utils/correlation.d.ts.map +1 -0
- package/dist/utils/correlation.js +34 -0
- package/dist/utils/correlation.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/shutdown.d.ts +28 -0
- package/dist/utils/shutdown.d.ts.map +1 -0
- package/dist/utils/shutdown.js +86 -0
- package/dist/utils/shutdown.js.map +1 -0
- package/dist/worker/claude-cli-worker.d.ts +61 -0
- package/dist/worker/claude-cli-worker.d.ts.map +1 -0
- package/dist/worker/claude-cli-worker.js +330 -0
- package/dist/worker/claude-cli-worker.js.map +1 -0
- package/dist/worker/cli-spawner.d.ts +42 -0
- package/dist/worker/cli-spawner.d.ts.map +1 -0
- package/dist/worker/cli-spawner.js +183 -0
- package/dist/worker/cli-spawner.js.map +1 -0
- package/dist/worker/config.d.ts +76 -0
- package/dist/worker/config.d.ts.map +1 -0
- package/dist/worker/config.js +39 -0
- package/dist/worker/config.js.map +1 -0
- package/dist/worker/epic-post-tasks.d.ts +73 -0
- package/dist/worker/epic-post-tasks.d.ts.map +1 -0
- package/dist/worker/epic-post-tasks.js +266 -0
- package/dist/worker/epic-post-tasks.js.map +1 -0
- package/dist/worker/gate-checker.d.ts +22 -0
- package/dist/worker/gate-checker.d.ts.map +1 -0
- package/dist/worker/gate-checker.js +41 -0
- package/dist/worker/gate-checker.js.map +1 -0
- package/dist/worker/index.d.ts +13 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +19 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/label-manager.d.ts +89 -0
- package/dist/worker/label-manager.d.ts.map +1 -0
- package/dist/worker/label-manager.js +200 -0
- package/dist/worker/label-manager.js.map +1 -0
- package/dist/worker/output-capture.d.ts +58 -0
- package/dist/worker/output-capture.d.ts.map +1 -0
- package/dist/worker/output-capture.js +153 -0
- package/dist/worker/output-capture.js.map +1 -0
- package/dist/worker/phase-loop.d.ts +64 -0
- package/dist/worker/phase-loop.d.ts.map +1 -0
- package/dist/worker/phase-loop.js +185 -0
- package/dist/worker/phase-loop.js.map +1 -0
- package/dist/worker/phase-resolver.d.ts +62 -0
- package/dist/worker/phase-resolver.d.ts.map +1 -0
- package/dist/worker/phase-resolver.js +144 -0
- package/dist/worker/phase-resolver.js.map +1 -0
- package/dist/worker/pr-feedback-handler.d.ts +105 -0
- package/dist/worker/pr-feedback-handler.d.ts.map +1 -0
- package/dist/worker/pr-feedback-handler.js +391 -0
- package/dist/worker/pr-feedback-handler.js.map +1 -0
- package/dist/worker/pr-linker.d.ts +69 -0
- package/dist/worker/pr-linker.d.ts.map +1 -0
- package/dist/worker/pr-linker.js +108 -0
- package/dist/worker/pr-linker.js.map +1 -0
- package/dist/worker/pr-manager.d.ts +61 -0
- package/dist/worker/pr-manager.d.ts.map +1 -0
- package/dist/worker/pr-manager.js +140 -0
- package/dist/worker/pr-manager.js.map +1 -0
- package/dist/worker/repo-checkout.d.ts +63 -0
- package/dist/worker/repo-checkout.d.ts.map +1 -0
- package/dist/worker/repo-checkout.js +160 -0
- package/dist/worker/repo-checkout.js.map +1 -0
- package/dist/worker/stage-comment-manager.d.ts +34 -0
- package/dist/worker/stage-comment-manager.d.ts.map +1 -0
- package/dist/worker/stage-comment-manager.js +114 -0
- package/dist/worker/stage-comment-manager.js.map +1 -0
- package/dist/worker/types.d.ts +192 -0
- package/dist/worker/types.d.ts.map +1 -0
- package/dist/worker/types.js +53 -0
- package/dist/worker/types.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { GitHubClient } from '@generacy-ai/workflow-engine';
|
|
2
|
+
import type { WorkflowPhase, Logger } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages label transitions on GitHub issues throughout the worker's phase loop.
|
|
5
|
+
*
|
|
6
|
+
* Each phase transition updates labels to reflect the current workflow state:
|
|
7
|
+
* - `phase:<name>` — the phase currently being executed
|
|
8
|
+
* - `completed:<name>` — a phase that finished successfully
|
|
9
|
+
* - `waiting-for:<gate>` — the workflow is paused at a review gate
|
|
10
|
+
* - `agent:paused` — the agent is waiting for human input
|
|
11
|
+
* - `agent:error` — the agent encountered an error
|
|
12
|
+
* - `agent:in-progress` — the agent is actively processing
|
|
13
|
+
*/
|
|
14
|
+
export declare class LabelManager {
|
|
15
|
+
private readonly github;
|
|
16
|
+
private readonly owner;
|
|
17
|
+
private readonly repo;
|
|
18
|
+
private readonly issueNumber;
|
|
19
|
+
private readonly logger;
|
|
20
|
+
constructor(github: GitHubClient, owner: string, repo: string, issueNumber: number, logger: Logger);
|
|
21
|
+
/**
|
|
22
|
+
* Called when a phase begins execution.
|
|
23
|
+
*
|
|
24
|
+
* Adds `phase:<current>` label and removes any previous `phase:*` labels.
|
|
25
|
+
*/
|
|
26
|
+
onPhaseStart(phase: WorkflowPhase): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Called when a phase completes successfully.
|
|
29
|
+
*
|
|
30
|
+
* Adds `completed:<current>` label and removes `phase:<current>` label.
|
|
31
|
+
*/
|
|
32
|
+
onPhaseComplete(phase: WorkflowPhase): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Called when a gate is hit and the workflow must pause for human review.
|
|
35
|
+
*
|
|
36
|
+
* Adds `waiting-for:<gate>` and `agent:paused` labels, removes `phase:<current>`.
|
|
37
|
+
*/
|
|
38
|
+
onGateHit(phase: WorkflowPhase, gateLabel: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Called when an error occurs during phase execution.
|
|
41
|
+
*
|
|
42
|
+
* Adds `agent:error` label and removes `phase:<current>`.
|
|
43
|
+
*/
|
|
44
|
+
onError(phase: WorkflowPhase): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Called when the entire workflow completes (all phases finished).
|
|
47
|
+
*
|
|
48
|
+
* Removes the `agent:in-progress` label.
|
|
49
|
+
*/
|
|
50
|
+
onWorkflowComplete(): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Called at the start of a resume (continue command) before the phase loop.
|
|
53
|
+
*
|
|
54
|
+
* Removes stale `waiting-for:*` and `agent:paused` labels that were set
|
|
55
|
+
* when the workflow paused at a gate, and adds `agent:in-progress` to
|
|
56
|
+
* reflect the active workflow state.
|
|
57
|
+
*/
|
|
58
|
+
onResumeStart(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Ensures `agent:in-progress` and any lingering `phase:*` labels are removed.
|
|
61
|
+
*
|
|
62
|
+
* Designed to be called from `finally` blocks and reaper loops — this method
|
|
63
|
+
* never throws. If the GitHub API call fails after retries, the error is logged
|
|
64
|
+
* at `warn` level and swallowed.
|
|
65
|
+
*
|
|
66
|
+
* Safe to call when labels have already been removed (idempotent):
|
|
67
|
+
* `removeLabels()` in `gh-cli.ts` checks for "not found" in stderr and
|
|
68
|
+
* silently ignores it, so removing an already-absent label is a no-op.
|
|
69
|
+
* This also means `onWorkflowComplete()` is idempotent — calling it when
|
|
70
|
+
* `agent:in-progress` has already been removed will not throw.
|
|
71
|
+
*/
|
|
72
|
+
ensureCleanup(): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Fetch current labels on the issue and return those matching the `phase:*` pattern.
|
|
75
|
+
*/
|
|
76
|
+
private getCurrentPhaseLabels;
|
|
77
|
+
/**
|
|
78
|
+
* Retry an async operation with exponential backoff.
|
|
79
|
+
*
|
|
80
|
+
* Attempts the operation up to 3 times with delays of 1000ms, 2000ms, and 4000ms
|
|
81
|
+
* between attempts. The final attempt's error is re-thrown.
|
|
82
|
+
*/
|
|
83
|
+
private retryWithBackoff;
|
|
84
|
+
/**
|
|
85
|
+
* Sleep for the given number of milliseconds.
|
|
86
|
+
*/
|
|
87
|
+
private sleep;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=label-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label-manager.d.ts","sourceRoot":"","sources":["../../src/worker/label-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAJN,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM;IAGjC;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBvD;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBvE;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlD;;;;OAIG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAazC;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BpC;;;;;;;;;;;;OAYG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBpC;;OAEG;YACW,qBAAqB;IAOnC;;;;;OAKG;YACW,gBAAgB;IA8B9B;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages label transitions on GitHub issues throughout the worker's phase loop.
|
|
3
|
+
*
|
|
4
|
+
* Each phase transition updates labels to reflect the current workflow state:
|
|
5
|
+
* - `phase:<name>` — the phase currently being executed
|
|
6
|
+
* - `completed:<name>` — a phase that finished successfully
|
|
7
|
+
* - `waiting-for:<gate>` — the workflow is paused at a review gate
|
|
8
|
+
* - `agent:paused` — the agent is waiting for human input
|
|
9
|
+
* - `agent:error` — the agent encountered an error
|
|
10
|
+
* - `agent:in-progress` — the agent is actively processing
|
|
11
|
+
*/
|
|
12
|
+
export class LabelManager {
|
|
13
|
+
github;
|
|
14
|
+
owner;
|
|
15
|
+
repo;
|
|
16
|
+
issueNumber;
|
|
17
|
+
logger;
|
|
18
|
+
constructor(github, owner, repo, issueNumber, logger) {
|
|
19
|
+
this.github = github;
|
|
20
|
+
this.owner = owner;
|
|
21
|
+
this.repo = repo;
|
|
22
|
+
this.issueNumber = issueNumber;
|
|
23
|
+
this.logger = logger;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Called when a phase begins execution.
|
|
27
|
+
*
|
|
28
|
+
* Adds `phase:<current>` label and removes any previous `phase:*` labels.
|
|
29
|
+
*/
|
|
30
|
+
async onPhaseStart(phase) {
|
|
31
|
+
await this.retryWithBackoff(async () => {
|
|
32
|
+
const currentLabels = await this.getCurrentPhaseLabels();
|
|
33
|
+
const phaseLabel = `phase:${phase}`;
|
|
34
|
+
// Remove any existing phase labels that aren't the new one
|
|
35
|
+
const labelsToRemove = currentLabels.filter((l) => l !== phaseLabel);
|
|
36
|
+
if (labelsToRemove.length > 0) {
|
|
37
|
+
this.logger.info({ labels: labelsToRemove, issue: this.issueNumber }, `Removing previous phase labels: ${labelsToRemove.join(', ')}`);
|
|
38
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, labelsToRemove);
|
|
39
|
+
}
|
|
40
|
+
// Add the new phase label
|
|
41
|
+
this.logger.info({ label: phaseLabel, issue: this.issueNumber }, `Adding phase label: ${phaseLabel}`);
|
|
42
|
+
await this.github.addLabels(this.owner, this.repo, this.issueNumber, [phaseLabel]);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Called when a phase completes successfully.
|
|
47
|
+
*
|
|
48
|
+
* Adds `completed:<current>` label and removes `phase:<current>` label.
|
|
49
|
+
*/
|
|
50
|
+
async onPhaseComplete(phase) {
|
|
51
|
+
await this.retryWithBackoff(async () => {
|
|
52
|
+
const phaseLabel = `phase:${phase}`;
|
|
53
|
+
const completedLabel = `completed:${phase}`;
|
|
54
|
+
this.logger.info({ phase, issue: this.issueNumber }, `Phase complete: removing ${phaseLabel}, adding ${completedLabel}`);
|
|
55
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, [phaseLabel]);
|
|
56
|
+
await this.github.addLabels(this.owner, this.repo, this.issueNumber, [completedLabel]);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Called when a gate is hit and the workflow must pause for human review.
|
|
61
|
+
*
|
|
62
|
+
* Adds `waiting-for:<gate>` and `agent:paused` labels, removes `phase:<current>`.
|
|
63
|
+
*/
|
|
64
|
+
async onGateHit(phase, gateLabel) {
|
|
65
|
+
await this.retryWithBackoff(async () => {
|
|
66
|
+
const phaseLabel = `phase:${phase}`;
|
|
67
|
+
const completedLabel = `completed:${phase}`;
|
|
68
|
+
this.logger.info({ phase, gateLabel, issue: this.issueNumber }, `Gate hit: removing ${phaseLabel} and ${completedLabel}, adding ${gateLabel} and agent:paused`);
|
|
69
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, [
|
|
70
|
+
phaseLabel,
|
|
71
|
+
completedLabel,
|
|
72
|
+
]);
|
|
73
|
+
await this.github.addLabels(this.owner, this.repo, this.issueNumber, [
|
|
74
|
+
gateLabel,
|
|
75
|
+
'agent:paused',
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Called when an error occurs during phase execution.
|
|
81
|
+
*
|
|
82
|
+
* Adds `agent:error` label and removes `phase:<current>`.
|
|
83
|
+
*/
|
|
84
|
+
async onError(phase) {
|
|
85
|
+
await this.retryWithBackoff(async () => {
|
|
86
|
+
const phaseLabel = `phase:${phase}`;
|
|
87
|
+
this.logger.info({ phase, issue: this.issueNumber }, `Error in phase: removing ${phaseLabel} and agent:in-progress, adding agent:error`);
|
|
88
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, [
|
|
89
|
+
phaseLabel,
|
|
90
|
+
'agent:in-progress',
|
|
91
|
+
]);
|
|
92
|
+
await this.github.addLabels(this.owner, this.repo, this.issueNumber, ['agent:error']);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Called when the entire workflow completes (all phases finished).
|
|
97
|
+
*
|
|
98
|
+
* Removes the `agent:in-progress` label.
|
|
99
|
+
*/
|
|
100
|
+
async onWorkflowComplete() {
|
|
101
|
+
await this.retryWithBackoff(async () => {
|
|
102
|
+
this.logger.info({ issue: this.issueNumber }, 'Workflow complete: removing agent:in-progress');
|
|
103
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, [
|
|
104
|
+
'agent:in-progress',
|
|
105
|
+
]);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Called at the start of a resume (continue command) before the phase loop.
|
|
110
|
+
*
|
|
111
|
+
* Removes stale `waiting-for:*` and `agent:paused` labels that were set
|
|
112
|
+
* when the workflow paused at a gate, and adds `agent:in-progress` to
|
|
113
|
+
* reflect the active workflow state.
|
|
114
|
+
*/
|
|
115
|
+
async onResumeStart() {
|
|
116
|
+
await this.retryWithBackoff(async () => {
|
|
117
|
+
const issue = await this.github.getIssue(this.owner, this.repo, this.issueNumber);
|
|
118
|
+
const currentLabels = issue.labels.map((l) => typeof l === 'string' ? l : l.name);
|
|
119
|
+
const labelsToRemove = currentLabels.filter((l) => l.startsWith('waiting-for:') || l === 'agent:paused');
|
|
120
|
+
if (labelsToRemove.length > 0) {
|
|
121
|
+
this.logger.info({ labels: labelsToRemove, issue: this.issueNumber }, 'Resume: removing waiting-for and agent:paused labels');
|
|
122
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, labelsToRemove);
|
|
123
|
+
}
|
|
124
|
+
// Add agent:in-progress to reflect active workflow state
|
|
125
|
+
this.logger.info({ issue: this.issueNumber }, 'Resume: adding agent:in-progress label');
|
|
126
|
+
await this.github.addLabels(this.owner, this.repo, this.issueNumber, ['agent:in-progress']);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Ensures `agent:in-progress` and any lingering `phase:*` labels are removed.
|
|
131
|
+
*
|
|
132
|
+
* Designed to be called from `finally` blocks and reaper loops — this method
|
|
133
|
+
* never throws. If the GitHub API call fails after retries, the error is logged
|
|
134
|
+
* at `warn` level and swallowed.
|
|
135
|
+
*
|
|
136
|
+
* Safe to call when labels have already been removed (idempotent):
|
|
137
|
+
* `removeLabels()` in `gh-cli.ts` checks for "not found" in stderr and
|
|
138
|
+
* silently ignores it, so removing an already-absent label is a no-op.
|
|
139
|
+
* This also means `onWorkflowComplete()` is idempotent — calling it when
|
|
140
|
+
* `agent:in-progress` has already been removed will not throw.
|
|
141
|
+
*/
|
|
142
|
+
async ensureCleanup() {
|
|
143
|
+
try {
|
|
144
|
+
const currentLabels = await this.getCurrentPhaseLabels();
|
|
145
|
+
const labelsToRemove = ['agent:in-progress', ...currentLabels];
|
|
146
|
+
if (labelsToRemove.length > 0) {
|
|
147
|
+
this.logger.info({ labels: labelsToRemove, issue: this.issueNumber }, 'Ensuring cleanup: removing agent:in-progress and phase labels');
|
|
148
|
+
await this.retryWithBackoff(async () => {
|
|
149
|
+
await this.github.removeLabels(this.owner, this.repo, this.issueNumber, labelsToRemove);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// Never throw from cleanup — log and move on
|
|
155
|
+
this.logger.warn({ error: String(error), issue: this.issueNumber }, 'Failed to ensure label cleanup (non-fatal)');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Fetch current labels on the issue and return those matching the `phase:*` pattern.
|
|
160
|
+
*/
|
|
161
|
+
async getCurrentPhaseLabels() {
|
|
162
|
+
const issue = await this.github.getIssue(this.owner, this.repo, this.issueNumber);
|
|
163
|
+
return issue.labels
|
|
164
|
+
.map((label) => (typeof label === 'string' ? label : label.name))
|
|
165
|
+
.filter((name) => name.startsWith('phase:'));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Retry an async operation with exponential backoff.
|
|
169
|
+
*
|
|
170
|
+
* Attempts the operation up to 3 times with delays of 1000ms, 2000ms, and 4000ms
|
|
171
|
+
* between attempts. The final attempt's error is re-thrown.
|
|
172
|
+
*/
|
|
173
|
+
async retryWithBackoff(fn) {
|
|
174
|
+
const maxAttempts = 3;
|
|
175
|
+
const delays = [1000, 2000, 4000];
|
|
176
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
177
|
+
try {
|
|
178
|
+
return await fn();
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (attempt === maxAttempts) {
|
|
182
|
+
this.logger.error({ attempt, error: String(error), issue: this.issueNumber }, `Label operation failed after ${maxAttempts} attempts`);
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
const delay = delays[attempt - 1];
|
|
186
|
+
this.logger.warn({ attempt, delay, error: String(error), issue: this.issueNumber }, `Label operation failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay}ms`);
|
|
187
|
+
await this.sleep(delay);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Unreachable, but satisfies TypeScript
|
|
191
|
+
throw new Error('retryWithBackoff: unexpected exit');
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Sleep for the given number of milliseconds.
|
|
195
|
+
*/
|
|
196
|
+
sleep(ms) {
|
|
197
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=label-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label-manager.js","sourceRoot":"","sources":["../../src/worker/label-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { OutputChunk, Logger } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Callback for SSE event emission
|
|
4
|
+
*/
|
|
5
|
+
export type SSEEventEmitter = (event: {
|
|
6
|
+
type: 'workflow:started' | 'step:started' | 'step:completed' | 'workflow:completed' | 'workflow:failed';
|
|
7
|
+
workflowId: string;
|
|
8
|
+
data: Record<string, unknown>;
|
|
9
|
+
}) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Parses newline-delimited JSON from Claude CLI stdout and emits SSE events.
|
|
12
|
+
*
|
|
13
|
+
* Claude CLI outputs one JSON object per line. This class accumulates raw
|
|
14
|
+
* string chunks (which may arrive mid-line), splits on newline boundaries,
|
|
15
|
+
* parses each complete line, and optionally emits SSE events for key
|
|
16
|
+
* lifecycle moments.
|
|
17
|
+
*/
|
|
18
|
+
export declare class OutputCapture {
|
|
19
|
+
private readonly workflowId;
|
|
20
|
+
private readonly logger;
|
|
21
|
+
private readonly emitter?;
|
|
22
|
+
private buffer;
|
|
23
|
+
private lineBuffer;
|
|
24
|
+
/** Session ID extracted from the Claude CLI `init` event (if present). */
|
|
25
|
+
private _sessionId;
|
|
26
|
+
constructor(workflowId: string, logger: Logger, emitter?: SSEEventEmitter | undefined);
|
|
27
|
+
/**
|
|
28
|
+
* Get the Claude CLI session ID captured from the `init` event.
|
|
29
|
+
* Returns undefined if no session ID has been received yet.
|
|
30
|
+
*/
|
|
31
|
+
get sessionId(): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Process a chunk of stdout data from Claude CLI.
|
|
34
|
+
* Parses newline-delimited JSON lines.
|
|
35
|
+
*/
|
|
36
|
+
processChunk(chunk: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Flush any remaining data in the line buffer.
|
|
39
|
+
*/
|
|
40
|
+
flush(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get all captured output chunks.
|
|
43
|
+
*/
|
|
44
|
+
getOutput(): OutputChunk[];
|
|
45
|
+
/**
|
|
46
|
+
* Clear the output buffer.
|
|
47
|
+
*/
|
|
48
|
+
clear(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Parse a single line of JSON and push the resulting OutputChunk.
|
|
51
|
+
*/
|
|
52
|
+
private parseLine;
|
|
53
|
+
/**
|
|
54
|
+
* Emit SSE events based on the chunk type.
|
|
55
|
+
*/
|
|
56
|
+
private emitSSEEvent;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=output-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-capture.d.ts","sourceRoot":"","sources":["../../src/worker/output-capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AActD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE;IACpC,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;IACxG,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,KAAK,IAAI,CAAC;AAEX;;;;;;;GAOG;AACH,qBAAa,aAAa;IAQtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAT3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAAM;IAExB,0EAA0E;IAC1E,OAAO,CAAC,UAAU,CAAqB;gBAGpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,eAAe,YAAA;IAG5C;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkBjC;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,OAAO,CAAC,SAAS;IA4CjB;;OAEG;IACH,OAAO,CAAC,YAAY;CAkCrB"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Valid OutputChunk type values recognized from Claude CLI JSON output.
|
|
3
|
+
*/
|
|
4
|
+
const KNOWN_TYPES = new Set([
|
|
5
|
+
'init',
|
|
6
|
+
'tool_use',
|
|
7
|
+
'tool_result',
|
|
8
|
+
'text',
|
|
9
|
+
'complete',
|
|
10
|
+
'error',
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* Parses newline-delimited JSON from Claude CLI stdout and emits SSE events.
|
|
14
|
+
*
|
|
15
|
+
* Claude CLI outputs one JSON object per line. This class accumulates raw
|
|
16
|
+
* string chunks (which may arrive mid-line), splits on newline boundaries,
|
|
17
|
+
* parses each complete line, and optionally emits SSE events for key
|
|
18
|
+
* lifecycle moments.
|
|
19
|
+
*/
|
|
20
|
+
export class OutputCapture {
|
|
21
|
+
workflowId;
|
|
22
|
+
logger;
|
|
23
|
+
emitter;
|
|
24
|
+
buffer = [];
|
|
25
|
+
lineBuffer = '';
|
|
26
|
+
/** Session ID extracted from the Claude CLI `init` event (if present). */
|
|
27
|
+
_sessionId;
|
|
28
|
+
constructor(workflowId, logger, emitter) {
|
|
29
|
+
this.workflowId = workflowId;
|
|
30
|
+
this.logger = logger;
|
|
31
|
+
this.emitter = emitter;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the Claude CLI session ID captured from the `init` event.
|
|
35
|
+
* Returns undefined if no session ID has been received yet.
|
|
36
|
+
*/
|
|
37
|
+
get sessionId() {
|
|
38
|
+
return this._sessionId;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Process a chunk of stdout data from Claude CLI.
|
|
42
|
+
* Parses newline-delimited JSON lines.
|
|
43
|
+
*/
|
|
44
|
+
processChunk(chunk) {
|
|
45
|
+
this.lineBuffer += chunk;
|
|
46
|
+
const lines = this.lineBuffer.split('\n');
|
|
47
|
+
// The last element is either an empty string (if chunk ended with \n)
|
|
48
|
+
// or an incomplete line that we keep in the buffer.
|
|
49
|
+
this.lineBuffer = lines.pop() ?? '';
|
|
50
|
+
for (const line of lines) {
|
|
51
|
+
const trimmed = line.trim();
|
|
52
|
+
if (trimmed.length === 0) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
this.parseLine(trimmed);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Flush any remaining data in the line buffer.
|
|
60
|
+
*/
|
|
61
|
+
flush() {
|
|
62
|
+
const remaining = this.lineBuffer.trim();
|
|
63
|
+
this.lineBuffer = '';
|
|
64
|
+
if (remaining.length === 0) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.parseLine(remaining);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get all captured output chunks.
|
|
71
|
+
*/
|
|
72
|
+
getOutput() {
|
|
73
|
+
return [...this.buffer];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Clear the output buffer.
|
|
77
|
+
*/
|
|
78
|
+
clear() {
|
|
79
|
+
this.buffer = [];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Parse a single line of JSON and push the resulting OutputChunk.
|
|
83
|
+
*/
|
|
84
|
+
parseLine(line) {
|
|
85
|
+
let parsed;
|
|
86
|
+
try {
|
|
87
|
+
parsed = JSON.parse(line);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
this.logger.debug({ line }, 'Non-JSON line from Claude CLI, treating as text');
|
|
91
|
+
const chunk = {
|
|
92
|
+
type: 'text',
|
|
93
|
+
data: { text: line },
|
|
94
|
+
timestamp: new Date().toISOString(),
|
|
95
|
+
};
|
|
96
|
+
this.buffer.push(chunk);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const rawType = typeof parsed.type === 'string' ? parsed.type : 'text';
|
|
100
|
+
const type = KNOWN_TYPES.has(rawType)
|
|
101
|
+
? rawType
|
|
102
|
+
: 'text';
|
|
103
|
+
// Extract metadata from tool_result chunks (e.g., filePath)
|
|
104
|
+
let metadata;
|
|
105
|
+
if (type === 'tool_result' && typeof parsed.filePath === 'string') {
|
|
106
|
+
metadata = { filePath: parsed.filePath };
|
|
107
|
+
}
|
|
108
|
+
const chunk = {
|
|
109
|
+
type,
|
|
110
|
+
data: parsed,
|
|
111
|
+
...(metadata ? { metadata } : {}),
|
|
112
|
+
timestamp: new Date().toISOString(),
|
|
113
|
+
};
|
|
114
|
+
// Extract session_id from init events for conversation resume support
|
|
115
|
+
if (type === 'init' && typeof parsed.session_id === 'string') {
|
|
116
|
+
this._sessionId = parsed.session_id;
|
|
117
|
+
this.logger.debug({ sessionId: this._sessionId }, 'Captured Claude CLI session ID');
|
|
118
|
+
}
|
|
119
|
+
this.buffer.push(chunk);
|
|
120
|
+
this.emitSSEEvent(chunk);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Emit SSE events based on the chunk type.
|
|
124
|
+
*/
|
|
125
|
+
emitSSEEvent(chunk) {
|
|
126
|
+
if (!this.emitter) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
switch (chunk.type) {
|
|
130
|
+
case 'init':
|
|
131
|
+
this.emitter({
|
|
132
|
+
type: 'step:started',
|
|
133
|
+
workflowId: this.workflowId,
|
|
134
|
+
data: { timestamp: chunk.timestamp, output: chunk.data },
|
|
135
|
+
});
|
|
136
|
+
break;
|
|
137
|
+
case 'complete':
|
|
138
|
+
this.emitter({
|
|
139
|
+
type: 'step:completed',
|
|
140
|
+
workflowId: this.workflowId,
|
|
141
|
+
data: { timestamp: chunk.timestamp, output: chunk.data },
|
|
142
|
+
});
|
|
143
|
+
break;
|
|
144
|
+
case 'error':
|
|
145
|
+
this.logger.warn({ workflowId: this.workflowId, error: chunk.data }, 'Error chunk received from Claude CLI');
|
|
146
|
+
break;
|
|
147
|
+
default:
|
|
148
|
+
// No SSE event for other chunk types
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=output-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-capture.js","sourceRoot":"","sources":["../../src/worker/output-capture.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAsB;IAC/C,MAAM;IACN,UAAU;IACV,aAAa;IACb,MAAM;IACN,UAAU;IACV,OAAO;CACR,CAAC,CAAC;AAWH;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IAQL;IACA;IACA;IATX,MAAM,GAAkB,EAAE,CAAC;IAC3B,UAAU,GAAG,EAAE,CAAC;IAExB,0EAA0E;IAClE,UAAU,CAAqB;IAEvC,YACmB,UAAkB,EAClB,MAAc,EACd,OAAyB;QAFzB,eAAU,GAAV,UAAU,CAAQ;QAClB,WAAM,GAAN,MAAM,CAAQ;QACd,YAAO,GAAP,OAAO,CAAkB;IACzC,CAAC;IAEJ;;;OAGG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,KAAa;QACxB,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC;QAEzB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,sEAAsE;QACtE,oDAAoD;QACpD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QAErB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,IAAY;QAC5B,IAAI,MAA+B,CAAC;QAEpC,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,iDAAiD,CAAC,CAAC;YAC/E,MAAM,KAAK,GAAgB;gBACzB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;gBACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QACvE,MAAM,IAAI,GAAwB,WAAW,CAAC,GAAG,CAAC,OAA8B,CAAC;YAC/E,CAAC,CAAE,OAA+B;YAClC,CAAC,CAAC,MAAM,CAAC;QAEX,4DAA4D;QAC5D,IAAI,QAA4C,CAAC;QACjD,IAAI,IAAI,KAAK,aAAa,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClE,QAAQ,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC3C,CAAC;QAED,MAAM,KAAK,GAAgB;YACzB,IAAI;YACJ,IAAI,EAAE,MAAM;YACZ,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,sEAAsE;QACtE,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC7D,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,gCAAgC,CAAC,CAAC;QACtF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,KAAkB;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,IAAI,CAAC,OAAO,CAAC;oBACX,IAAI,EAAE,cAAc;oBACpB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE;iBACzD,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,UAAU;gBACb,IAAI,CAAC,OAAO,CAAC;oBACX,IAAI,EAAE,gBAAgB;oBACtB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE;iBACzD,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,OAAO;gBACV,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAClD,sCAAsC,CACvC,CAAC;gBACF,MAAM;YAER;gBACE,qCAAqC;gBACrC,MAAM;QACV,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { WorkerContext, PhaseResult, Logger, WorkflowPhase } from './types.js';
|
|
2
|
+
import type { WorkerConfig } from './config.js';
|
|
3
|
+
import type { LabelManager } from './label-manager.js';
|
|
4
|
+
import type { StageCommentManager } from './stage-comment-manager.js';
|
|
5
|
+
import type { GateChecker } from './gate-checker.js';
|
|
6
|
+
import type { CliSpawner } from './cli-spawner.js';
|
|
7
|
+
import type { OutputCapture } from './output-capture.js';
|
|
8
|
+
import type { PrManager } from './pr-manager.js';
|
|
9
|
+
/**
|
|
10
|
+
* Dependencies injected into the PhaseLoop.
|
|
11
|
+
*/
|
|
12
|
+
export interface PhaseLoopDeps {
|
|
13
|
+
labelManager: LabelManager;
|
|
14
|
+
stageCommentManager: StageCommentManager;
|
|
15
|
+
gateChecker: GateChecker;
|
|
16
|
+
cliSpawner: CliSpawner;
|
|
17
|
+
outputCapture: OutputCapture;
|
|
18
|
+
prManager: PrManager;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Result of a complete phase loop execution.
|
|
22
|
+
*/
|
|
23
|
+
export interface PhaseLoopResult {
|
|
24
|
+
/** All phase results from the loop */
|
|
25
|
+
results: PhaseResult[];
|
|
26
|
+
/** Whether the entire loop completed successfully */
|
|
27
|
+
completed: boolean;
|
|
28
|
+
/** The last phase that was executed */
|
|
29
|
+
lastPhase: string;
|
|
30
|
+
/** Whether the loop was stopped by a gate */
|
|
31
|
+
gateHit: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Iterates through workflow phases from the starting phase to completion.
|
|
35
|
+
*
|
|
36
|
+
* For each phase the loop:
|
|
37
|
+
* 1. Updates labels to reflect the current phase
|
|
38
|
+
* 2. Spawns the Claude CLI (or runs the validate command)
|
|
39
|
+
* 3. Marks the phase as completed
|
|
40
|
+
* 4. Checks for review gates
|
|
41
|
+
* 5. Updates the stage comment with progress
|
|
42
|
+
*
|
|
43
|
+
* The loop stops on:
|
|
44
|
+
* - Gate hit (workflow paused for human review)
|
|
45
|
+
* - Phase failure (error)
|
|
46
|
+
* - Abort signal
|
|
47
|
+
* - All phases completed
|
|
48
|
+
*/
|
|
49
|
+
export declare class PhaseLoop {
|
|
50
|
+
private readonly logger;
|
|
51
|
+
constructor(logger: Logger);
|
|
52
|
+
/**
|
|
53
|
+
* Execute the phase loop from the starting phase through to completion.
|
|
54
|
+
*
|
|
55
|
+
* @param phaseSequence - Optional workflow-specific phase sequence.
|
|
56
|
+
* Defaults to the global PHASE_SEQUENCE for backward compatibility.
|
|
57
|
+
*/
|
|
58
|
+
executeLoop(context: WorkerContext, config: WorkerConfig, deps: PhaseLoopDeps, phaseSequence?: WorkflowPhase[]): Promise<PhaseLoopResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Build a phase progress array for stage comment updates.
|
|
61
|
+
*/
|
|
62
|
+
private buildPhaseProgress;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=phase-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-loop.d.ts","sourceRoot":"","sources":["../../src/worker/phase-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,qDAAqD;IACrD,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAE3C;;;;;OAKG;IACG,WAAW,CACf,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,aAAa,EACnB,aAAa,CAAC,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,eAAe,CAAC;IA+K3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAwB3B"}
|