@overlordai/worker 1.0.53 → 1.0.55
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/clean-output-buffer.d.ts +21 -0
- package/dist/clean-output-buffer.d.ts.map +1 -0
- package/dist/clean-output-buffer.js +70 -0
- package/dist/clean-output-buffer.js.map +1 -0
- package/dist/config.d.ts +4 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +54 -39
- package/dist/config.js.map +1 -1
- package/dist/executor/base.executor.d.ts +30 -11
- package/dist/executor/base.executor.d.ts.map +1 -1
- package/dist/executor/base.executor.js +25 -2
- package/dist/executor/base.executor.js.map +1 -1
- package/dist/executor/claude.executor.d.ts +7 -8
- package/dist/executor/claude.executor.d.ts.map +1 -1
- package/dist/executor/claude.executor.js +36 -26
- package/dist/executor/claude.executor.js.map +1 -1
- package/dist/executor/codex.executor.d.ts +7 -8
- package/dist/executor/codex.executor.d.ts.map +1 -1
- package/dist/executor/codex.executor.js +64 -26
- package/dist/executor/codex.executor.js.map +1 -1
- package/dist/executor/cursor.executor.d.ts +6 -7
- package/dist/executor/cursor.executor.d.ts.map +1 -1
- package/dist/executor/cursor.executor.js +12 -22
- package/dist/executor/cursor.executor.js.map +1 -1
- package/dist/executor/custom.executor.d.ts +15 -7
- package/dist/executor/custom.executor.d.ts.map +1 -1
- package/dist/executor/custom.executor.js +25 -28
- package/dist/executor/custom.executor.js.map +1 -1
- package/dist/git-operations.d.ts +14 -12
- package/dist/git-operations.d.ts.map +1 -1
- package/dist/git-operations.js +50 -98
- package/dist/git-operations.js.map +1 -1
- package/dist/git-token-helper.d.ts +27 -0
- package/dist/git-token-helper.d.ts.map +1 -0
- package/dist/git-token-helper.js +114 -0
- package/dist/git-token-helper.js.map +1 -0
- package/dist/healthz.d.ts.map +1 -1
- package/dist/healthz.js +3 -7
- package/dist/healthz.js.map +1 -1
- package/dist/http-post.d.ts +2 -0
- package/dist/http-post.d.ts.map +1 -0
- package/dist/http-post.js +74 -0
- package/dist/http-post.js.map +1 -0
- package/dist/jwt-manager.d.ts +2 -3
- package/dist/jwt-manager.d.ts.map +1 -1
- package/dist/jwt-manager.js +5 -43
- package/dist/jwt-manager.js.map +1 -1
- package/dist/lease-manager.d.ts +4 -1
- package/dist/lease-manager.d.ts.map +1 -1
- package/dist/lease-manager.js +2 -6
- package/dist/lease-manager.js.map +1 -1
- package/dist/main.js +147 -277
- package/dist/main.js.map +1 -1
- package/dist/orphan-reaper.d.ts +1 -1
- package/dist/orphan-reaper.d.ts.map +1 -1
- package/dist/orphan-reaper.js +46 -30
- package/dist/orphan-reaper.js.map +1 -1
- package/dist/pipeline-compiler.d.ts +10 -0
- package/dist/pipeline-compiler.d.ts.map +1 -0
- package/dist/pipeline-compiler.js +179 -0
- package/dist/pipeline-compiler.js.map +1 -0
- package/dist/pipeline-parser.d.ts.map +1 -1
- package/dist/pipeline-parser.js +4 -3
- package/dist/pipeline-parser.js.map +1 -1
- package/dist/pipeline-runner.d.ts +1 -0
- package/dist/pipeline-runner.d.ts.map +1 -1
- package/dist/pipeline-runner.js +37 -27
- package/dist/pipeline-runner.js.map +1 -1
- package/dist/project-mutex.d.ts +1 -0
- package/dist/project-mutex.d.ts.map +1 -1
- package/dist/project-mutex.js +9 -1
- package/dist/project-mutex.js.map +1 -1
- package/dist/pty-manager.d.ts +2 -0
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +68 -42
- package/dist/pty-manager.js.map +1 -1
- package/dist/pty-relay-client.d.ts +38 -0
- package/dist/pty-relay-client.d.ts.map +1 -0
- package/dist/pty-relay-client.js +146 -0
- package/dist/pty-relay-client.js.map +1 -0
- package/dist/pty-stdin-writer.d.ts +11 -0
- package/dist/pty-stdin-writer.d.ts.map +1 -0
- package/dist/pty-stdin-writer.js +22 -0
- package/dist/pty-stdin-writer.js.map +1 -0
- package/dist/ringbuffer.d.ts +2 -0
- package/dist/ringbuffer.d.ts.map +1 -1
- package/dist/ringbuffer.js +10 -1
- package/dist/ringbuffer.js.map +1 -1
- package/dist/stage-monitor.d.ts +72 -0
- package/dist/stage-monitor.d.ts.map +1 -0
- package/dist/stage-monitor.js +234 -0
- package/dist/stage-monitor.js.map +1 -0
- package/dist/task-handler.d.ts +18 -12
- package/dist/task-handler.d.ts.map +1 -1
- package/dist/task-handler.js +298 -78
- package/dist/task-handler.js.map +1 -1
- package/dist/tunnel-manager.d.ts +16 -6
- package/dist/tunnel-manager.d.ts.map +1 -1
- package/dist/tunnel-manager.js +117 -16
- package/dist/tunnel-manager.js.map +1 -1
- package/dist/worker-client.d.ts +16 -7
- package/dist/worker-client.d.ts.map +1 -1
- package/dist/worker-client.js +40 -52
- package/dist/worker-client.js.map +1 -1
- package/dist/workspace-manager.d.ts +1 -0
- package/dist/workspace-manager.d.ts.map +1 -1
- package/dist/workspace-manager.js +102 -82
- package/dist/workspace-manager.js.map +1 -1
- package/package.json +4 -2
|
@@ -1,8 +1,48 @@
|
|
|
1
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
|
+
};
|
|
2
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
39
|
exports.CodexExecutor = void 0;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
4
42
|
const protocol_1 = require("@overlordai/protocol");
|
|
5
43
|
const base_executor_js_1 = require("./base.executor.js");
|
|
44
|
+
const pino_1 = __importDefault(require("pino"));
|
|
45
|
+
const log = (0, pino_1.default)({ name: 'codex-executor' });
|
|
6
46
|
/**
|
|
7
47
|
* Executor for OpenAI Codex CLI.
|
|
8
48
|
*
|
|
@@ -11,41 +51,39 @@ const base_executor_js_1 = require("./base.executor.js");
|
|
|
11
51
|
*/
|
|
12
52
|
class CodexExecutor extends base_executor_js_1.AgentExecutor {
|
|
13
53
|
agentType = protocol_1.AgentType.CODEX;
|
|
54
|
+
authErrorPatterns = [
|
|
55
|
+
{ pattern: /Authentication failed|Please log in|invalid.*api.*key/i, failureType: 'auth_failure' },
|
|
56
|
+
{ pattern: /Rate limit exceeded|too many requests/i, failureType: 'rate_limit' },
|
|
57
|
+
{ pattern: /command not found|ENOENT/i, failureType: 'binary_missing' },
|
|
58
|
+
];
|
|
14
59
|
getStartCommand() {
|
|
15
60
|
return 'codex';
|
|
16
61
|
}
|
|
17
|
-
buildArgs(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
62
|
+
buildArgs(_config, _workspacePath) {
|
|
63
|
+
return ['--full-auto'];
|
|
64
|
+
}
|
|
65
|
+
prepareEnvironment(worktreePath, realHome) {
|
|
66
|
+
// Codex stores config in ~/.codex — symlink entire directory if it exists
|
|
67
|
+
try {
|
|
68
|
+
const src = path.join(realHome, '.codex');
|
|
69
|
+
if (!fs.existsSync(src))
|
|
70
|
+
return; // skip to avoid dangling symlink
|
|
71
|
+
const dst = path.join(worktreePath, '.codex');
|
|
72
|
+
fs.symlinkSync(src, dst);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
if (err.code !== 'EEXIST') {
|
|
76
|
+
log.warn({ worktreePath, err }, 'Codex environment setup failed (non-fatal)');
|
|
77
|
+
}
|
|
21
78
|
}
|
|
22
|
-
|
|
79
|
+
}
|
|
80
|
+
buildEnvVars(_realHome) {
|
|
81
|
+
return {};
|
|
23
82
|
}
|
|
24
83
|
detectPrompt(cleanOutput) {
|
|
25
84
|
// Match Codex's prompt indicators at end of output
|
|
26
85
|
return /[>❯]\s*$/.test(cleanOutput.trimEnd());
|
|
27
86
|
}
|
|
28
|
-
detectStageComplete(cleanOutput, stage) {
|
|
29
|
-
if (cleanOutput.includes(`${protocol_1.STAGE_DONE_SENTINEL}${stage}]]`)) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
detectAuthError(cleanOutput) {
|
|
35
|
-
if (/Authentication failed|Please log in|invalid.*api.*key/i.test(cleanOutput)) {
|
|
36
|
-
return { detected: true, failureType: 'auth_failure' };
|
|
37
|
-
}
|
|
38
|
-
if (/Rate limit exceeded|too many requests/i.test(cleanOutput)) {
|
|
39
|
-
return { detected: true, failureType: 'rate_limit' };
|
|
40
|
-
}
|
|
41
|
-
if (/command not found|ENOENT/i.test(cleanOutput)) {
|
|
42
|
-
return { detected: true, failureType: 'binary_missing' };
|
|
43
|
-
}
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
formatCommand(stage) {
|
|
47
|
-
return stage.command ?? stage.name;
|
|
48
|
-
}
|
|
49
87
|
}
|
|
50
88
|
exports.CodexExecutor = CodexExecutor;
|
|
51
89
|
//# sourceMappingURL=codex.executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.executor.js","sourceRoot":"","sources":["../../src/executor/codex.executor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codex.executor.js","sourceRoot":"","sources":["../../src/executor/codex.executor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAClC,mDAAiD;AAEjD,yDAAmD;AAEnD,gDAAwB;AAExB,MAAM,GAAG,GAAG,IAAA,cAAI,EAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAE7C;;;;;GAKG;AACH,MAAa,aAAc,SAAQ,gCAAa;IACrC,SAAS,GAAG,oBAAS,CAAC,KAAK,CAAC;IAElB,iBAAiB,GAAuB;QACzD,EAAE,OAAO,EAAE,wDAAwD,EAAE,WAAW,EAAE,cAAc,EAAE;QAClG,EAAE,OAAO,EAAE,wCAAwC,EAAE,WAAW,EAAE,YAAY,EAAE;QAChF,EAAE,OAAO,EAAE,2BAA2B,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACxE,CAAC;IAEF,eAAe;QACb,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,SAAS,CAAC,OAAuB,EAAE,cAAsB;QACvD,OAAO,CAAC,aAAa,CAAC,CAAC;IACzB,CAAC;IAED,kBAAkB,CAAC,YAAoB,EAAE,QAAgB;QACvD,0EAA0E;QAC1E,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,CAAC,iCAAiC;YAClE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAC9C,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1B,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,4CAA4C,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY,CAAC,WAAmB;QAC9B,mDAAmD;QACnD,OAAO,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;CACF;AAvCD,sCAuCC"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { ConfigSnapshot, StageConfig } from '@overlordai/protocol';
|
|
1
|
+
import type { ConfigSnapshot } from '@overlordai/protocol';
|
|
3
2
|
import { AgentExecutor } from './base.executor.js';
|
|
4
|
-
import type {
|
|
3
|
+
import type { AuthErrorPattern } from './base.executor.js';
|
|
5
4
|
/**
|
|
6
5
|
* Executor for Cursor Agent CLI.
|
|
7
6
|
*
|
|
8
7
|
* Uses --yolo flag for fully automated mode.
|
|
9
8
|
*/
|
|
10
9
|
export declare class CursorExecutor extends AgentExecutor {
|
|
11
|
-
readonly agentType
|
|
10
|
+
readonly agentType: "cursor";
|
|
11
|
+
protected readonly authErrorPatterns: AuthErrorPattern[];
|
|
12
12
|
getStartCommand(): string;
|
|
13
13
|
buildArgs(_config: ConfigSnapshot, _workspacePath: string): string[];
|
|
14
|
+
prepareEnvironment(_worktreePath: string, _realHome: string): void;
|
|
15
|
+
buildEnvVars(_realHome: string): Record<string, string>;
|
|
14
16
|
detectPrompt(cleanOutput: string): boolean;
|
|
15
|
-
detectStageComplete(cleanOutput: string, stage: string): boolean;
|
|
16
|
-
detectAuthError(cleanOutput: string): AuthErrorResult | null;
|
|
17
|
-
formatCommand(stage: StageConfig): string;
|
|
18
17
|
}
|
|
19
18
|
//# sourceMappingURL=cursor.executor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.executor.d.ts","sourceRoot":"","sources":["../../src/executor/cursor.executor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cursor.executor.d.ts","sourceRoot":"","sources":["../../src/executor/cursor.executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,aAAa;IAC/C,QAAQ,CAAC,SAAS,WAAoB;IAEtC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,CAItD;IAEF,eAAe,IAAI,MAAM;IAIzB,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;IAIpE,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIlE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvD,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;CAI3C"}
|
|
@@ -10,37 +10,27 @@ const base_executor_js_1 = require("./base.executor.js");
|
|
|
10
10
|
*/
|
|
11
11
|
class CursorExecutor extends base_executor_js_1.AgentExecutor {
|
|
12
12
|
agentType = protocol_1.AgentType.CURSOR;
|
|
13
|
+
authErrorPatterns = [
|
|
14
|
+
{ pattern: /Authentication failed|Please log in/i, failureType: 'auth_failure' },
|
|
15
|
+
{ pattern: /Rate limit exceeded/i, failureType: 'rate_limit' },
|
|
16
|
+
{ pattern: /command not found|ENOENT/i, failureType: 'binary_missing' },
|
|
17
|
+
];
|
|
13
18
|
getStartCommand() {
|
|
14
19
|
return 'cursor';
|
|
15
20
|
}
|
|
16
21
|
buildArgs(_config, _workspacePath) {
|
|
17
|
-
return ['--yolo'];
|
|
22
|
+
return ['agent', '--yolo'];
|
|
23
|
+
}
|
|
24
|
+
prepareEnvironment(_worktreePath, _realHome) {
|
|
25
|
+
// Cursor uses XDG .config/ which is already symlinked by workspace-manager
|
|
26
|
+
}
|
|
27
|
+
buildEnvVars(_realHome) {
|
|
28
|
+
return {};
|
|
18
29
|
}
|
|
19
30
|
detectPrompt(cleanOutput) {
|
|
20
31
|
// Match Cursor Agent's ? prompt at end of output
|
|
21
32
|
return /\?\s*$/.test(cleanOutput.trimEnd());
|
|
22
33
|
}
|
|
23
|
-
detectStageComplete(cleanOutput, stage) {
|
|
24
|
-
if (cleanOutput.includes(`${protocol_1.STAGE_DONE_SENTINEL}${stage}]]`)) {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
detectAuthError(cleanOutput) {
|
|
30
|
-
if (/Authentication failed|Please log in/i.test(cleanOutput)) {
|
|
31
|
-
return { detected: true, failureType: 'auth_failure' };
|
|
32
|
-
}
|
|
33
|
-
if (/Rate limit exceeded/i.test(cleanOutput)) {
|
|
34
|
-
return { detected: true, failureType: 'rate_limit' };
|
|
35
|
-
}
|
|
36
|
-
if (/command not found|ENOENT/i.test(cleanOutput)) {
|
|
37
|
-
return { detected: true, failureType: 'binary_missing' };
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
formatCommand(stage) {
|
|
42
|
-
return stage.command ?? stage.name;
|
|
43
|
-
}
|
|
44
34
|
}
|
|
45
35
|
exports.CursorExecutor = CursorExecutor;
|
|
46
36
|
//# sourceMappingURL=cursor.executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.executor.js","sourceRoot":"","sources":["../../src/executor/cursor.executor.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"cursor.executor.js","sourceRoot":"","sources":["../../src/executor/cursor.executor.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAEjD,yDAAmD;AAGnD;;;;GAIG;AACH,MAAa,cAAe,SAAQ,gCAAa;IACtC,SAAS,GAAG,oBAAS,CAAC,MAAM,CAAC;IAEnB,iBAAiB,GAAuB;QACzD,EAAE,OAAO,EAAE,sCAAsC,EAAE,WAAW,EAAE,cAAc,EAAE;QAChF,EAAE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,YAAY,EAAE;QAC9D,EAAE,OAAO,EAAE,2BAA2B,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACxE,CAAC;IAEF,eAAe;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,OAAuB,EAAE,cAAsB;QACvD,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,kBAAkB,CAAC,aAAqB,EAAE,SAAiB;QACzD,2EAA2E;IAC7E,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY,CAAC,WAAmB;QAC9B,iDAAiD;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,CAAC;CACF;AA7BD,wCA6BC"}
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { ConfigSnapshot, StageConfig } from '@overlordai/protocol';
|
|
1
|
+
import type { ConfigSnapshot } from '@overlordai/protocol';
|
|
3
2
|
import { AgentExecutor } from './base.executor.js';
|
|
4
|
-
import type {
|
|
3
|
+
import type { AuthErrorPattern } from './base.executor.js';
|
|
5
4
|
/**
|
|
6
5
|
* Executor for custom/user-provided agent CLIs.
|
|
7
6
|
*
|
|
8
7
|
* The custom executor uses the configSnapshot's customCommand field
|
|
9
8
|
* to determine which CLI binary to invoke. This allows projects to
|
|
10
9
|
* integrate arbitrary agent tooling into the Overlord pipeline.
|
|
10
|
+
*
|
|
11
|
+
* SECURITY: agentCommand comes from admin-configured project settings
|
|
12
|
+
* (ConfigSnapshot.agentCommand), NOT from end-user input. Only users
|
|
13
|
+
* with project admin privileges can set this value via the server API.
|
|
14
|
+
* The command is passed to `sh -c` intentionally to support shell
|
|
15
|
+
* features (pipes, redirects, etc.) that admins may need. The PTY
|
|
16
|
+
* environment is already sandboxed (no inherited process.env, restricted
|
|
17
|
+
* env vars via RESERVED_PREFIXES). The null-byte check prevents
|
|
18
|
+
* argument injection at the execve level.
|
|
11
19
|
*/
|
|
12
20
|
export declare class CustomExecutor extends AgentExecutor {
|
|
13
|
-
readonly agentType
|
|
21
|
+
readonly agentType: "custom";
|
|
22
|
+
protected readonly authErrorPatterns: AuthErrorPattern[];
|
|
14
23
|
getStartCommand(): string;
|
|
15
24
|
buildArgs(config: ConfigSnapshot, _workspacePath: string): string[];
|
|
25
|
+
prepareEnvironment(_worktreePath: string, _realHome: string): void;
|
|
26
|
+
buildEnvVars(_realHome: string): Record<string, string>;
|
|
16
27
|
detectPrompt(cleanOutput: string): boolean;
|
|
17
|
-
detectStageComplete(cleanOutput: string, stage: string): boolean;
|
|
18
|
-
detectAuthError(cleanOutput: string): AuthErrorResult | null;
|
|
19
|
-
formatCommand(stage: StageConfig): string;
|
|
20
28
|
}
|
|
21
29
|
//# sourceMappingURL=custom.executor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.executor.d.ts","sourceRoot":"","sources":["../../src/executor/custom.executor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"custom.executor.d.ts","sourceRoot":"","sources":["../../src/executor/custom.executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAe,SAAQ,aAAa;IAC/C,QAAQ,CAAC,SAAS,WAAoB;IAEtC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,CAItD;IAEF,eAAe,IAAI,MAAM;IAMzB,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;IAQnE,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIlE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvD,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;CAI3C"}
|
|
@@ -9,49 +9,46 @@ const base_executor_js_1 = require("./base.executor.js");
|
|
|
9
9
|
* The custom executor uses the configSnapshot's customCommand field
|
|
10
10
|
* to determine which CLI binary to invoke. This allows projects to
|
|
11
11
|
* integrate arbitrary agent tooling into the Overlord pipeline.
|
|
12
|
+
*
|
|
13
|
+
* SECURITY: agentCommand comes from admin-configured project settings
|
|
14
|
+
* (ConfigSnapshot.agentCommand), NOT from end-user input. Only users
|
|
15
|
+
* with project admin privileges can set this value via the server API.
|
|
16
|
+
* The command is passed to `sh -c` intentionally to support shell
|
|
17
|
+
* features (pipes, redirects, etc.) that admins may need. The PTY
|
|
18
|
+
* environment is already sandboxed (no inherited process.env, restricted
|
|
19
|
+
* env vars via RESERVED_PREFIXES). The null-byte check prevents
|
|
20
|
+
* argument injection at the execve level.
|
|
12
21
|
*/
|
|
13
22
|
class CustomExecutor extends base_executor_js_1.AgentExecutor {
|
|
14
23
|
agentType = protocol_1.AgentType.CUSTOM;
|
|
24
|
+
authErrorPatterns = [
|
|
25
|
+
{ pattern: /Authentication failed|Unauthorized|403 Forbidden/i, failureType: 'auth_failure' },
|
|
26
|
+
{ pattern: /Rate limit|too many requests|429/i, failureType: 'rate_limit' },
|
|
27
|
+
{ pattern: /command not found|ENOENT|No such file/i, failureType: 'binary_missing' },
|
|
28
|
+
];
|
|
15
29
|
getStartCommand() {
|
|
16
30
|
// The actual command is determined at spawn time via buildArgs / config.
|
|
17
31
|
// Default to 'sh' as a safe fallback; the real command comes from config.
|
|
18
32
|
return 'sh';
|
|
19
33
|
}
|
|
20
34
|
buildArgs(config, _workspacePath) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// When agentCommand is set, we run: sh -c "<agentCommand>"
|
|
26
|
-
args.push('-c', config.agentCommand);
|
|
35
|
+
if (!config.agentCommand)
|
|
36
|
+
return [];
|
|
37
|
+
if (/\0/.test(config.agentCommand)) {
|
|
38
|
+
throw new Error('agentCommand contains null bytes');
|
|
27
39
|
}
|
|
28
|
-
return
|
|
40
|
+
return ['-c', config.agentCommand];
|
|
41
|
+
}
|
|
42
|
+
prepareEnvironment(_worktreePath, _realHome) {
|
|
43
|
+
// Custom executors manage their own auth
|
|
44
|
+
}
|
|
45
|
+
buildEnvVars(_realHome) {
|
|
46
|
+
return {};
|
|
29
47
|
}
|
|
30
48
|
detectPrompt(cleanOutput) {
|
|
31
49
|
// Generic prompt detection: look for common shell prompt patterns
|
|
32
50
|
return /[$#>❯]\s*$/.test(cleanOutput.trimEnd());
|
|
33
51
|
}
|
|
34
|
-
detectStageComplete(cleanOutput, stage) {
|
|
35
|
-
if (cleanOutput.includes(`${protocol_1.STAGE_DONE_SENTINEL}${stage}]]`)) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
detectAuthError(cleanOutput) {
|
|
41
|
-
if (/Authentication failed|Unauthorized|403 Forbidden/i.test(cleanOutput)) {
|
|
42
|
-
return { detected: true, failureType: 'auth_failure' };
|
|
43
|
-
}
|
|
44
|
-
if (/Rate limit|too many requests|429/i.test(cleanOutput)) {
|
|
45
|
-
return { detected: true, failureType: 'rate_limit' };
|
|
46
|
-
}
|
|
47
|
-
if (/command not found|ENOENT|No such file/i.test(cleanOutput)) {
|
|
48
|
-
return { detected: true, failureType: 'binary_missing' };
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
formatCommand(stage) {
|
|
53
|
-
return stage.command ?? stage.name;
|
|
54
|
-
}
|
|
55
52
|
}
|
|
56
53
|
exports.CustomExecutor = CustomExecutor;
|
|
57
54
|
//# sourceMappingURL=custom.executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.executor.js","sourceRoot":"","sources":["../../src/executor/custom.executor.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"custom.executor.js","sourceRoot":"","sources":["../../src/executor/custom.executor.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAEjD,yDAAmD;AAGnD;;;;;;;;;;;;;;;GAeG;AACH,MAAa,cAAe,SAAQ,gCAAa;IACtC,SAAS,GAAG,oBAAS,CAAC,MAAM,CAAC;IAEnB,iBAAiB,GAAuB;QACzD,EAAE,OAAO,EAAE,mDAAmD,EAAE,WAAW,EAAE,cAAc,EAAE;QAC7F,EAAE,OAAO,EAAE,mCAAmC,EAAE,WAAW,EAAE,YAAY,EAAE;QAC3E,EAAE,OAAO,EAAE,wCAAwC,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACrF,CAAC;IAEF,eAAe;QACb,yEAAyE;QACzE,0EAA0E;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,MAAsB,EAAE,cAAsB;QACtD,IAAI,CAAC,MAAM,CAAC,YAAY;YAAE,OAAO,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IAED,kBAAkB,CAAC,aAAqB,EAAE,SAAiB;QACzD,yCAAyC;IAC3C,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY,CAAC,WAAmB;QAC9B,kEAAkE;QAClE,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;CACF;AAnCD,wCAmCC"}
|
package/dist/git-operations.d.ts
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Wraps git CLI commands via child_process.
|
|
3
|
-
* Every method is
|
|
2
|
+
* Wraps git CLI commands via child_process.execFile.
|
|
3
|
+
* Every method is async and rejects on non-zero exit.
|
|
4
4
|
*/
|
|
5
5
|
export declare class GitOperations {
|
|
6
6
|
private sshKeyPath?;
|
|
7
7
|
constructor(sshKeyPath?: string);
|
|
8
8
|
/** Build environment with optional SSH key override. */
|
|
9
9
|
private buildEnv;
|
|
10
|
+
/** Run git with standard options; returns stdout as Buffer. */
|
|
11
|
+
private run;
|
|
10
12
|
/** git clone --bare <repoUrl> <targetDir> */
|
|
11
|
-
cloneBare(repoUrl: string, targetDir: string): void
|
|
13
|
+
cloneBare(repoUrl: string, targetDir: string): Promise<void>;
|
|
12
14
|
/** git remote get-url origin */
|
|
13
|
-
getRemoteUrl(bareDir: string): string
|
|
15
|
+
getRemoteUrl(bareDir: string): Promise<string>;
|
|
14
16
|
/** git remote set-url origin <url> (update remote to match latest config) */
|
|
15
|
-
setRemoteUrl(bareDir: string, url: string): void
|
|
17
|
+
setRemoteUrl(bareDir: string, url: string): Promise<void>;
|
|
16
18
|
/** Ensure the bare repo has a proper fetch refspec for origin/* refs. */
|
|
17
|
-
ensureFetchRefspec(bareDir: string): void
|
|
19
|
+
ensureFetchRefspec(bareDir: string): Promise<void>;
|
|
18
20
|
/** Delete a local branch if it exists (cleanup for retries). */
|
|
19
|
-
deleteBranchIfExists(bareDir: string, branch: string): void
|
|
21
|
+
deleteBranchIfExists(bareDir: string, branch: string): Promise<void>;
|
|
20
22
|
/** git fetch origin (run inside bare repo) */
|
|
21
|
-
fetch(bareDir: string): void
|
|
23
|
+
fetch(bareDir: string): Promise<void>;
|
|
22
24
|
/** git worktree add <worktreePath> -b <branch> <startPoint> */
|
|
23
|
-
addWorktree(bareDir: string, worktreePath: string, branch: string, startPoint: string): void
|
|
25
|
+
addWorktree(bareDir: string, worktreePath: string, branch: string, startPoint: string): Promise<void>;
|
|
24
26
|
/** git worktree remove <worktreePath> --force */
|
|
25
|
-
removeWorktree(bareDir: string, worktreePath: string): void
|
|
27
|
+
removeWorktree(bareDir: string, worktreePath: string): Promise<void>;
|
|
26
28
|
/** git worktree prune */
|
|
27
|
-
pruneWorktrees(bareDir: string): void
|
|
29
|
+
pruneWorktrees(bareDir: string): Promise<void>;
|
|
28
30
|
/** git config --local <key> <value> */
|
|
29
|
-
setLocalConfig(worktreePath: string, key: string, value: string): void
|
|
31
|
+
setLocalConfig(worktreePath: string, key: string, value: string): Promise<void>;
|
|
30
32
|
}
|
|
31
33
|
//# sourceMappingURL=git-operations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-operations.d.ts","sourceRoot":"","sources":["../src/git-operations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-operations.d.ts","sourceRoot":"","sources":["../src/git-operations.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAC,CAAS;gBAEhB,UAAU,CAAC,EAAE,MAAM;IAI/B,wDAAwD;IACxD,OAAO,CAAC,QAAQ;IAQhB,+DAA+D;IAC/D,OAAO,CAAC,GAAG;IAsBX,6CAA6C;IACvC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlE,gCAAgC;IAC1B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpD,6EAA6E;IACvE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,yEAAyE;IACnE,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxD,gEAAgE;IAC1D,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB1E,8CAA8C;IACxC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,+DAA+D;IACzD,WAAW,CACf,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAKhB,iDAAiD;IAC3C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1E,yBAAyB;IACnB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,uCAAuC;IACjC,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAItF"}
|
package/dist/git-operations.js
CHANGED
|
@@ -7,11 +7,13 @@ exports.GitOperations = void 0;
|
|
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
|
8
8
|
const pino_1 = __importDefault(require("pino"));
|
|
9
9
|
const safe_env_js_1 = require("./safe-env.js");
|
|
10
|
+
const git_token_helper_js_1 = require("./git-token-helper.js");
|
|
11
|
+
const protocol_1 = require("@overlordai/protocol");
|
|
10
12
|
const logger = (0, pino_1.default)({ name: 'git-operations' });
|
|
11
13
|
const EXEC_TIMEOUT = 120_000; // 2 minutes
|
|
12
14
|
/**
|
|
13
|
-
* Wraps git CLI commands via child_process.
|
|
14
|
-
* Every method is
|
|
15
|
+
* Wraps git CLI commands via child_process.execFile.
|
|
16
|
+
* Every method is async and rejects on non-zero exit.
|
|
15
17
|
*/
|
|
16
18
|
class GitOperations {
|
|
17
19
|
sshKeyPath;
|
|
@@ -26,50 +28,45 @@ class GitOperations {
|
|
|
26
28
|
}
|
|
27
29
|
return env;
|
|
28
30
|
}
|
|
29
|
-
/** git
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
/** Run git with standard options; returns stdout as Buffer. */
|
|
32
|
+
run(args, cwd) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
(0, node_child_process_1.execFile)('git', args, {
|
|
35
|
+
cwd,
|
|
36
|
+
timeout: EXEC_TIMEOUT,
|
|
37
|
+
encoding: 'buffer',
|
|
38
|
+
env: this.buildEnv(),
|
|
39
|
+
}, (error, stdout) => {
|
|
40
|
+
if (error) {
|
|
41
|
+
reject(error);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
resolve(stdout);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
43
47
|
});
|
|
44
48
|
}
|
|
49
|
+
/** git clone --bare <repoUrl> <targetDir> */
|
|
50
|
+
async cloneBare(repoUrl, targetDir) {
|
|
51
|
+
logger.info({ repoUrl: (0, git_token_helper_js_1.maskUrl)(repoUrl), targetDir }, 'Cloning bare repository');
|
|
52
|
+
await this.run(['clone', '--bare', repoUrl, targetDir]);
|
|
53
|
+
await this.run(['config', 'remote.origin.fetch', '+refs/heads/*:refs/remotes/origin/*'], targetDir);
|
|
54
|
+
}
|
|
45
55
|
/** git remote get-url origin */
|
|
46
|
-
getRemoteUrl(bareDir) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
timeout: EXEC_TIMEOUT,
|
|
50
|
-
stdio: 'pipe',
|
|
51
|
-
env: this.buildEnv(),
|
|
52
|
-
}).toString().trim();
|
|
56
|
+
async getRemoteUrl(bareDir) {
|
|
57
|
+
const buf = await this.run(['remote', 'get-url', 'origin'], bareDir);
|
|
58
|
+
return buf.toString().trim();
|
|
53
59
|
}
|
|
54
60
|
/** git remote set-url origin <url> (update remote to match latest config) */
|
|
55
|
-
setRemoteUrl(bareDir, url) {
|
|
56
|
-
|
|
57
|
-
cwd: bareDir,
|
|
58
|
-
timeout: EXEC_TIMEOUT,
|
|
59
|
-
stdio: 'pipe',
|
|
60
|
-
env: this.buildEnv(),
|
|
61
|
-
});
|
|
61
|
+
async setRemoteUrl(bareDir, url) {
|
|
62
|
+
await this.run(['remote', 'set-url', 'origin', url], bareDir);
|
|
62
63
|
}
|
|
63
64
|
/** Ensure the bare repo has a proper fetch refspec for origin/* refs. */
|
|
64
|
-
ensureFetchRefspec(bareDir) {
|
|
65
|
+
async ensureFetchRefspec(bareDir) {
|
|
65
66
|
const expected = '+refs/heads/*:refs/remotes/origin/*';
|
|
66
67
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
timeout: EXEC_TIMEOUT,
|
|
70
|
-
stdio: 'pipe',
|
|
71
|
-
env: this.buildEnv(),
|
|
72
|
-
}).toString().trim();
|
|
68
|
+
const buf = await this.run(['config', 'remote.origin.fetch'], bareDir);
|
|
69
|
+
const current = buf.toString().trim();
|
|
73
70
|
if (current === expected)
|
|
74
71
|
return;
|
|
75
72
|
}
|
|
@@ -77,96 +74,51 @@ class GitOperations {
|
|
|
77
74
|
// config key missing
|
|
78
75
|
}
|
|
79
76
|
logger.info({ bareDir }, 'Setting fetch refspec on existing bare repo');
|
|
80
|
-
|
|
81
|
-
cwd: bareDir,
|
|
82
|
-
timeout: EXEC_TIMEOUT,
|
|
83
|
-
stdio: 'pipe',
|
|
84
|
-
env: this.buildEnv(),
|
|
85
|
-
});
|
|
77
|
+
await this.run(['config', 'remote.origin.fetch', expected], bareDir);
|
|
86
78
|
}
|
|
87
79
|
/** Delete a local branch if it exists (cleanup for retries). */
|
|
88
|
-
deleteBranchIfExists(bareDir, branch) {
|
|
89
|
-
// Prune stale worktree refs first — a worktree from a previous failed
|
|
90
|
-
// attempt may still reference this branch, preventing deletion.
|
|
80
|
+
async deleteBranchIfExists(bareDir, branch) {
|
|
91
81
|
try {
|
|
92
|
-
|
|
93
|
-
cwd: bareDir,
|
|
94
|
-
timeout: EXEC_TIMEOUT,
|
|
95
|
-
stdio: 'pipe',
|
|
96
|
-
env: this.buildEnv(),
|
|
97
|
-
});
|
|
82
|
+
await this.run(['worktree', 'prune'], bareDir);
|
|
98
83
|
}
|
|
99
84
|
catch {
|
|
100
85
|
// prune failure is non-fatal
|
|
101
86
|
}
|
|
102
87
|
try {
|
|
103
|
-
|
|
104
|
-
cwd: bareDir,
|
|
105
|
-
timeout: EXEC_TIMEOUT,
|
|
106
|
-
stdio: 'pipe',
|
|
107
|
-
env: this.buildEnv(),
|
|
108
|
-
});
|
|
88
|
+
await this.run(['branch', '-D', branch], bareDir);
|
|
109
89
|
logger.info({ bareDir, branch }, 'Deleted stale branch');
|
|
110
90
|
}
|
|
111
91
|
catch (err) {
|
|
112
|
-
const msg =
|
|
113
|
-
if (msg.includes('not found')
|
|
114
|
-
// Branch doesn't exist — fine
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
92
|
+
const msg = (0, protocol_1.getErrorMessage)(err);
|
|
93
|
+
if (!msg.includes('not found') && !msg.includes('No such branch')) {
|
|
117
94
|
logger.warn({ bareDir, branch, err: msg }, 'Failed to delete branch');
|
|
118
95
|
}
|
|
119
96
|
}
|
|
120
97
|
}
|
|
121
98
|
/** git fetch origin (run inside bare repo) */
|
|
122
|
-
fetch(bareDir) {
|
|
99
|
+
async fetch(bareDir) {
|
|
123
100
|
logger.info({ bareDir }, 'Fetching origin');
|
|
124
|
-
|
|
125
|
-
cwd: bareDir,
|
|
126
|
-
timeout: EXEC_TIMEOUT,
|
|
127
|
-
stdio: 'pipe',
|
|
128
|
-
env: this.buildEnv(),
|
|
129
|
-
});
|
|
101
|
+
await this.run(['fetch', 'origin'], bareDir);
|
|
130
102
|
}
|
|
131
103
|
/** git worktree add <worktreePath> -b <branch> <startPoint> */
|
|
132
|
-
addWorktree(bareDir, worktreePath, branch, startPoint) {
|
|
104
|
+
async addWorktree(bareDir, worktreePath, branch, startPoint) {
|
|
133
105
|
logger.info({ bareDir, worktreePath, branch, startPoint }, 'Adding worktree');
|
|
134
|
-
|
|
135
|
-
cwd: bareDir,
|
|
136
|
-
timeout: EXEC_TIMEOUT,
|
|
137
|
-
stdio: 'pipe',
|
|
138
|
-
env: this.buildEnv(),
|
|
139
|
-
});
|
|
106
|
+
await this.run(['worktree', 'add', worktreePath, '-b', branch, startPoint], bareDir);
|
|
140
107
|
}
|
|
141
108
|
/** git worktree remove <worktreePath> --force */
|
|
142
|
-
removeWorktree(bareDir, worktreePath) {
|
|
109
|
+
async removeWorktree(bareDir, worktreePath) {
|
|
143
110
|
logger.info({ bareDir, worktreePath }, 'Removing worktree');
|
|
144
|
-
|
|
145
|
-
cwd: bareDir,
|
|
146
|
-
timeout: EXEC_TIMEOUT,
|
|
147
|
-
stdio: 'pipe',
|
|
148
|
-
env: this.buildEnv(),
|
|
149
|
-
});
|
|
111
|
+
await this.run(['worktree', 'remove', worktreePath, '--force'], bareDir);
|
|
150
112
|
}
|
|
151
113
|
/** git worktree prune */
|
|
152
|
-
pruneWorktrees(bareDir) {
|
|
114
|
+
async pruneWorktrees(bareDir) {
|
|
153
115
|
logger.info({ bareDir }, 'Pruning worktrees');
|
|
154
|
-
|
|
155
|
-
cwd: bareDir,
|
|
156
|
-
timeout: EXEC_TIMEOUT,
|
|
157
|
-
stdio: 'pipe',
|
|
158
|
-
env: this.buildEnv(),
|
|
159
|
-
});
|
|
116
|
+
await this.run(['worktree', 'prune'], bareDir);
|
|
160
117
|
}
|
|
161
118
|
/** git config --local <key> <value> */
|
|
162
|
-
setLocalConfig(worktreePath, key, value) {
|
|
119
|
+
async setLocalConfig(worktreePath, key, value) {
|
|
163
120
|
logger.debug({ worktreePath, key }, 'Setting local git config');
|
|
164
|
-
|
|
165
|
-
cwd: worktreePath,
|
|
166
|
-
timeout: EXEC_TIMEOUT,
|
|
167
|
-
stdio: 'pipe',
|
|
168
|
-
env: this.buildEnv(),
|
|
169
|
-
});
|
|
121
|
+
await this.run(['config', '--local', key, value], worktreePath);
|
|
170
122
|
}
|
|
171
123
|
}
|
|
172
124
|
exports.GitOperations = GitOperations;
|