@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.
- package/dist/ansi-stripper.d.ts +11 -0
- package/dist/ansi-stripper.d.ts.map +1 -0
- package/dist/ansi-stripper.js +19 -0
- package/dist/ansi-stripper.js.map +1 -0
- package/dist/capability-detector.d.ts +5 -0
- package/dist/capability-detector.d.ts.map +1 -0
- package/dist/capability-detector.js +43 -0
- package/dist/capability-detector.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +144 -0
- package/dist/config.js.map +1 -0
- package/dist/executor/base.executor.d.ts +55 -0
- package/dist/executor/base.executor.d.ts.map +1 -0
- package/dist/executor/base.executor.js +30 -0
- package/dist/executor/base.executor.js.map +1 -0
- package/dist/executor/claude.executor.d.ts +23 -0
- package/dist/executor/claude.executor.d.ts.map +1 -0
- package/dist/executor/claude.executor.js +106 -0
- package/dist/executor/claude.executor.js.map +1 -0
- package/dist/executor/codex.executor.d.ts +20 -0
- package/dist/executor/codex.executor.d.ts.map +1 -0
- package/dist/executor/codex.executor.js +51 -0
- package/dist/executor/codex.executor.js.map +1 -0
- package/dist/executor/cursor.executor.d.ts +19 -0
- package/dist/executor/cursor.executor.d.ts.map +1 -0
- package/dist/executor/cursor.executor.js +46 -0
- package/dist/executor/cursor.executor.js.map +1 -0
- package/dist/executor/custom.executor.d.ts +21 -0
- package/dist/executor/custom.executor.d.ts.map +1 -0
- package/dist/executor/custom.executor.js +57 -0
- package/dist/executor/custom.executor.js.map +1 -0
- package/dist/executor/executor.factory.d.ts +9 -0
- package/dist/executor/executor.factory.d.ts.map +1 -0
- package/dist/executor/executor.factory.js +29 -0
- package/dist/executor/executor.factory.js.map +1 -0
- package/dist/git-operations.d.ts +23 -0
- package/dist/git-operations.d.ts.map +1 -0
- package/dist/git-operations.js +94 -0
- package/dist/git-operations.js.map +1 -0
- package/dist/hardware.d.ts +14 -0
- package/dist/hardware.d.ts.map +1 -0
- package/dist/hardware.js +92 -0
- package/dist/hardware.js.map +1 -0
- package/dist/healthz.d.ts +14 -0
- package/dist/healthz.d.ts.map +1 -0
- package/dist/healthz.js +104 -0
- package/dist/healthz.js.map +1 -0
- package/dist/jwt-manager.d.ts +23 -0
- package/dist/jwt-manager.d.ts.map +1 -0
- package/dist/jwt-manager.js +169 -0
- package/dist/jwt-manager.js.map +1 -0
- package/dist/lease-manager.d.ts +17 -0
- package/dist/lease-manager.d.ts.map +1 -0
- package/dist/lease-manager.js +62 -0
- package/dist/lease-manager.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +497 -0
- package/dist/main.js.map +1 -0
- package/dist/orphan-reaper.d.ts +6 -0
- package/dist/orphan-reaper.d.ts.map +1 -0
- package/dist/orphan-reaper.js +148 -0
- package/dist/orphan-reaper.js.map +1 -0
- package/dist/pipeline-parser.d.ts +14 -0
- package/dist/pipeline-parser.d.ts.map +1 -0
- package/dist/pipeline-parser.js +183 -0
- package/dist/pipeline-parser.js.map +1 -0
- package/dist/pipeline-runner.d.ts +120 -0
- package/dist/pipeline-runner.d.ts.map +1 -0
- package/dist/pipeline-runner.js +568 -0
- package/dist/pipeline-runner.js.map +1 -0
- package/dist/project-mutex.d.ts +14 -0
- package/dist/project-mutex.d.ts.map +1 -0
- package/dist/project-mutex.js +25 -0
- package/dist/project-mutex.js.map +1 -0
- package/dist/pty-manager.d.ts +50 -0
- package/dist/pty-manager.d.ts.map +1 -0
- package/dist/pty-manager.js +203 -0
- package/dist/pty-manager.js.map +1 -0
- package/dist/ringbuffer.d.ts +22 -0
- package/dist/ringbuffer.d.ts.map +1 -0
- package/dist/ringbuffer.js +57 -0
- package/dist/ringbuffer.js.map +1 -0
- package/dist/safe-env.d.ts +6 -0
- package/dist/safe-env.d.ts.map +1 -0
- package/dist/safe-env.js +19 -0
- package/dist/safe-env.js.map +1 -0
- package/dist/stage-detector.d.ts +62 -0
- package/dist/stage-detector.d.ts.map +1 -0
- package/dist/stage-detector.js +140 -0
- package/dist/stage-detector.js.map +1 -0
- package/dist/task-handler.d.ts +56 -0
- package/dist/task-handler.d.ts.map +1 -0
- package/dist/task-handler.js +296 -0
- package/dist/task-handler.js.map +1 -0
- package/dist/tunnel-manager.d.ts +34 -0
- package/dist/tunnel-manager.d.ts.map +1 -0
- package/dist/tunnel-manager.js +165 -0
- package/dist/tunnel-manager.js.map +1 -0
- package/dist/worker-client.d.ts +62 -0
- package/dist/worker-client.d.ts.map +1 -0
- package/dist/worker-client.js +303 -0
- package/dist/worker-client.js.map +1 -0
- package/dist/workspace-manager.d.ts +51 -0
- package/dist/workspace-manager.d.ts.map +1 -0
- package/dist/workspace-manager.js +276 -0
- package/dist/workspace-manager.js.map +1 -0
- 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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"}
|