@overlordai/worker 1.0.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.
Files changed (109) hide show
  1. package/dist/ansi-stripper.d.ts +11 -0
  2. package/dist/ansi-stripper.d.ts.map +1 -0
  3. package/dist/ansi-stripper.js +19 -0
  4. package/dist/ansi-stripper.js.map +1 -0
  5. package/dist/capability-detector.d.ts +5 -0
  6. package/dist/capability-detector.d.ts.map +1 -0
  7. package/dist/capability-detector.js +43 -0
  8. package/dist/capability-detector.js.map +1 -0
  9. package/dist/config.d.ts +27 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +144 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/executor/base.executor.d.ts +55 -0
  14. package/dist/executor/base.executor.d.ts.map +1 -0
  15. package/dist/executor/base.executor.js +30 -0
  16. package/dist/executor/base.executor.js.map +1 -0
  17. package/dist/executor/claude.executor.d.ts +23 -0
  18. package/dist/executor/claude.executor.d.ts.map +1 -0
  19. package/dist/executor/claude.executor.js +106 -0
  20. package/dist/executor/claude.executor.js.map +1 -0
  21. package/dist/executor/codex.executor.d.ts +20 -0
  22. package/dist/executor/codex.executor.d.ts.map +1 -0
  23. package/dist/executor/codex.executor.js +51 -0
  24. package/dist/executor/codex.executor.js.map +1 -0
  25. package/dist/executor/cursor.executor.d.ts +19 -0
  26. package/dist/executor/cursor.executor.d.ts.map +1 -0
  27. package/dist/executor/cursor.executor.js +46 -0
  28. package/dist/executor/cursor.executor.js.map +1 -0
  29. package/dist/executor/custom.executor.d.ts +21 -0
  30. package/dist/executor/custom.executor.d.ts.map +1 -0
  31. package/dist/executor/custom.executor.js +57 -0
  32. package/dist/executor/custom.executor.js.map +1 -0
  33. package/dist/executor/executor.factory.d.ts +9 -0
  34. package/dist/executor/executor.factory.d.ts.map +1 -0
  35. package/dist/executor/executor.factory.js +29 -0
  36. package/dist/executor/executor.factory.js.map +1 -0
  37. package/dist/git-operations.d.ts +23 -0
  38. package/dist/git-operations.d.ts.map +1 -0
  39. package/dist/git-operations.js +94 -0
  40. package/dist/git-operations.js.map +1 -0
  41. package/dist/hardware.d.ts +14 -0
  42. package/dist/hardware.d.ts.map +1 -0
  43. package/dist/hardware.js +92 -0
  44. package/dist/hardware.js.map +1 -0
  45. package/dist/healthz.d.ts +14 -0
  46. package/dist/healthz.d.ts.map +1 -0
  47. package/dist/healthz.js +104 -0
  48. package/dist/healthz.js.map +1 -0
  49. package/dist/jwt-manager.d.ts +23 -0
  50. package/dist/jwt-manager.d.ts.map +1 -0
  51. package/dist/jwt-manager.js +169 -0
  52. package/dist/jwt-manager.js.map +1 -0
  53. package/dist/lease-manager.d.ts +17 -0
  54. package/dist/lease-manager.d.ts.map +1 -0
  55. package/dist/lease-manager.js +62 -0
  56. package/dist/lease-manager.js.map +1 -0
  57. package/dist/main.d.ts +3 -0
  58. package/dist/main.d.ts.map +1 -0
  59. package/dist/main.js +497 -0
  60. package/dist/main.js.map +1 -0
  61. package/dist/orphan-reaper.d.ts +6 -0
  62. package/dist/orphan-reaper.d.ts.map +1 -0
  63. package/dist/orphan-reaper.js +148 -0
  64. package/dist/orphan-reaper.js.map +1 -0
  65. package/dist/pipeline-parser.d.ts +14 -0
  66. package/dist/pipeline-parser.d.ts.map +1 -0
  67. package/dist/pipeline-parser.js +183 -0
  68. package/dist/pipeline-parser.js.map +1 -0
  69. package/dist/pipeline-runner.d.ts +120 -0
  70. package/dist/pipeline-runner.d.ts.map +1 -0
  71. package/dist/pipeline-runner.js +568 -0
  72. package/dist/pipeline-runner.js.map +1 -0
  73. package/dist/project-mutex.d.ts +14 -0
  74. package/dist/project-mutex.d.ts.map +1 -0
  75. package/dist/project-mutex.js +25 -0
  76. package/dist/project-mutex.js.map +1 -0
  77. package/dist/pty-manager.d.ts +50 -0
  78. package/dist/pty-manager.d.ts.map +1 -0
  79. package/dist/pty-manager.js +203 -0
  80. package/dist/pty-manager.js.map +1 -0
  81. package/dist/ringbuffer.d.ts +22 -0
  82. package/dist/ringbuffer.d.ts.map +1 -0
  83. package/dist/ringbuffer.js +57 -0
  84. package/dist/ringbuffer.js.map +1 -0
  85. package/dist/safe-env.d.ts +6 -0
  86. package/dist/safe-env.d.ts.map +1 -0
  87. package/dist/safe-env.js +19 -0
  88. package/dist/safe-env.js.map +1 -0
  89. package/dist/stage-detector.d.ts +62 -0
  90. package/dist/stage-detector.d.ts.map +1 -0
  91. package/dist/stage-detector.js +140 -0
  92. package/dist/stage-detector.js.map +1 -0
  93. package/dist/task-handler.d.ts +56 -0
  94. package/dist/task-handler.d.ts.map +1 -0
  95. package/dist/task-handler.js +296 -0
  96. package/dist/task-handler.js.map +1 -0
  97. package/dist/tunnel-manager.d.ts +34 -0
  98. package/dist/tunnel-manager.d.ts.map +1 -0
  99. package/dist/tunnel-manager.js +165 -0
  100. package/dist/tunnel-manager.js.map +1 -0
  101. package/dist/worker-client.d.ts +62 -0
  102. package/dist/worker-client.d.ts.map +1 -0
  103. package/dist/worker-client.js +303 -0
  104. package/dist/worker-client.js.map +1 -0
  105. package/dist/workspace-manager.d.ts +51 -0
  106. package/dist/workspace-manager.d.ts.map +1 -0
  107. package/dist/workspace-manager.js +276 -0
  108. package/dist/workspace-manager.js.map +1 -0
  109. package/package.json +30 -0
