@coralai/sps-cli 0.6.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/commands/cardAdd.d.ts +2 -0
- package/dist/commands/cardAdd.d.ts.map +1 -0
- package/dist/commands/cardAdd.js +65 -0
- package/dist/commands/cardAdd.js.map +1 -0
- package/dist/commands/doctor.d.ts +9 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +264 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/monitorTick.d.ts +2 -0
- package/dist/commands/monitorTick.d.ts.map +1 -0
- package/dist/commands/monitorTick.js +47 -0
- package/dist/commands/monitorTick.js.map +1 -0
- package/dist/commands/pipelineTick.d.ts +2 -0
- package/dist/commands/pipelineTick.d.ts.map +1 -0
- package/dist/commands/pipelineTick.js +44 -0
- package/dist/commands/pipelineTick.js.map +1 -0
- package/dist/commands/pmCommand.d.ts +2 -0
- package/dist/commands/pmCommand.d.ts.map +1 -0
- package/dist/commands/pmCommand.js +159 -0
- package/dist/commands/pmCommand.js.map +1 -0
- package/dist/commands/projectInit.d.ts +2 -0
- package/dist/commands/projectInit.d.ts.map +1 -0
- package/dist/commands/projectInit.js +75 -0
- package/dist/commands/projectInit.js.map +1 -0
- package/dist/commands/qaTick.d.ts +2 -0
- package/dist/commands/qaTick.d.ts.map +1 -0
- package/dist/commands/qaTick.js +43 -0
- package/dist/commands/qaTick.js.map +1 -0
- package/dist/commands/schedulerTick.d.ts +2 -0
- package/dist/commands/schedulerTick.d.ts.map +1 -0
- package/dist/commands/schedulerTick.js +45 -0
- package/dist/commands/schedulerTick.js.map +1 -0
- package/dist/commands/tick.d.ts +14 -0
- package/dist/commands/tick.d.ts.map +1 -0
- package/dist/commands/tick.js +251 -0
- package/dist/commands/tick.js.map +1 -0
- package/dist/commands/workerLaunch.d.ts +2 -0
- package/dist/commands/workerLaunch.d.ts.map +1 -0
- package/dist/commands/workerLaunch.js +56 -0
- package/dist/commands/workerLaunch.js.map +1 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +131 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +23 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +28 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/lock.d.ts +14 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +65 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/logger.d.ts +24 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +62 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paths.d.ts +27 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +29 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/queue.d.ts +14 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/queue.js +38 -0
- package/dist/core/queue.js.map +1 -0
- package/dist/core/state.d.ts +32 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +52 -0
- package/dist/core/state.js.map +1 -0
- package/dist/engines/CloseoutEngine.d.ts +60 -0
- package/dist/engines/CloseoutEngine.d.ts.map +1 -0
- package/dist/engines/CloseoutEngine.js +596 -0
- package/dist/engines/CloseoutEngine.js.map +1 -0
- package/dist/engines/ExecutionEngine.d.ts +65 -0
- package/dist/engines/ExecutionEngine.d.ts.map +1 -0
- package/dist/engines/ExecutionEngine.js +603 -0
- package/dist/engines/ExecutionEngine.js.map +1 -0
- package/dist/engines/MonitorEngine.d.ts +39 -0
- package/dist/engines/MonitorEngine.d.ts.map +1 -0
- package/dist/engines/MonitorEngine.js +473 -0
- package/dist/engines/MonitorEngine.js.map +1 -0
- package/dist/engines/SchedulerEngine.d.ts +24 -0
- package/dist/engines/SchedulerEngine.d.ts.map +1 -0
- package/dist/engines/SchedulerEngine.js +195 -0
- package/dist/engines/SchedulerEngine.js.map +1 -0
- package/dist/interfaces/HookProvider.d.ts +9 -0
- package/dist/interfaces/HookProvider.d.ts.map +1 -0
- package/dist/interfaces/HookProvider.js +2 -0
- package/dist/interfaces/HookProvider.js.map +1 -0
- package/dist/interfaces/Notifier.d.ts +11 -0
- package/dist/interfaces/Notifier.d.ts.map +1 -0
- package/dist/interfaces/Notifier.js +2 -0
- package/dist/interfaces/Notifier.js.map +1 -0
- package/dist/interfaces/RepoBackend.d.ts +23 -0
- package/dist/interfaces/RepoBackend.d.ts.map +1 -0
- package/dist/interfaces/RepoBackend.js +2 -0
- package/dist/interfaces/RepoBackend.js.map +1 -0
- package/dist/interfaces/TaskBackend.d.ts +24 -0
- package/dist/interfaces/TaskBackend.d.ts.map +1 -0
- package/dist/interfaces/TaskBackend.js +2 -0
- package/dist/interfaces/TaskBackend.js.map +1 -0
- package/dist/interfaces/WorkerProvider.d.ts +23 -0
- package/dist/interfaces/WorkerProvider.d.ts.map +1 -0
- package/dist/interfaces/WorkerProvider.js +2 -0
- package/dist/interfaces/WorkerProvider.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +226 -0
- package/dist/main.js.map +1 -0
- package/dist/models/types.d.ts +68 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +2 -0
- package/dist/models/types.js.map +1 -0
- package/dist/providers/ClaudeWorkerProvider.d.ts +84 -0
- package/dist/providers/ClaudeWorkerProvider.d.ts.map +1 -0
- package/dist/providers/ClaudeWorkerProvider.js +293 -0
- package/dist/providers/ClaudeWorkerProvider.js.map +1 -0
- package/dist/providers/CodexWorkerProvider.d.ts +50 -0
- package/dist/providers/CodexWorkerProvider.d.ts.map +1 -0
- package/dist/providers/CodexWorkerProvider.js +275 -0
- package/dist/providers/CodexWorkerProvider.js.map +1 -0
- package/dist/providers/GitLabRepoBackend.d.ts +42 -0
- package/dist/providers/GitLabRepoBackend.d.ts.map +1 -0
- package/dist/providers/GitLabRepoBackend.js +280 -0
- package/dist/providers/GitLabRepoBackend.js.map +1 -0
- package/dist/providers/MarkdownTaskBackend.d.ts +88 -0
- package/dist/providers/MarkdownTaskBackend.d.ts.map +1 -0
- package/dist/providers/MarkdownTaskBackend.js +414 -0
- package/dist/providers/MarkdownTaskBackend.js.map +1 -0
- package/dist/providers/MatrixNotifier.d.ts +30 -0
- package/dist/providers/MatrixNotifier.d.ts.map +1 -0
- package/dist/providers/MatrixNotifier.js +82 -0
- package/dist/providers/MatrixNotifier.js.map +1 -0
- package/dist/providers/PlaneTaskBackend.d.ts +86 -0
- package/dist/providers/PlaneTaskBackend.d.ts.map +1 -0
- package/dist/providers/PlaneTaskBackend.js +409 -0
- package/dist/providers/PlaneTaskBackend.js.map +1 -0
- package/dist/providers/TrelloTaskBackend.d.ts +53 -0
- package/dist/providers/TrelloTaskBackend.d.ts.map +1 -0
- package/dist/providers/TrelloTaskBackend.js +300 -0
- package/dist/providers/TrelloTaskBackend.js.map +1 -0
- package/dist/providers/registry.d.ts +10 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +29 -0
- package/dist/providers/registry.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
/**
|
|
4
|
+
* Codex CLI patterns (differs from Claude):
|
|
5
|
+
*
|
|
6
|
+
* Ready prompt: › <placeholder>
|
|
7
|
+
* gpt-5.3-codex default · ...
|
|
8
|
+
*
|
|
9
|
+
* Completion: returns to › prompt after task
|
|
10
|
+
*
|
|
11
|
+
* Update blocker: ✨ Update available!
|
|
12
|
+
* › 1. Update now
|
|
13
|
+
* 2. Skip
|
|
14
|
+
* 3. Skip until next version
|
|
15
|
+
* Press enter to continue
|
|
16
|
+
*
|
|
17
|
+
* Confirmation: (none with --dangerously-bypass-approvals-and-sandbox)
|
|
18
|
+
*
|
|
19
|
+
* Exit command: /quit (Claude uses /exit)
|
|
20
|
+
*/
|
|
21
|
+
/** Completion keywords in codex pane text. */
|
|
22
|
+
const COMPLETION_KEYWORDS = /\b(done|completed|finished|Next step:|committed|pushed|MR created|merge request)\b/i;
|
|
23
|
+
/** Codex ready prompt: › at start of line + model info line */
|
|
24
|
+
const CODEX_READY = /›\s.*$/m;
|
|
25
|
+
const CODEX_MODEL_LINE = /codex.*default.*·/i;
|
|
26
|
+
/** Codex update blocker pattern */
|
|
27
|
+
const CODEX_UPDATE_PROMPT = /Update available|Skip until next version/i;
|
|
28
|
+
/**
|
|
29
|
+
* Run a tmux command. Returns null on failure.
|
|
30
|
+
*/
|
|
31
|
+
function tmux(args) {
|
|
32
|
+
try {
|
|
33
|
+
return execFileSync('tmux', args, {
|
|
34
|
+
encoding: 'utf-8',
|
|
35
|
+
timeout: 10_000,
|
|
36
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const stderr = err.stderr ?? '';
|
|
41
|
+
if (stderr.includes('server exited unexpectedly') || stderr.includes('no server running')) {
|
|
42
|
+
try {
|
|
43
|
+
const uid = process.getuid?.() ?? 1000;
|
|
44
|
+
const { rmSync } = require('node:fs');
|
|
45
|
+
rmSync(`/tmp/tmux-${uid}`, { recursive: true, force: true });
|
|
46
|
+
process.stderr.write('[codex-worker] Cleaned stale tmux socket, retrying\n');
|
|
47
|
+
return execFileSync('tmux', args, {
|
|
48
|
+
encoding: 'utf-8',
|
|
49
|
+
timeout: 10_000,
|
|
50
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function sessionExists(session) {
|
|
61
|
+
return tmux(['has-session', '-t', session]) !== null;
|
|
62
|
+
}
|
|
63
|
+
function capturePaneText(session, lines) {
|
|
64
|
+
return tmux(['capture-pane', '-t', session, '-p', '-S', `-${lines}`]) ?? '';
|
|
65
|
+
}
|
|
66
|
+
export class CodexWorkerProvider {
|
|
67
|
+
config;
|
|
68
|
+
constructor(config) {
|
|
69
|
+
this.config = config;
|
|
70
|
+
}
|
|
71
|
+
async prepareEnv(worktree, _seq) {
|
|
72
|
+
if (!existsSync(worktree)) {
|
|
73
|
+
throw new Error(`Worktree directory does not exist: ${worktree}`);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
execFileSync('git', ['-C', worktree, 'rev-parse', '--is-inside-work-tree'], {
|
|
77
|
+
encoding: 'utf-8', timeout: 5_000, stdio: ['ignore', 'pipe', 'pipe'],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
throw new Error(`Directory is not a git worktree: ${worktree}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Launch Codex in a tmux session (interactive mode).
|
|
86
|
+
* Handles session reuse and update prompt auto-skip.
|
|
87
|
+
*/
|
|
88
|
+
async launch(session, worktree) {
|
|
89
|
+
const codexCmd = 'codex --sandbox danger-full-access -a never --no-alt-screen';
|
|
90
|
+
if (sessionExists(session)) {
|
|
91
|
+
const pane = capturePaneText(session, 10);
|
|
92
|
+
const codexAlive = CODEX_READY.test(pane) && CODEX_MODEL_LINE.test(pane);
|
|
93
|
+
if (codexAlive) {
|
|
94
|
+
// Codex running — clear conversation + switch worktree
|
|
95
|
+
process.stderr.write(`[codex-worker] Reusing live Codex session ${session}\n`);
|
|
96
|
+
tmux(['send-keys', '-t', session, '/clear', 'Enter']);
|
|
97
|
+
await this.sleep(1_000);
|
|
98
|
+
// Codex doesn't support cd mid-session, but we can try
|
|
99
|
+
tmux(['send-keys', '-t', session, `/cd ${worktree}`, 'Enter']);
|
|
100
|
+
await this.sleep(500);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Session exists but Codex not running
|
|
104
|
+
process.stderr.write(`[codex-worker] Reusing tmux session ${session}\n`);
|
|
105
|
+
tmux(['send-keys', '-t', session, `cd ${worktree}`, 'Enter']);
|
|
106
|
+
await this.sleep(500);
|
|
107
|
+
tmux(['send-keys', '-t', session, codexCmd, 'Enter']);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// New session
|
|
111
|
+
const result = tmux(['new-session', '-d', '-s', session, '-c', worktree]);
|
|
112
|
+
if (result === null && !sessionExists(session)) {
|
|
113
|
+
throw new Error(`Failed to create tmux session: ${session}`);
|
|
114
|
+
}
|
|
115
|
+
tmux(['send-keys', '-t', session, codexCmd, 'Enter']);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Wait for Codex to be ready.
|
|
119
|
+
* Must handle the update prompt blocker (auto-skip).
|
|
120
|
+
*/
|
|
121
|
+
async waitReady(session, timeoutMs = 90_000) {
|
|
122
|
+
const pollInterval = 3_000;
|
|
123
|
+
const deadline = Date.now() + timeoutMs;
|
|
124
|
+
let updateSkipped = false;
|
|
125
|
+
// Codex is slower to start than Claude — wait longer before first check
|
|
126
|
+
await this.sleep(5_000);
|
|
127
|
+
while (Date.now() < deadline) {
|
|
128
|
+
const text = capturePaneText(session, 30);
|
|
129
|
+
// Handle update prompt — send Enter to dismiss, then skip
|
|
130
|
+
if (!updateSkipped && CODEX_UPDATE_PROMPT.test(text)) {
|
|
131
|
+
process.stderr.write('[codex-worker] Detected update prompt, skipping\n');
|
|
132
|
+
// If showing numbered options (1/2/3), select 3 "Skip until next version"
|
|
133
|
+
if (/1\. Update now/i.test(text)) {
|
|
134
|
+
tmux(['send-keys', '-t', session, 'Down']);
|
|
135
|
+
await this.sleep(300);
|
|
136
|
+
tmux(['send-keys', '-t', session, 'Down']);
|
|
137
|
+
await this.sleep(300);
|
|
138
|
+
}
|
|
139
|
+
tmux(['send-keys', '-t', session, 'Enter']);
|
|
140
|
+
updateSkipped = true;
|
|
141
|
+
await this.sleep(5_000);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
// Handle "Press enter to continue" after update banner
|
|
145
|
+
if (/Press enter to continue/i.test(text)) {
|
|
146
|
+
tmux(['send-keys', '-t', session, 'Enter']);
|
|
147
|
+
await this.sleep(3_000);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// Check if Codex is ready: › prompt + model info line
|
|
151
|
+
if (CODEX_MODEL_LINE.test(text) && CODEX_READY.test(text)) {
|
|
152
|
+
process.stderr.write('[codex-worker] Codex ready\n');
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
// Also match "OpenAI Codex" banner + › prompt
|
|
156
|
+
if (/OpenAI Codex/i.test(text) && /›/m.test(text)) {
|
|
157
|
+
process.stderr.write('[codex-worker] Codex ready (banner match)\n');
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
await this.sleep(pollInterval);
|
|
161
|
+
}
|
|
162
|
+
process.stderr.write(`[codex-worker] waitReady timed out after ${timeoutMs}ms\n`);
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Send task prompt to Codex via tmux paste-buffer.
|
|
167
|
+
*/
|
|
168
|
+
async sendTask(session, promptFile) {
|
|
169
|
+
if (!existsSync(promptFile)) {
|
|
170
|
+
throw new Error(`Prompt file does not exist: ${promptFile}`);
|
|
171
|
+
}
|
|
172
|
+
const content = readFileSync(promptFile, 'utf-8').trim();
|
|
173
|
+
const bufferFile = `/tmp/sps-task-${Date.now()}.txt`;
|
|
174
|
+
const { writeFileSync: writeTmp, unlinkSync } = await import('node:fs');
|
|
175
|
+
writeTmp(bufferFile, content);
|
|
176
|
+
tmux(['load-buffer', bufferFile]);
|
|
177
|
+
tmux(['paste-buffer', '-t', session]);
|
|
178
|
+
try {
|
|
179
|
+
unlinkSync(bufferFile);
|
|
180
|
+
}
|
|
181
|
+
catch { /* cleanup */ }
|
|
182
|
+
await this.sleep(500);
|
|
183
|
+
tmux(['send-keys', '-t', session, 'Enter']);
|
|
184
|
+
}
|
|
185
|
+
async inspect(session) {
|
|
186
|
+
const alive = sessionExists(session);
|
|
187
|
+
const paneText = alive ? capturePaneText(session, 50) : '';
|
|
188
|
+
return { alive, paneText };
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Codex with --dangerously-bypass-approvals-and-sandbox doesn't need confirmation.
|
|
192
|
+
* But if run without that flag, it may show approval prompts.
|
|
193
|
+
* For now, always return not waiting since we use bypass mode.
|
|
194
|
+
*/
|
|
195
|
+
async detectWaiting(session) {
|
|
196
|
+
// Codex in bypass mode doesn't have confirmation prompts
|
|
197
|
+
// But check for any "Press enter" or similar blockers
|
|
198
|
+
const pane = capturePaneText(session, 15);
|
|
199
|
+
// Update prompt blocker
|
|
200
|
+
if (CODEX_UPDATE_PROMPT.test(pane)) {
|
|
201
|
+
return { waiting: true, destructive: false, prompt: 'Codex update prompt' };
|
|
202
|
+
}
|
|
203
|
+
return { waiting: false, destructive: false, prompt: '' };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Detect completion by checking if Codex returned to › prompt after working.
|
|
207
|
+
*/
|
|
208
|
+
async detectCompleted(session, logDir, _branch) {
|
|
209
|
+
// Priority 1: task_completed marker file (same as Claude)
|
|
210
|
+
const markerPath = `${logDir}/task_completed`;
|
|
211
|
+
if (existsSync(markerPath)) {
|
|
212
|
+
return 'COMPLETED';
|
|
213
|
+
}
|
|
214
|
+
// Priority 2: check for update prompt (needs auto-skip, not completion)
|
|
215
|
+
const pane = capturePaneText(session, 20);
|
|
216
|
+
if (CODEX_UPDATE_PROMPT.test(pane)) {
|
|
217
|
+
return 'NEEDS_INPUT'; // will trigger auto-confirm to skip update
|
|
218
|
+
}
|
|
219
|
+
// Priority 3: completion keywords + back at › prompt
|
|
220
|
+
if (COMPLETION_KEYWORDS.test(pane) && CODEX_READY.test(pane) && CODEX_MODEL_LINE.test(pane)) {
|
|
221
|
+
return 'COMPLETED';
|
|
222
|
+
}
|
|
223
|
+
// Priority 4: session alive
|
|
224
|
+
if (sessionExists(session)) {
|
|
225
|
+
return 'ALIVE';
|
|
226
|
+
}
|
|
227
|
+
return 'DEAD';
|
|
228
|
+
}
|
|
229
|
+
async detectBlocked(session) {
|
|
230
|
+
const pane = capturePaneText(session, 30);
|
|
231
|
+
return /(error|fatal|rate.?limit|quota exceeded)/i.test(pane);
|
|
232
|
+
}
|
|
233
|
+
async sendFix(session, fixPrompt) {
|
|
234
|
+
const escaped = fixPrompt.replace(/'/g, "'\\''");
|
|
235
|
+
tmux(['send-keys', '-t', session, escaped, 'Enter']);
|
|
236
|
+
}
|
|
237
|
+
async resolveConflict(session, worktree, branch) {
|
|
238
|
+
const instruction = [
|
|
239
|
+
`There is a merge conflict on branch ${branch}.`,
|
|
240
|
+
`Working directory: ${worktree}`,
|
|
241
|
+
'Please resolve the conflict:',
|
|
242
|
+
`1. Run: git fetch origin && git rebase origin/${this.config.GITLAB_MERGE_BRANCH}`,
|
|
243
|
+
'2. Resolve any conflicts in the affected files',
|
|
244
|
+
'3. Run: git add . && git rebase --continue',
|
|
245
|
+
'4. Run: git push --force-with-lease',
|
|
246
|
+
].join('\n');
|
|
247
|
+
tmux(['send-keys', '-t', session, instruction, 'Enter']);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Stop Codex. Uses /quit (Codex's exit command, not /exit like Claude).
|
|
251
|
+
*/
|
|
252
|
+
async stop(session) {
|
|
253
|
+
if (!sessionExists(session))
|
|
254
|
+
return;
|
|
255
|
+
if (this.config.WORKER_SESSION_REUSE) {
|
|
256
|
+
// Keep session, just quit Codex
|
|
257
|
+
tmux(['send-keys', '-t', session, '/quit', 'Enter']);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
tmux(['send-keys', '-t', session, '/quit', 'Enter']);
|
|
261
|
+
for (let i = 0; i < 5; i++) {
|
|
262
|
+
await this.sleep(1_000);
|
|
263
|
+
if (!sessionExists(session))
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
tmux(['kill-session', '-t', session]);
|
|
267
|
+
}
|
|
268
|
+
async collectSummary(session) {
|
|
269
|
+
return capturePaneText(session, 100);
|
|
270
|
+
}
|
|
271
|
+
sleep(ms) {
|
|
272
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=CodexWorkerProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodexWorkerProvider.js","sourceRoot":"","sources":["../../src/providers/CodexWorkerProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKnD;;;;;;;;;;;;;;;;;GAiBG;AAEH,8CAA8C;AAC9C,MAAM,mBAAmB,GACvB,qFAAqF,CAAC;AAExF,+DAA+D;AAC/D,MAAM,WAAW,GAAG,SAAS,CAAC;AAC9B,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAE9C,mCAAmC;AACnC,MAAM,mBAAmB,GAAG,2CAA2C,CAAC;AAExE;;GAEG;AACH,SAAS,IAAI,CAAC,IAAc;IAC1B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE;YAChC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,MAAM;YACf,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,IAAI,EAAE,CAAC;QACzD,IAAI,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1F,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC;gBACvC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;gBACtC,MAAM,CAAC,aAAa,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;gBAC7E,OAAO,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE;oBAChC,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;iBAClC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,IAAI,CAAC,CAAC,aAAa,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,KAAa;IACrD,OAAO,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,OAAO,mBAAmB;IACb,MAAM,CAAgB;IAEvC,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,IAAY;QAC7C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC;YACH,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,CAAC,EAAE;gBAC1E,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aACrE,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,QAAgB;QAC5C,MAAM,QAAQ,GAAG,6DAA6D,CAAC;QAE/E,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC1C,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEzE,IAAI,UAAU,EAAE,CAAC;gBACf,uDAAuD;gBACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,OAAO,IAAI,CAAC,CAAC;gBAC/E,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBACtD,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxB,uDAAuD;gBACvD,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC/D,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,uCAAuC;YACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,OAAO,IAAI,CAAC,CAAC;YACzE,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YAC9D,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,cAAc;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC1E,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS,CAAC,OAAe,EAAE,SAAS,GAAG,MAAM;QACjD,MAAM,YAAY,GAAG,KAAK,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,aAAa,GAAG,KAAK,CAAC;QAE1B,wEAAwE;QACxE,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAExB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAE1C,0DAA0D;YAC1D,IAAI,CAAC,aAAa,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;gBAC1E,0EAA0E;gBAC1E,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;oBAC3C,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACtB,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;oBAC3C,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxB,CAAC;gBACD,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC5C,aAAa,GAAG,IAAI,CAAC;gBACrB,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,uDAAuD;YACvD,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1C,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC5C,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,sDAAsD;YACtD,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBACrD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,8CAA8C;YAC9C,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBACpE,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,SAAS,MAAM,CAAC,CAAC;QAClF,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAe,EAAE,UAAkB;QAChD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,UAAU,GAAG,iBAAiB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;QACrD,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACxE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC;YAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QACvD,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa,CAAC,OAAe;QACjC,yDAAyD;QACzD,sDAAsD;QACtD,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAE1C,wBAAwB;QACxB,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QAC9E,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,OAAe,EACf,MAAc,EACd,OAAe;QAEf,0DAA0D;QAC1D,MAAM,UAAU,GAAG,GAAG,MAAM,iBAAiB,CAAC;QAC9C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,wEAAwE;QACxE,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,aAAa,CAAC,CAAC,2CAA2C;QACnE,CAAC;QAED,qDAAqD;QACrD,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5F,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,4BAA4B;QAC5B,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAe;QACjC,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,SAAiB;QAC9C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe,EAAE,QAAgB,EAAE,MAAc;QACrE,MAAM,WAAW,GAAG;YAClB,uCAAuC,MAAM,GAAG;YAChD,sBAAsB,QAAQ,EAAE;YAChC,8BAA8B;YAC9B,iDAAiD,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE;YAClF,gDAAgD;YAChD,4CAA4C;YAC5C,qCAAqC;SACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,OAAe;QACxB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YAAE,OAAO;QAEpC,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACrC,gCAAgC;YAChC,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;gBAAE,OAAO;QACtC,CAAC;QACD,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,OAAO,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProjectConfig } from '../core/config.js';
|
|
2
|
+
import type { RepoBackend } from '../interfaces/RepoBackend.js';
|
|
3
|
+
import type { MrStatus } from '../models/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* GitLab-backed implementation of RepoBackend.
|
|
6
|
+
* Local git operations via execFileSync, remote operations via GitLab REST API.
|
|
7
|
+
*/
|
|
8
|
+
export declare class GitLabRepoBackend implements RepoBackend {
|
|
9
|
+
private readonly gitlabUrl;
|
|
10
|
+
private readonly projectId;
|
|
11
|
+
private readonly token;
|
|
12
|
+
private readonly apiBase;
|
|
13
|
+
private readonly mergeBranch;
|
|
14
|
+
constructor(config: ProjectConfig);
|
|
15
|
+
private git;
|
|
16
|
+
private apiGet;
|
|
17
|
+
private apiPost;
|
|
18
|
+
private apiPut;
|
|
19
|
+
ensureCleanBase(repoDir: string, baseBranch: string): Promise<void>;
|
|
20
|
+
ensureBranch(repoDir: string, branchName: string, baseBranch: string): Promise<void>;
|
|
21
|
+
ensureWorktree(repoDir: string, branchName: string, worktreePath: string): Promise<void>;
|
|
22
|
+
commit(worktree: string, message: string): Promise<void>;
|
|
23
|
+
push(worktree: string, branch: string, force?: boolean): Promise<void>;
|
|
24
|
+
rebase(worktree: string, baseBranch: string): Promise<{
|
|
25
|
+
success: boolean;
|
|
26
|
+
conflictFiles?: string[];
|
|
27
|
+
}>;
|
|
28
|
+
createOrUpdateMr(branch: string, title: string, description: string): Promise<{
|
|
29
|
+
url: string;
|
|
30
|
+
iid: number;
|
|
31
|
+
}>;
|
|
32
|
+
getMrStatus(branch: string): Promise<MrStatus>;
|
|
33
|
+
mergeMr(iid: number): Promise<{
|
|
34
|
+
merged: boolean;
|
|
35
|
+
error?: string;
|
|
36
|
+
}>;
|
|
37
|
+
detectMerged(branch: string): Promise<boolean>;
|
|
38
|
+
private mapMrState;
|
|
39
|
+
private mapCiStatus;
|
|
40
|
+
private mapMergeStatus;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=GitLabRepoBackend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitLabRepoBackend.d.ts","sourceRoot":"","sources":["../../src/providers/GitLabRepoBackend.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,EAAE,aAAa;IAYjC,OAAO,CAAC,GAAG;YAqBG,MAAM;YAiBN,OAAO;YAgBP,MAAM;IAoBd,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BpF,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxF,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxD,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA2BrG,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAkClC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAoC9C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBlE,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpD,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,cAAc;CAQvB"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
/**
|
|
4
|
+
* GitLab-backed implementation of RepoBackend.
|
|
5
|
+
* Local git operations via execFileSync, remote operations via GitLab REST API.
|
|
6
|
+
*/
|
|
7
|
+
export class GitLabRepoBackend {
|
|
8
|
+
gitlabUrl;
|
|
9
|
+
projectId;
|
|
10
|
+
token;
|
|
11
|
+
apiBase;
|
|
12
|
+
mergeBranch;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.gitlabUrl = config.raw.GITLAB_URL || 'https://gitlab.com';
|
|
15
|
+
this.projectId = config.GITLAB_PROJECT_ID;
|
|
16
|
+
this.token = config.raw.GITLAB_TOKEN || '';
|
|
17
|
+
this.apiBase = `${this.gitlabUrl}/api/v4/projects/${encodeURIComponent(this.projectId)}`;
|
|
18
|
+
this.mergeBranch = config.GITLAB_MERGE_BRANCH;
|
|
19
|
+
}
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Git helpers
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
git(args, cwd) {
|
|
24
|
+
try {
|
|
25
|
+
return execFileSync('git', args, {
|
|
26
|
+
cwd,
|
|
27
|
+
encoding: 'utf-8',
|
|
28
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
29
|
+
}).trim();
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
const e = err;
|
|
33
|
+
const stderr = typeof e.stderr === 'string' ? e.stderr.trim() : '';
|
|
34
|
+
const code = e.status ?? 1;
|
|
35
|
+
throw new Error(`git ${args.join(' ')} failed (exit ${code}) in ${cwd}: ${stderr}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// API helpers
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
async apiGet(path, query) {
|
|
42
|
+
const url = new URL(`${this.apiBase}${path}`);
|
|
43
|
+
if (query) {
|
|
44
|
+
for (const [k, v] of Object.entries(query)) {
|
|
45
|
+
url.searchParams.set(k, v);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const res = await fetch(url.toString(), {
|
|
49
|
+
headers: { 'PRIVATE-TOKEN': this.token },
|
|
50
|
+
});
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
const body = await res.text();
|
|
53
|
+
throw new Error(`GitLab GET ${path} returned ${res.status}: ${body}`);
|
|
54
|
+
}
|
|
55
|
+
return (await res.json());
|
|
56
|
+
}
|
|
57
|
+
async apiPost(path, body) {
|
|
58
|
+
const res = await fetch(`${this.apiBase}${path}`, {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: {
|
|
61
|
+
'PRIVATE-TOKEN': this.token,
|
|
62
|
+
'Content-Type': 'application/json',
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
const text = await res.text();
|
|
68
|
+
throw new Error(`GitLab POST ${path} returned ${res.status}: ${text}`);
|
|
69
|
+
}
|
|
70
|
+
return (await res.json());
|
|
71
|
+
}
|
|
72
|
+
async apiPut(path, body) {
|
|
73
|
+
const res = await fetch(`${this.apiBase}${path}`, {
|
|
74
|
+
method: 'PUT',
|
|
75
|
+
headers: {
|
|
76
|
+
'PRIVATE-TOKEN': this.token,
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
},
|
|
79
|
+
body: JSON.stringify(body),
|
|
80
|
+
});
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const text = await res.text();
|
|
83
|
+
throw new Error(`GitLab PUT ${path} returned ${res.status}: ${text}`);
|
|
84
|
+
}
|
|
85
|
+
return (await res.json());
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Local git operations
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
async ensureCleanBase(repoDir, baseBranch) {
|
|
91
|
+
this.git(['fetch', 'origin'], repoDir);
|
|
92
|
+
this.git(['checkout', baseBranch], repoDir);
|
|
93
|
+
this.git(['pull', 'origin', baseBranch], repoDir);
|
|
94
|
+
}
|
|
95
|
+
async ensureBranch(repoDir, branchName, baseBranch) {
|
|
96
|
+
// Ensure we're on base branch first (avoid branch-in-use conflicts with worktrees)
|
|
97
|
+
this.git(['fetch', 'origin'], repoDir);
|
|
98
|
+
try {
|
|
99
|
+
this.git(['checkout', baseBranch], repoDir);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// May fail if baseBranch doesn't exist locally yet
|
|
103
|
+
this.git(['checkout', '-b', baseBranch, `origin/${baseBranch}`], repoDir);
|
|
104
|
+
}
|
|
105
|
+
// Check if branch already exists locally or remotely
|
|
106
|
+
try {
|
|
107
|
+
this.git(['rev-parse', '--verify', branchName], repoDir);
|
|
108
|
+
// Branch exists locally — nothing more to do (worktree will check it out)
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Check remote
|
|
112
|
+
try {
|
|
113
|
+
this.git(['rev-parse', '--verify', `origin/${branchName}`], repoDir);
|
|
114
|
+
// Exists on remote — create local tracking branch (don't checkout)
|
|
115
|
+
this.git(['branch', branchName, `origin/${branchName}`], repoDir);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Does not exist anywhere — create from base (don't checkout)
|
|
119
|
+
this.git(['branch', branchName, `origin/${baseBranch}`], repoDir);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async ensureWorktree(repoDir, branchName, worktreePath) {
|
|
124
|
+
if (existsSync(worktreePath)) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Prune stale worktree references before adding new one
|
|
128
|
+
try {
|
|
129
|
+
this.git(['worktree', 'prune'], repoDir);
|
|
130
|
+
}
|
|
131
|
+
catch { /* non-fatal */ }
|
|
132
|
+
this.git(['worktree', 'add', worktreePath, branchName], repoDir);
|
|
133
|
+
}
|
|
134
|
+
async commit(worktree, message) {
|
|
135
|
+
this.git(['add', '-A'], worktree);
|
|
136
|
+
// Check if there is anything to commit
|
|
137
|
+
try {
|
|
138
|
+
this.git(['diff', '--cached', '--quiet'], worktree);
|
|
139
|
+
// No changes staged — nothing to commit
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// There are staged changes — proceed with commit
|
|
144
|
+
}
|
|
145
|
+
this.git(['commit', '-m', message], worktree);
|
|
146
|
+
}
|
|
147
|
+
async push(worktree, branch, force) {
|
|
148
|
+
const args = ['push', 'origin', branch];
|
|
149
|
+
if (force) {
|
|
150
|
+
args.splice(1, 0, '--force-with-lease');
|
|
151
|
+
}
|
|
152
|
+
this.git(args, worktree);
|
|
153
|
+
}
|
|
154
|
+
async rebase(worktree, baseBranch) {
|
|
155
|
+
this.git(['fetch', 'origin'], worktree);
|
|
156
|
+
try {
|
|
157
|
+
this.git(['rebase', `origin/${baseBranch}`], worktree);
|
|
158
|
+
return { success: true };
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Rebase failed — extract conflict files then abort
|
|
162
|
+
let conflictFiles = [];
|
|
163
|
+
try {
|
|
164
|
+
const status = this.git(['diff', '--name-only', '--diff-filter=U'], worktree);
|
|
165
|
+
conflictFiles = status.split('\n').filter(Boolean);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Could not list conflicts — return empty list
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
this.git(['rebase', '--abort'], worktree);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Abort may fail if rebase already cleaned up
|
|
175
|
+
}
|
|
176
|
+
return { success: false, conflictFiles };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// GitLab API operations
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
async createOrUpdateMr(branch, title, description) {
|
|
183
|
+
const existing = await this.apiGet('/merge_requests', {
|
|
184
|
+
source_branch: branch,
|
|
185
|
+
target_branch: this.mergeBranch,
|
|
186
|
+
state: 'opened',
|
|
187
|
+
});
|
|
188
|
+
if (existing.length > 0) {
|
|
189
|
+
// Update existing MR
|
|
190
|
+
const mr = existing[0];
|
|
191
|
+
const updated = await this.apiPut(`/merge_requests/${mr.iid}`, {
|
|
192
|
+
title,
|
|
193
|
+
description,
|
|
194
|
+
});
|
|
195
|
+
return { url: updated.web_url, iid: updated.iid };
|
|
196
|
+
}
|
|
197
|
+
// Create new MR
|
|
198
|
+
const created = await this.apiPost('/merge_requests', {
|
|
199
|
+
source_branch: branch,
|
|
200
|
+
target_branch: this.mergeBranch,
|
|
201
|
+
title,
|
|
202
|
+
description,
|
|
203
|
+
});
|
|
204
|
+
return { url: created.web_url, iid: created.iid };
|
|
205
|
+
}
|
|
206
|
+
async getMrStatus(branch) {
|
|
207
|
+
const mrs = await this.apiGet('/merge_requests', {
|
|
208
|
+
source_branch: branch,
|
|
209
|
+
});
|
|
210
|
+
if (mrs.length === 0) {
|
|
211
|
+
return {
|
|
212
|
+
exists: false,
|
|
213
|
+
state: 'not_found',
|
|
214
|
+
ciStatus: 'unknown',
|
|
215
|
+
mergeStatus: 'unknown',
|
|
216
|
+
url: null,
|
|
217
|
+
iid: null,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const mr = mrs[0];
|
|
221
|
+
return {
|
|
222
|
+
exists: true,
|
|
223
|
+
state: this.mapMrState(mr.state),
|
|
224
|
+
ciStatus: this.mapCiStatus(mr.head_pipeline?.status ?? null),
|
|
225
|
+
mergeStatus: this.mapMergeStatus(mr.merge_status),
|
|
226
|
+
url: mr.web_url,
|
|
227
|
+
iid: mr.iid,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
async mergeMr(iid) {
|
|
231
|
+
try {
|
|
232
|
+
const result = await this.apiPut(`/merge_requests/${iid}/merge`, {});
|
|
233
|
+
if (result.state === 'merged') {
|
|
234
|
+
return { merged: true };
|
|
235
|
+
}
|
|
236
|
+
return { merged: false, error: result.merge_error || `Unexpected state: ${result.state}` };
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
240
|
+
return { merged: false, error: message };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async detectMerged(branch) {
|
|
244
|
+
const mrs = await this.apiGet('/merge_requests', {
|
|
245
|
+
source_branch: branch,
|
|
246
|
+
state: 'merged',
|
|
247
|
+
});
|
|
248
|
+
return mrs.length > 0;
|
|
249
|
+
}
|
|
250
|
+
// ---------------------------------------------------------------------------
|
|
251
|
+
// Status mapping helpers (doc 12 §13.4)
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
mapMrState(state) {
|
|
254
|
+
switch (state) {
|
|
255
|
+
case 'opened': return 'opened';
|
|
256
|
+
case 'merged': return 'merged';
|
|
257
|
+
case 'closed': return 'closed';
|
|
258
|
+
default: return 'not_found';
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
mapCiStatus(status) {
|
|
262
|
+
switch (status) {
|
|
263
|
+
case 'success': return 'success';
|
|
264
|
+
case 'failed': return 'failed';
|
|
265
|
+
case 'running': return 'running';
|
|
266
|
+
case 'pending': return 'pending';
|
|
267
|
+
case 'created': return 'created';
|
|
268
|
+
default: return 'unknown';
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
mapMergeStatus(status) {
|
|
272
|
+
switch (status) {
|
|
273
|
+
case 'can_be_merged': return 'can_be_merged';
|
|
274
|
+
case 'cannot_be_merged': return 'cannot_be_merged';
|
|
275
|
+
case 'checking': return 'checking';
|
|
276
|
+
default: return 'unknown';
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=GitLabRepoBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitLabRepoBackend.js","sourceRoot":"","sources":["../../src/providers/GitLabRepoBackend.ts"],"names":[],"mappings":"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"}
|