@@ -0,0 +1,56 @@
1
+ import type { ExecuteTaskFrame, CancelTaskFrame, CleanupWorkspaceFrame, ResumeTaskFrame, ConfigSnapshot } from '@overlordai/protocol';
2
+ import { WorkerConfig } from './config.js';
3
+ import type { WorkspaceManager, WorkspaceInfo } from './workspace-manager.js';
4
+ import type { PtyManager, PtySession } from './pty-manager.js';
5
+ import { PipelineRunner, type LeaseChecker } from './pipeline-runner.js';
6
+ import type { StageConfirmMode, StageChoiceOption } from '@overlordai/protocol';
7
+ export interface TaskContext {
8
+ taskId: number;
9
+ description: string;
10
+ projectKey: string;
11
+ stage: string;
12
+ workspaceInfo: WorkspaceInfo | null;
13
+ ptySession: PtySession | null;
14
+ pipelineRunner: PipelineRunner | null;
15
+ channelToken: string;
16
+ configSnapshot: ConfigSnapshot;
17
+ abortController: AbortController;
18
+ }
19
+ type ProgressCallback = (taskId: number, stage: string, status: string, message?: string) => void;
20
+ type AckCallback = (msgId: string, payload?: Record<string, unknown>) => void;
21
+ type ConfirmRequestCallback = (taskId: number, stageIndex: number, mode: StageConfirmMode, timeout: number, prompt?: string, choices?: StageChoiceOption[]) => void;
22
+ export declare class TaskHandler {
23
+ private activeTasks;
24
+ private config;
25
+ private onProgress;
26
+ private onAck;
27
+ private onConfirmRequest;
28
+ private workspaceManager;
29
+ private ptyManager;
30
+ private leaseChecker;
31
+ constructor(config: WorkerConfig, onProgress: ProgressCallback, onAck: AckCallback, onConfirmRequest: ConfirmRequestCallback, workspaceManager: WorkspaceManager, ptyManager: PtyManager, leaseChecker: LeaseChecker);
32
+ getActiveTaskCount(): number;
33
+ getActiveTaskIds(): number[];
34
+ /**
35
+ * Wait until all active tasks have finished.
36
+ * Resolves immediately if no tasks are active.
37
+ */
38
+ waitForActiveTasks(): Promise<void>;
39
+ getActiveTaskStatuses(): Array<{
40
+ taskId: number;
41
+ localStatus: 'still_running' | 'completed_locally' | 'failed_locally';
42
+ currentStage?: string;
43
+ }>;
44
+ handleExecute(frame: ExecuteTaskFrame): Promise<void>;
45
+ handleCancel(frame: CancelTaskFrame): Promise<void>;
46
+ handleCleanupWorkspace(frame: CleanupWorkspaceFrame): Promise<void>;
47
+ handleStageConfirmResponse(taskId: number, stageIndex: number, result: string): void;
48
+ handleResume(frame: ResumeTaskFrame): Promise<void>;
49
+ /**
50
+ * Run the pipeline for a task using PipelineRunner.
51
+ * Creates a PipelineRunner instance, wires up events, and waits for completion.
52
+ */
53
+ private runPipeline;
54
+ }
55
+ export {};
56
+ //# sourceMappingURL=task-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-handler.d.ts","sourceRoot":"","sources":["../src/task-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,cAAc,EACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIhF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;CAClC;AAED,KAAK,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAClG,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAC9E,KAAK,sBAAsB,GAAG,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,iBAAiB,EAAE,KAC1B,IAAI,CAAC;AAEV,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAe;gBAGjC,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,WAAW,EAClB,gBAAgB,EAAE,sBAAsB,EACxC,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY;IAW5B,kBAAkB,IAAI,MAAM;IAI5B,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;;OAGG;IACH,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBnC,qBAAqB,IAAI,KAAK,CAAC;QAC7B,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,eAAe,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;QACtE,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAgBI,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqFrD,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBnD,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBzE,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAgB9E,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBzD;;;OAGG;IACH,OAAO,CAAC,WAAW;CAoEpB"}
@@ -0,0 +1,296 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.TaskHandler = void 0;
40
+ const fs = __importStar(require("node:fs"));
41
+ const pino_1 = __importDefault(require("pino"));
42
+ const pipeline_runner_js_1 = require("./pipeline-runner.js");
43
+ const log = (0, pino_1.default)({ name: 'task-handler' });
44
+ class TaskHandler {
45
+ activeTasks = new Map();
46
+ config;
47
+ onProgress;
48
+ onAck;
49
+ onConfirmRequest;
50
+ workspaceManager;
51
+ ptyManager;
52
+ leaseChecker;
53
+ constructor(config, onProgress, onAck, onConfirmRequest, workspaceManager, ptyManager, leaseChecker) {
54
+ this.config = config;
55
+ this.onProgress = onProgress;
56
+ this.onAck = onAck;
57
+ this.onConfirmRequest = onConfirmRequest;
58
+ this.workspaceManager = workspaceManager;
59
+ this.ptyManager = ptyManager;
60
+ this.leaseChecker = leaseChecker;
61
+ }
62
+ getActiveTaskCount() {
63
+ return this.activeTasks.size;
64
+ }
65
+ getActiveTaskIds() {
66
+ return Array.from(this.activeTasks.keys());
67
+ }
68
+ /**
69
+ * Wait until all active tasks have finished.
70
+ * Resolves immediately if no tasks are active.
71
+ */
72
+ waitForActiveTasks() {
73
+ if (this.activeTasks.size === 0) {
74
+ return Promise.resolve();
75
+ }
76
+ return new Promise((resolve) => {
77
+ const check = setInterval(() => {
78
+ if (this.activeTasks.size === 0) {
79
+ clearInterval(check);
80
+ resolve();
81
+ }
82
+ }, 500);
83
+ if (check.unref)
84
+ check.unref();
85
+ });
86
+ }
87
+ getActiveTaskStatuses() {
88
+ const statuses = [];
89
+ for (const [taskId, ctx] of this.activeTasks) {
90
+ statuses.push({
91
+ taskId,
92
+ localStatus: ctx.ptySession ? 'still_running' : 'completed_locally',
93
+ currentStage: ctx.stage,
94
+ });
95
+ }
96
+ return statuses;
97
+ }
98
+ async handleExecute(frame) {
99
+ const { taskId, description, projectKey, configSnapshot, developer, channelToken, msgId } = frame;
100
+ if (this.activeTasks.has(taskId)) {
101
+ log.warn({ taskId }, 'Task already active, ignoring duplicate execute');
102
+ this.onAck(msgId, { status: 'already_running' });
103
+ return;
104
+ }
105
+ log.info({ taskId, agentType: configSnapshot.agentType }, 'Executing task');
106
+ const abortController = new AbortController();
107
+ const ctx = {
108
+ taskId,
109
+ description,
110
+ projectKey,
111
+ stage: 'init',
112
+ workspaceInfo: null,
113
+ ptySession: null,
114
+ pipelineRunner: null,
115
+ channelToken,
116
+ configSnapshot,
117
+ abortController,
118
+ };
119
+ this.activeTasks.set(taskId, ctx);
120
+ // Ack the execute message
121
+ this.onAck(msgId, { status: 'accepted' });
122
+ this.onProgress(taskId, 'init', 'running', 'Initializing workspace');
123
+ try {
124
+ // 1. Initialize workspace via WorkspaceManager (bare clone, worktree, git config, setup commands)
125
+ const workspaceInfo = await this.workspaceManager.initialize({
126
+ taskId,
127
+ projectKey,
128
+ configSnapshot,
129
+ developer,
130
+ });
131
+ ctx.workspaceInfo = workspaceInfo;
132
+ if (abortController.signal.aborted) {
133
+ throw new Error('Task cancelled');
134
+ }
135
+ // 2. Create PTY session via PtyManager
136
+ ctx.stage = 'agent';
137
+ this.onProgress(taskId, 'agent', 'running', 'Starting agent');
138
+ const ptySession = this.ptyManager.createSession({
139
+ taskId,
140
+ workspacePath: workspaceInfo.path,
141
+ env: workspaceInfo.env,
142
+ configSnapshot,
143
+ developer,
144
+ });
145
+ ctx.ptySession = ptySession;
146
+ // 3. Run pipeline via PipelineRunner
147
+ await this.runPipeline(ctx, ptySession, description);
148
+ }
149
+ catch (err) {
150
+ if (abortController.signal.aborted) {
151
+ log.info({ taskId }, 'Task was cancelled');
152
+ this.onProgress(taskId, ctx.stage, 'cancelled', 'Task cancelled');
153
+ }
154
+ else {
155
+ const message = err instanceof Error ? err.message : String(err);
156
+ log.error({ taskId, err }, 'Task failed');
157
+ this.onProgress(taskId, ctx.stage, 'failed', message);
158
+ }
159
+ }
160
+ finally {
161
+ // Cleanup PTY session
162
+ if (ctx.ptySession) {
163
+ await this.ptyManager.closeSession(taskId);
164
+ ctx.ptySession = null;
165
+ }
166
+ // Destroy pipeline runner
167
+ if (ctx.pipelineRunner) {
168
+ ctx.pipelineRunner.destroy();
169
+ ctx.pipelineRunner = null;
170
+ }
171
+ this.activeTasks.delete(taskId);
172
+ }
173
+ }
174
+ async handleCancel(frame) {
175
+ const { taskId, msgId } = frame;
176
+ const ctx = this.activeTasks.get(taskId);
177
+ if (!ctx) {
178
+ log.warn({ taskId }, 'Cancel requested for unknown task');
179
+ this.onAck(msgId, { status: 'not_found' });
180
+ return;
181
+ }
182
+ log.info({ taskId }, 'Cancelling task');
183
+ this.onAck(msgId, { status: 'cancelling' });
184
+ // Signal the abort controller
185
+ ctx.abortController.abort();
186
+ // Cancel PTY session (SIGTERM -> grace -> SIGKILL)
187
+ await this.ptyManager.cancel(taskId);
188
+ }
189
+ async handleCleanupWorkspace(frame) {
190
+ const { taskId, workspacePath, msgId } = frame;
191
+ log.info({ taskId, workspacePath }, 'Cleaning up workspace');
192
+ try {
193
+ await this.workspaceManager.cleanup(taskId, workspacePath);
194
+ this.onAck(msgId, { status: 'cleaned' });
195
+ }
196
+ catch (err) {
197
+ // Fallback: try direct removal if worktree cleanup fails
198
+ log.warn({ taskId, workspacePath, err }, 'WorkspaceManager cleanup failed, trying direct removal');
199
+ try {
200
+ if (fs.existsSync(workspacePath)) {
201
+ fs.rmSync(workspacePath, { recursive: true, force: true });
202
+ log.info({ taskId, workspacePath }, 'Workspace force-removed');
203
+ }
204
+ this.onAck(msgId, { status: 'cleaned' });
205
+ }
206
+ catch (rmErr) {
207
+ log.error({ taskId, workspacePath, err: rmErr }, 'Failed to cleanup workspace');
208
+ this.onAck(msgId, { status: 'error', error: rmErr instanceof Error ? rmErr.message : String(rmErr) });
209
+ }
210
+ }
211
+ }
212
+ handleStageConfirmResponse(taskId, stageIndex, result) {
213
+ const ctx = this.activeTasks.get(taskId);
214
+ if (!ctx) {
215
+ log.warn({ taskId }, 'Stage confirm response for unknown task');
216
+ return;
217
+ }
218
+ if (!ctx.pipelineRunner) {
219
+ log.warn({ taskId }, 'Stage confirm response but no pipeline runner');
220
+ return;
221
+ }
222
+ ctx.pipelineRunner.confirmStage(taskId, stageIndex, result);
223
+ }
224
+ async handleResume(frame) {
225
+ const { taskId, msgId } = frame;
226
+ const ctx = this.activeTasks.get(taskId);
227
+ if (!ctx) {
228
+ log.warn({ taskId }, 'Resume requested for unknown task');
229
+ this.onAck(msgId, { status: 'not_found' });
230
+ return;
231
+ }
232
+ log.info({ taskId }, 'Resuming task');
233
+ this.onAck(msgId, { status: 'resuming' });
234
+ // Resume the pipeline runner if it exists
235
+ if (ctx.pipelineRunner) {
236
+ ctx.pipelineRunner.resume();
237
+ }
238
+ this.onProgress(taskId, ctx.stage, 'running', 'Task resumed');
239
+ }
240
+ /**
241
+ * Run the pipeline for a task using PipelineRunner.
242
+ * Creates a PipelineRunner instance, wires up events, and waits for completion.
243
+ */
244
+ runPipeline(ctx, ptySession, taskDescription) {
245
+ return new Promise((resolve, reject) => {
246
+ const { taskId, configSnapshot, abortController } = ctx;
247
+ // Adapt PtySession to the minimal interface PipelineRunner expects
248
+ const pipelinePtySession = {
249
+ write: (data) => ptySession.pty.write(data),
250
+ getCleanOutput: () => ptySession.cleanOutput,
251
+ resetCleanOutput: () => ptySession.resetCleanOutput(),
252
+ onData: (handler) => ptySession.onData(handler),
253
+ onExit: (handler) => ptySession.onExit(handler),
254
+ };
255
+ // Use the executor as a prompt detector
256
+ const promptDetector = {
257
+ detectPrompt: (output) => ptySession.executor.detectPrompt(output),
258
+ };
259
+ const runner = new pipeline_runner_js_1.PipelineRunner(taskId, ptySession.sessionId, pipelinePtySession, this.leaseChecker, promptDetector);
260
+ ctx.pipelineRunner = runner;
261
+ // Wire up pipeline events
262
+ runner.onStageChanged((tid, stageName) => {
263
+ ctx.stage = stageName;
264
+ this.onProgress(tid, stageName, 'running', `Stage: ${stageName}`);
265
+ });
266
+ runner.onCompleted((tid) => {
267
+ ctx.stage = 'completed';
268
+ this.onProgress(tid, 'completed', 'completed', 'Task completed successfully');
269
+ resolve();
270
+ });
271
+ runner.onFailed((tid, error) => {
272
+ if (abortController.signal.aborted) {
273
+ reject(new Error('Task cancelled'));
274
+ }
275
+ else {
276
+ reject(new Error(error));
277
+ }
278
+ });
279
+ runner.onConfirmRequired((tid, _stageName, mode, prompt, choices, timeout) => {
280
+ const stageIndex = runner.getState().currentStageIndex;
281
+ this.onConfirmRequest(tid, stageIndex, mode, timeout ?? 0, prompt, choices);
282
+ });
283
+ // Listen for abort
284
+ const onAbort = () => {
285
+ runner.destroy();
286
+ };
287
+ abortController.signal.addEventListener('abort', onAbort, { once: true });
288
+ // Start the pipeline
289
+ runner.start(configSnapshot.pipeline, taskDescription).catch((err) => {
290
+ reject(err);
291
+ });
292
+ });
293
+ }
294
+ }
295
+ exports.TaskHandler = TaskHandler;
296
+ //# sourceMappingURL=task-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-handler.js","sourceRoot":"","sources":["../src/task-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Manages Cursor remote tunnel processes for active tasks.
3
+ *
4
+ * TODO: Full implementation should:
5
+ * - Parse the tunnel URL from the `cursor --remote-tunnel` stdout
6
+ * - Handle tunnel process crashes and automatic restarts
7
+ * - Enforce tunnel TTL / expiry
8
+ * - Allocate and track ports
9
+ */
10
+ export declare class TunnelManager {
11
+ private tunnels;
12
+ /**
13
+ * Start a Cursor remote tunnel for the given task workspace.
14
+ * Returns the tunnel URL on success.
15
+ */
16
+ start(taskId: number, workspacePath: string): Promise<string>;
17
+ /**
18
+ * Stop the tunnel for the given task.
19
+ */
20
+ stop(taskId: number): Promise<void>;
21
+ /**
22
+ * Stop all active tunnels. Called during worker shutdown.
23
+ */
24
+ stopAll(): void;
25
+ /**
26
+ * Check whether a tunnel is active for the given task.
27
+ */
28
+ hasTunnel(taskId: number): boolean;
29
+ /**
30
+ * Get the tunnel URL for a task, or null if not available.
31
+ */
32
+ getTunnelUrl(taskId: number): string | null;
33
+ }
34
+ //# sourceMappingURL=tunnel-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-manager.d.ts","sourceRoot":"","sources":["../src/tunnel-manager.ts"],"names":[],"mappings":"AAaA;;;;;;;;GAQG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAkC;IAEjD;;;OAGG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmFnE;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCzC;;OAEG;IACH,OAAO,IAAI,IAAI;IAYf;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAG5C"}
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TunnelManager = void 0;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const pino_1 = __importDefault(require("pino"));
9
+ const safe_env_js_1 = require("./safe-env.js");
10
+ const log = (0, pino_1.default)({ name: 'tunnel-manager' });
11
+ /**
12
+ * Manages Cursor remote tunnel processes for active tasks.
13
+ *
14
+ * TODO: Full implementation should:
15
+ * - Parse the tunnel URL from the `cursor --remote-tunnel` stdout
16
+ * - Handle tunnel process crashes and automatic restarts
17
+ * - Enforce tunnel TTL / expiry
18
+ * - Allocate and track ports
19
+ */
20
+ class TunnelManager {
21
+ tunnels = new Map();
22
+ /**
23
+ * Start a Cursor remote tunnel for the given task workspace.
24
+ * Returns the tunnel URL on success.
25
+ */
26
+ async start(taskId, workspacePath) {
27
+ // If a tunnel already exists for this task, stop it first
28
+ if (this.tunnels.has(taskId)) {
29
+ log.warn({ taskId }, 'Tunnel already exists for task, stopping existing tunnel');
30
+ await this.stop(taskId);
31
+ }
32
+ log.info({ taskId, workspacePath }, 'Starting cursor remote tunnel');
33
+ return new Promise((resolve, reject) => {
34
+ let resolved = false;
35
+ let output = '';
36
+ // TODO: Replace with actual `cursor --remote-tunnel` invocation once
37
+ // the cursor CLI tunnel feature is available and tested.
38
+ // For now, spawn the process and attempt to extract a URL from stdout.
39
+ const child = (0, node_child_process_1.spawn)('cursor', ['--remote-tunnel', '--folder', workspacePath], {
40
+ stdio: ['ignore', 'pipe', 'pipe'],
41
+ env: (0, safe_env_js_1.buildSafeEnv)(),
42
+ });
43
+ const entry = {
44
+ taskId,
45
+ workspacePath,
46
+ process: child,
47
+ tunnelUrl: null,
48
+ };
49
+ this.tunnels.set(taskId, entry);
50
+ const timeout = setTimeout(() => {
51
+ if (!resolved) {
52
+ resolved = true;
53
+ child.kill('SIGTERM');
54
+ this.tunnels.delete(taskId);
55
+ log.warn({ taskId }, 'Tunnel start timed out, killing child process');
56
+ reject(new Error('Tunnel start timed out waiting for URL'));
57
+ }
58
+ }, 30_000);
59
+ child.stdout?.on('data', (data) => {
60
+ if (resolved)
61
+ return;
62
+ const chunk = data.toString();
63
+ output += chunk;
64
+ log.debug({ taskId, chunk: chunk.trim() }, 'Tunnel stdout');
65
+ // Attempt to extract tunnel URL from output
66
+ // Common patterns: https://... or vscode://...
67
+ const urlMatch = output.match(/https?:\/\/[^\s"'<>)\]},;]+/);
68
+ if (urlMatch && !resolved) {
69
+ resolved = true;
70
+ clearTimeout(timeout);
71
+ entry.tunnelUrl = urlMatch[0];
72
+ log.info({ taskId, tunnelUrl: entry.tunnelUrl }, 'Tunnel URL extracted');
73
+ resolve(entry.tunnelUrl);
74
+ }
75
+ });
76
+ child.stderr?.on('data', (data) => {
77
+ log.warn({ taskId, stderr: data.toString().trim() }, 'Tunnel stderr');
78
+ });
79
+ child.on('error', (err) => {
80
+ clearTimeout(timeout);
81
+ this.tunnels.delete(taskId);
82
+ if (!resolved) {
83
+ resolved = true;
84
+ log.error({ taskId, err }, 'Tunnel process failed to start');
85
+ reject(new Error(`Tunnel process error: ${err.message}`));
86
+ }
87
+ });
88
+ child.on('exit', (code, signal) => {
89
+ clearTimeout(timeout);
90
+ log.info({ taskId, code, signal }, 'Tunnel process exited');
91
+ this.tunnels.delete(taskId);
92
+ if (!resolved) {
93
+ resolved = true;
94
+ reject(new Error(`Tunnel process exited prematurely with code ${code}`));
95
+ }
96
+ });
97
+ });
98
+ }
99
+ /**
100
+ * Stop the tunnel for the given task.
101
+ */
102
+ async stop(taskId) {
103
+ const entry = this.tunnels.get(taskId);
104
+ if (!entry) {
105
+ log.debug({ taskId }, 'No tunnel found for task, nothing to stop');
106
+ return;
107
+ }
108
+ log.info({ taskId }, 'Stopping tunnel');
109
+ this.tunnels.delete(taskId);
110
+ return new Promise((resolve) => {
111
+ const child = entry.process;
112
+ // Give the process a chance to exit gracefully
113
+ const forceKillTimeout = setTimeout(() => {
114
+ try {
115
+ child.kill('SIGKILL');
116
+ }
117
+ catch {
118
+ // Process may already be dead
119
+ }
120
+ resolve();
121
+ }, 5_000);
122
+ child.once('exit', () => {
123
+ clearTimeout(forceKillTimeout);
124
+ resolve();
125
+ });
126
+ try {
127
+ child.kill('SIGTERM');
128
+ }
129
+ catch {
130
+ // Process may already be dead
131
+ clearTimeout(forceKillTimeout);
132
+ resolve();
133
+ }
134
+ });
135
+ }
136
+ /**
137
+ * Stop all active tunnels. Called during worker shutdown.
138
+ */
139
+ stopAll() {
140
+ for (const [taskId, entry] of this.tunnels) {
141
+ log.info({ taskId }, 'Stopping tunnel during shutdown');
142
+ try {
143
+ entry.process.kill('SIGTERM');
144
+ }
145
+ catch {
146
+ // Process may already be dead
147
+ }
148
+ }
149
+ this.tunnels.clear();
150
+ }
151
+ /**
152
+ * Check whether a tunnel is active for the given task.
153
+ */
154
+ hasTunnel(taskId) {
155
+ return this.tunnels.has(taskId);
156
+ }
157
+ /**
158
+ * Get the tunnel URL for a task, or null if not available.
159
+ */
160
+ getTunnelUrl(taskId) {
161
+ return this.tunnels.get(taskId)?.tunnelUrl ?? null;
162
+ }
163
+ }
164
+ exports.TunnelManager = TunnelManager;
165
+ //# sourceMappingURL=tunnel-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-manager.js","sourceRoot":"","sources":["../src/tunnel-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { ExecuteTaskFrame, CancelTaskFrame, CleanupWorkspaceFrame, ResumeTaskFrame, HeartbeatAckFrame, ServerShuttingDownFrame, RecoverySecretBootstrapFrame, StartTunnelFrame, StopTunnelFrame, StageConfirmResponseFrame } from '@overlordai/protocol';
2
+ import type { StageConfirmMode, StageChoiceOption } from '@overlordai/protocol';
3
+ export interface WorkerClientOptions {
4
+ overlordHost: string;
5
+ machineId: string;
6
+ getToken: () => string;
7
+ getCapabilities: () => string[];
8
+ getActiveSlots: () => number;
9
+ }
10
+ export interface WorkerClientHandlers {
11
+ onExecute: (frame: ExecuteTaskFrame) => void;
12
+ onCancel: (frame: CancelTaskFrame) => void;
13
+ onCleanupWorkspace: (frame: CleanupWorkspaceFrame) => void;
14
+ onResume: (frame: ResumeTaskFrame) => void;
15
+ onServerShuttingDown: (frame: ServerShuttingDownFrame) => void;
16
+ onRecoverySecretBootstrap: (frame: RecoverySecretBootstrapFrame) => void;
17
+ onHeartbeatAck: (frame: HeartbeatAckFrame) => void;
18
+ onStartTunnel: (frame: StartTunnelFrame) => void;
19
+ onStopTunnel: (frame: StopTunnelFrame) => void;
20
+ onStageConfirmResponse: (frame: StageConfirmResponseFrame) => void;
21
+ onConnected: () => void;
22
+ onDisconnected: () => void;
23
+ }
24
+ export declare class WorkerClient {
25
+ private ws;
26
+ private options;
27
+ private handlers;
28
+ private heartbeatTimer;
29
+ private reconnectTimer;
30
+ private reconnectDelay;
31
+ private connected;
32
+ private intentionalClose;
33
+ private dedupSet;
34
+ private dedupCleanupTimer;
35
+ constructor(options: WorkerClientOptions, handlers: WorkerClientHandlers);
36
+ isConnected(): boolean;
37
+ connect(): void;
38
+ disconnect(): void;
39
+ sendHeartbeat(): void;
40
+ sendAck(msgId: string, payload?: Record<string, unknown>): void;
41
+ sendProgress(taskId: number, stage: string, status: string, message?: string): void;
42
+ sendReconnect(tasks: Array<{
43
+ taskId: number;
44
+ localStatus: 'still_running' | 'completed_locally' | 'failed_locally';
45
+ currentStage?: string;
46
+ branch?: string;
47
+ mrUrl?: string;
48
+ errorMessage?: string;
49
+ }>): void;
50
+ sendRecoverySecretAck(): void;
51
+ sendStageConfirmRequest(taskId: number, stageIndex: number, mode: StageConfirmMode, timeout: number, prompt?: string, choices?: StageChoiceOption[]): void;
52
+ private sendFrame;
53
+ private handleMessage;
54
+ private buildWsUrl;
55
+ private startHeartbeat;
56
+ private stopHeartbeat;
57
+ private startDedupCleanup;
58
+ private stopDedupCleanup;
59
+ private scheduleReconnect;
60
+ private cleanup;
61
+ }
62
+ //# sourceMappingURL=worker-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-client.d.ts","sourceRoot":"","sources":["../src/worker-client.ts"],"names":[],"mappings":"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"}