@hexidecibel/companion 0.0.1 → 0.1.1
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/__tests__/task-parser.test.js +29 -29
- package/dist/__tests__/task-parser.test.js.map +1 -1
- package/dist/anthropic-usage.d.ts.map +1 -1
- package/dist/anthropic-usage.js +1 -1
- package/dist/anthropic-usage.js.map +1 -1
- package/dist/cert-generator.d.ts.map +1 -1
- package/dist/cert-generator.js +4 -21
- package/dist/cert-generator.js.map +1 -1
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +413 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -7
- package/dist/config.js.map +1 -1
- package/dist/escalation.d.ts +51 -0
- package/dist/escalation.d.ts.map +1 -0
- package/dist/escalation.js +198 -0
- package/dist/escalation.js.map +1 -0
- package/dist/index.js +67 -30
- package/dist/index.js.map +1 -1
- package/dist/input-injector.d.ts.map +1 -1
- package/dist/input-injector.js +9 -5
- package/dist/input-injector.js.map +1 -1
- package/dist/notification-store.d.ts +35 -0
- package/dist/notification-store.d.ts.map +1 -0
- package/dist/notification-store.js +272 -0
- package/dist/notification-store.js.map +1 -0
- package/dist/parser.d.ts +15 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +106 -61
- package/dist/parser.js.map +1 -1
- package/dist/push.d.ts +18 -26
- package/dist/push.d.ts.map +1 -1
- package/dist/push.js +90 -184
- package/dist/push.js.map +1 -1
- package/dist/qr-server.d.ts.map +1 -1
- package/dist/qr-server.js +159 -139
- package/dist/qr-server.js.map +1 -1
- package/dist/rules-engine.d.ts +20 -0
- package/dist/rules-engine.d.ts.map +1 -0
- package/dist/rules-engine.js +71 -0
- package/dist/rules-engine.js.map +1 -0
- package/dist/scaffold/claude-commands.d.ts +18 -0
- package/dist/scaffold/claude-commands.d.ts.map +1 -0
- package/dist/scaffold/claude-commands.js +352 -0
- package/dist/scaffold/claude-commands.js.map +1 -0
- package/dist/scaffold/generator.d.ts.map +1 -1
- package/dist/scaffold/generator.js +26 -1
- package/dist/scaffold/generator.js.map +1 -1
- package/dist/scaffold/scorer.d.ts +19 -0
- package/dist/scaffold/scorer.d.ts.map +1 -0
- package/dist/scaffold/scorer.js +92 -0
- package/dist/scaffold/scorer.js.map +1 -0
- package/dist/scaffold/templates/go-cli.d.ts +3 -0
- package/dist/scaffold/templates/go-cli.d.ts.map +1 -0
- package/dist/scaffold/templates/go-cli.js +249 -0
- package/dist/scaffold/templates/go-cli.js.map +1 -0
- package/dist/scaffold/templates/index.d.ts.map +1 -1
- package/dist/scaffold/templates/index.js +8 -2
- package/dist/scaffold/templates/index.js.map +1 -1
- package/dist/scaffold/templates/nextjs.d.ts +3 -0
- package/dist/scaffold/templates/nextjs.d.ts.map +1 -0
- package/dist/scaffold/templates/nextjs.js +336 -0
- package/dist/scaffold/templates/nextjs.js.map +1 -0
- package/dist/scaffold/templates/node-express.d.ts.map +1 -1
- package/dist/scaffold/templates/node-express.js +170 -157
- package/dist/scaffold/templates/node-express.js.map +1 -1
- package/dist/scaffold/templates/python-fastapi.d.ts.map +1 -1
- package/dist/scaffold/templates/python-fastapi.js +234 -221
- package/dist/scaffold/templates/python-fastapi.js.map +1 -1
- package/dist/scaffold/templates/react-mui-website.d.ts.map +1 -1
- package/dist/scaffold/templates/react-mui-website.js +337 -324
- package/dist/scaffold/templates/react-mui-website.js.map +1 -1
- package/dist/scaffold/templates/react-typescript.d.ts.map +1 -1
- package/dist/scaffold/templates/react-typescript.js +219 -206
- package/dist/scaffold/templates/react-typescript.js.map +1 -1
- package/dist/scaffold/templates/typescript-library.d.ts +3 -0
- package/dist/scaffold/templates/typescript-library.d.ts.map +1 -0
- package/dist/scaffold/templates/typescript-library.js +241 -0
- package/dist/scaffold/templates/typescript-library.js.map +1 -0
- package/dist/scaffold/types.d.ts +7 -0
- package/dist/scaffold/types.d.ts.map +1 -1
- package/dist/subagent-watcher.d.ts.map +1 -1
- package/dist/subagent-watcher.js +3 -3
- package/dist/subagent-watcher.js.map +1 -1
- package/dist/tmux-manager.d.ts +37 -0
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +165 -5
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-config.d.ts.map +1 -1
- package/dist/tool-config.js +2 -2
- package/dist/tool-config.js.map +1 -1
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -1
- package/dist/watcher.d.ts +7 -0
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +118 -9
- package/dist/watcher.js.map +1 -1
- package/dist/websocket.d.ts +16 -2
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +758 -117
- package/dist/websocket.js.map +1 -1
- package/dist/work-group-manager.d.ts +69 -0
- package/dist/work-group-manager.d.ts.map +1 -0
- package/dist/work-group-manager.js +610 -0
- package/dist/work-group-manager.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,610 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.WorkGroupManager = void 0;
|
|
37
|
+
const events_1 = require("events");
|
|
38
|
+
const uuid_1 = require("uuid");
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const child_process_1 = require("child_process");
|
|
43
|
+
const util_1 = require("util");
|
|
44
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
45
|
+
const STATE_FILE = path.join(os.homedir(), '.companion', 'work-groups.json');
|
|
46
|
+
class WorkGroupManager extends events_1.EventEmitter {
|
|
47
|
+
groups = new Map();
|
|
48
|
+
tmux;
|
|
49
|
+
injector;
|
|
50
|
+
watcher;
|
|
51
|
+
monitorInterval = null;
|
|
52
|
+
constructor(tmux, injector, watcher) {
|
|
53
|
+
super();
|
|
54
|
+
this.tmux = tmux;
|
|
55
|
+
this.injector = injector;
|
|
56
|
+
this.watcher = watcher;
|
|
57
|
+
this.loadState();
|
|
58
|
+
this.startMonitoring();
|
|
59
|
+
// Listen to watcher events for all sessions (active and non-active)
|
|
60
|
+
this.watcher.on('status-change', (data) => this.handleStatusChange(data));
|
|
61
|
+
this.watcher.on('other-session-activity', (data) => this.handleStatusChange(data));
|
|
62
|
+
}
|
|
63
|
+
async createWorkGroup(request) {
|
|
64
|
+
const groupId = (0, uuid_1.v4)();
|
|
65
|
+
const group = {
|
|
66
|
+
id: groupId,
|
|
67
|
+
name: request.name,
|
|
68
|
+
foremanSessionId: request.foremanSessionId,
|
|
69
|
+
foremanTmuxSession: request.foremanTmuxSession,
|
|
70
|
+
status: 'active',
|
|
71
|
+
workers: [],
|
|
72
|
+
createdAt: Date.now(),
|
|
73
|
+
planFile: request.planFile,
|
|
74
|
+
};
|
|
75
|
+
// Spawn each worker
|
|
76
|
+
for (const workerReq of request.workers) {
|
|
77
|
+
const worker = await this.spawnWorker(request.parentDir, workerReq);
|
|
78
|
+
group.workers.push(worker);
|
|
79
|
+
}
|
|
80
|
+
this.groups.set(groupId, group);
|
|
81
|
+
this.saveState();
|
|
82
|
+
this.emitUpdate(group);
|
|
83
|
+
console.log(`WorkGroupManager: Created group "${group.name}" with ${group.workers.length} workers`);
|
|
84
|
+
return group;
|
|
85
|
+
}
|
|
86
|
+
async spawnWorker(parentDir, request) {
|
|
87
|
+
const workerId = (0, uuid_1.v4)();
|
|
88
|
+
const branchName = `parallel/${request.taskSlug}`;
|
|
89
|
+
const worker = {
|
|
90
|
+
id: workerId,
|
|
91
|
+
sessionId: '',
|
|
92
|
+
tmuxSessionName: '',
|
|
93
|
+
taskSlug: request.taskSlug,
|
|
94
|
+
taskDescription: request.taskDescription,
|
|
95
|
+
branch: branchName,
|
|
96
|
+
worktreePath: '',
|
|
97
|
+
status: 'spawning',
|
|
98
|
+
commits: [],
|
|
99
|
+
startedAt: Date.now(),
|
|
100
|
+
};
|
|
101
|
+
try {
|
|
102
|
+
// Create git worktree
|
|
103
|
+
const wtResult = await this.tmux.createWorktree(parentDir, branchName);
|
|
104
|
+
if (!wtResult.success || !wtResult.worktreePath) {
|
|
105
|
+
worker.status = 'error';
|
|
106
|
+
worker.error = wtResult.error || 'Failed to create worktree';
|
|
107
|
+
return worker;
|
|
108
|
+
}
|
|
109
|
+
worker.worktreePath = wtResult.worktreePath;
|
|
110
|
+
worker.branch = wtResult.branch || branchName;
|
|
111
|
+
// Create tmux session in the worktree directory
|
|
112
|
+
const sessionName = this.tmux.generateSessionName(wtResult.worktreePath);
|
|
113
|
+
const tmuxResult = await this.tmux.createSession(sessionName, wtResult.worktreePath, true);
|
|
114
|
+
if (!tmuxResult.success) {
|
|
115
|
+
worker.status = 'error';
|
|
116
|
+
worker.error = tmuxResult.error || 'Failed to create tmux session';
|
|
117
|
+
// Clean up worktree on failure
|
|
118
|
+
await this.tmux.removeWorktree(parentDir, wtResult.worktreePath);
|
|
119
|
+
return worker;
|
|
120
|
+
}
|
|
121
|
+
worker.tmuxSessionName = sessionName;
|
|
122
|
+
// Derive sessionId from worktree path (same encoding as watcher uses)
|
|
123
|
+
worker.sessionId = wtResult.worktreePath.replace(/\//g, '-').replace(/^-/, '-');
|
|
124
|
+
// Wait for Claude CLI to start up
|
|
125
|
+
await this.waitForCliReady(sessionName);
|
|
126
|
+
// Inject the worker prompt
|
|
127
|
+
const prompt = this.buildWorkerPrompt(request);
|
|
128
|
+
await this.injector.sendInput(prompt, sessionName);
|
|
129
|
+
worker.status = 'working';
|
|
130
|
+
// Refresh watcher so it picks up the new session's conversation files
|
|
131
|
+
await this.watcher.refreshTmuxPaths();
|
|
132
|
+
console.log(`WorkGroupManager: Spawned worker "${request.taskSlug}" in ${sessionName}`);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
worker.status = 'error';
|
|
136
|
+
worker.error = err instanceof Error ? err.message : String(err);
|
|
137
|
+
console.error(`WorkGroupManager: Failed to spawn worker "${request.taskSlug}":`, err);
|
|
138
|
+
}
|
|
139
|
+
return worker;
|
|
140
|
+
}
|
|
141
|
+
buildWorkerPrompt(request) {
|
|
142
|
+
const fileList = request.files.length > 0
|
|
143
|
+
? request.files.map((f) => `- \`${f}\``).join('\n')
|
|
144
|
+
: '(see plan section below)';
|
|
145
|
+
return [
|
|
146
|
+
'You are implementing one item from a parallel work plan. Other items are being',
|
|
147
|
+
'worked on simultaneously in separate sessions. Stay focused on your task only.',
|
|
148
|
+
'',
|
|
149
|
+
`## Task: ${request.taskSlug}`,
|
|
150
|
+
'',
|
|
151
|
+
request.planSection,
|
|
152
|
+
'',
|
|
153
|
+
'## Scoped Files',
|
|
154
|
+
fileList,
|
|
155
|
+
'',
|
|
156
|
+
'## Rules',
|
|
157
|
+
'- Only modify files relevant to this task',
|
|
158
|
+
'- Follow TDD: write tests first, then implement, then refactor',
|
|
159
|
+
'- Run type check when done (npx tsc --noEmit or equivalent)',
|
|
160
|
+
'- Commit with a descriptive message when done (do NOT push)',
|
|
161
|
+
'- If you need clarification, ask — someone is monitoring',
|
|
162
|
+
'- When finished, your final message should start with "TASK COMPLETE:"',
|
|
163
|
+
' followed by a summary of what was done and commit SHAs',
|
|
164
|
+
].join('\n');
|
|
165
|
+
}
|
|
166
|
+
async waitForCliReady(sessionName, maxWaitMs = 15000) {
|
|
167
|
+
const startTime = Date.now();
|
|
168
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
169
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
170
|
+
const output = await this.tmux.capturePane(sessionName, 20);
|
|
171
|
+
// Look for common Claude CLI ready indicators
|
|
172
|
+
if (output.includes('claude') &&
|
|
173
|
+
(output.includes('>') || output.includes('$') || output.includes('What'))) {
|
|
174
|
+
console.log(`WorkGroupManager: CLI ready in ${sessionName} after ${Date.now() - startTime}ms`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
console.log(`WorkGroupManager: CLI wait timeout in ${sessionName}, proceeding anyway`);
|
|
179
|
+
}
|
|
180
|
+
handleStatusChange(data) {
|
|
181
|
+
if (!data.sessionId)
|
|
182
|
+
return;
|
|
183
|
+
for (const group of this.groups.values()) {
|
|
184
|
+
if (group.status !== 'active')
|
|
185
|
+
continue;
|
|
186
|
+
for (const worker of group.workers) {
|
|
187
|
+
if (worker.sessionId !== data.sessionId && worker.tmuxSessionName !== data.sessionId)
|
|
188
|
+
continue;
|
|
189
|
+
if (worker.status === 'completed' || worker.status === 'error')
|
|
190
|
+
continue;
|
|
191
|
+
// Update activity
|
|
192
|
+
if (data.currentActivity) {
|
|
193
|
+
worker.lastActivity = data.currentActivity;
|
|
194
|
+
}
|
|
195
|
+
// Check for completion
|
|
196
|
+
if (data.isWaitingForInput && data.lastMessage?.content) {
|
|
197
|
+
const content = data.lastMessage.content;
|
|
198
|
+
if (content.startsWith('TASK COMPLETE:') || content.includes('TASK COMPLETE:')) {
|
|
199
|
+
worker.status = 'completed';
|
|
200
|
+
worker.completedAt = Date.now();
|
|
201
|
+
this.detectCommits(worker);
|
|
202
|
+
this.saveState();
|
|
203
|
+
this.emitUpdate(group);
|
|
204
|
+
this.checkGroupCompletion(group);
|
|
205
|
+
console.log(`WorkGroupManager: Worker "${worker.taskSlug}" completed`);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
// Worker is waiting for input (question from Claude)
|
|
209
|
+
worker.status = 'waiting';
|
|
210
|
+
worker.lastQuestion = this.extractQuestion(content);
|
|
211
|
+
this.saveState();
|
|
212
|
+
this.emitUpdate(group);
|
|
213
|
+
this.emit('worker-waiting', { groupName: group.name, worker });
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
// Worker is actively working
|
|
217
|
+
if (!data.isWaitingForInput && worker.status === 'waiting') {
|
|
218
|
+
worker.status = 'working';
|
|
219
|
+
worker.lastQuestion = undefined;
|
|
220
|
+
this.saveState();
|
|
221
|
+
this.emitUpdate(group);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
extractQuestion(content) {
|
|
227
|
+
// Try to extract question text and options from the message
|
|
228
|
+
const lines = content.split('\n').filter((l) => l.trim());
|
|
229
|
+
const text = lines[0] || content.substring(0, 200);
|
|
230
|
+
// Look for numbered or bulleted options
|
|
231
|
+
const options = [];
|
|
232
|
+
for (const line of lines.slice(1)) {
|
|
233
|
+
const match = line.match(/^\s*(?:\d+[.)]\s*|[-*]\s+)(.+)/);
|
|
234
|
+
if (match) {
|
|
235
|
+
options.push({ label: match[1].trim() });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
text,
|
|
240
|
+
options: options.length > 0 ? options : undefined,
|
|
241
|
+
timestamp: Date.now(),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
async detectCommits(worker) {
|
|
245
|
+
if (!worker.worktreePath)
|
|
246
|
+
return;
|
|
247
|
+
try {
|
|
248
|
+
// Get commits on this branch that aren't on the base branch
|
|
249
|
+
const { stdout } = await execAsync('git log --oneline --format="%H" HEAD ^main 2>/dev/null || git log --oneline --format="%H" HEAD ^master 2>/dev/null || true', { cwd: worker.worktreePath });
|
|
250
|
+
worker.commits = stdout
|
|
251
|
+
.trim()
|
|
252
|
+
.split('\n')
|
|
253
|
+
.filter((l) => l.length > 0);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// Ignore errors
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
checkGroupCompletion(group) {
|
|
260
|
+
const allDone = group.workers.every((w) => w.status === 'completed' || w.status === 'error');
|
|
261
|
+
if (allDone) {
|
|
262
|
+
console.log(`WorkGroupManager: All workers in group "${group.name}" have finished`);
|
|
263
|
+
this.emit('group-ready-to-merge', { groupId: group.id, name: group.name });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async dismissWorkGroup(groupId) {
|
|
267
|
+
const group = this.groups.get(groupId);
|
|
268
|
+
if (!group)
|
|
269
|
+
return { success: false };
|
|
270
|
+
if (group.status === 'completed' || group.status === 'cancelled' || group.status === 'failed') {
|
|
271
|
+
this.groups.delete(groupId);
|
|
272
|
+
this.saveState();
|
|
273
|
+
this.emitUpdate(group);
|
|
274
|
+
return { success: true };
|
|
275
|
+
}
|
|
276
|
+
return { success: false };
|
|
277
|
+
}
|
|
278
|
+
getWorkGroups() {
|
|
279
|
+
return Array.from(this.groups.values());
|
|
280
|
+
}
|
|
281
|
+
getWorkGroup(id) {
|
|
282
|
+
return this.groups.get(id);
|
|
283
|
+
}
|
|
284
|
+
getWorkGroupForSession(sessionId) {
|
|
285
|
+
for (const group of this.groups.values()) {
|
|
286
|
+
if (group.foremanSessionId === sessionId)
|
|
287
|
+
return group;
|
|
288
|
+
for (const worker of group.workers) {
|
|
289
|
+
if (worker.sessionId === sessionId)
|
|
290
|
+
return group;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
async mergeWorkGroup(groupId) {
|
|
296
|
+
const group = this.groups.get(groupId);
|
|
297
|
+
if (!group) {
|
|
298
|
+
return { success: false, error: 'Work group not found' };
|
|
299
|
+
}
|
|
300
|
+
const completedWorkers = group.workers.filter((w) => w.status === 'completed');
|
|
301
|
+
if (completedWorkers.length === 0) {
|
|
302
|
+
return { success: false, error: 'No completed workers to merge' };
|
|
303
|
+
}
|
|
304
|
+
group.status = 'merging';
|
|
305
|
+
this.saveState();
|
|
306
|
+
this.emitUpdate(group);
|
|
307
|
+
// Find the main repo directory from a worker's worktree
|
|
308
|
+
const firstWorker = group.workers[0];
|
|
309
|
+
let mainRepoDir;
|
|
310
|
+
try {
|
|
311
|
+
const { stdout } = await execAsync('git rev-parse --show-toplevel', {
|
|
312
|
+
cwd: firstWorker.worktreePath,
|
|
313
|
+
});
|
|
314
|
+
// The worktree's toplevel IS the worktree. We need the main repo.
|
|
315
|
+
// Read the .git file in the worktree to find it.
|
|
316
|
+
const gitFile = path.join(firstWorker.worktreePath, '.git');
|
|
317
|
+
if (fs.existsSync(gitFile) && fs.statSync(gitFile).isFile()) {
|
|
318
|
+
const gitContent = fs.readFileSync(gitFile, 'utf-8').trim();
|
|
319
|
+
const match = gitContent.match(/gitdir:\s*(.+)/);
|
|
320
|
+
if (match) {
|
|
321
|
+
// gitdir points to .git/worktrees/<name> — go up 3 levels
|
|
322
|
+
mainRepoDir = path.resolve(path.dirname(match[1]), '..', '..');
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
mainRepoDir = stdout.trim();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
mainRepoDir = stdout.trim();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
group.status = 'failed';
|
|
334
|
+
group.error = 'Could not determine main repo directory';
|
|
335
|
+
this.saveState();
|
|
336
|
+
this.emitUpdate(group);
|
|
337
|
+
return { success: false, error: group.error };
|
|
338
|
+
}
|
|
339
|
+
// Try octopus merge of completed branches
|
|
340
|
+
const branches = completedWorkers.map((w) => w.branch);
|
|
341
|
+
const branchArgs = branches.join(' ');
|
|
342
|
+
try {
|
|
343
|
+
// Ensure we're on the right branch in the main repo
|
|
344
|
+
await execAsync('git checkout main 2>/dev/null || git checkout master', { cwd: mainRepoDir });
|
|
345
|
+
// Try the merge
|
|
346
|
+
await execAsync(`git merge ${branchArgs} --no-edit`, {
|
|
347
|
+
cwd: mainRepoDir,
|
|
348
|
+
});
|
|
349
|
+
// Get the merge commit SHA
|
|
350
|
+
const { stdout: sha } = await execAsync('git rev-parse HEAD', { cwd: mainRepoDir });
|
|
351
|
+
group.mergeCommit = sha.trim();
|
|
352
|
+
group.status = 'completed';
|
|
353
|
+
group.completedAt = Date.now();
|
|
354
|
+
// Clean up worktrees and branches for completed workers
|
|
355
|
+
for (const worker of completedWorkers) {
|
|
356
|
+
await this.cleanupWorker(mainRepoDir, worker, true);
|
|
357
|
+
}
|
|
358
|
+
this.saveState();
|
|
359
|
+
this.emitUpdate(group);
|
|
360
|
+
console.log(`WorkGroupManager: Merged group "${group.name}" → ${group.mergeCommit}`);
|
|
361
|
+
return { success: true, mergeCommit: group.mergeCommit };
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
// Merge conflict — abort and report
|
|
365
|
+
try {
|
|
366
|
+
await execAsync('git merge --abort', { cwd: mainRepoDir });
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
// Ignore abort errors
|
|
370
|
+
}
|
|
371
|
+
// Determine which files conflict
|
|
372
|
+
const conflicts = [];
|
|
373
|
+
try {
|
|
374
|
+
const { stdout: statusOutput } = await execAsync('git diff --name-only --diff-filter=U 2>/dev/null || true', { cwd: mainRepoDir });
|
|
375
|
+
conflicts.push(...statusOutput
|
|
376
|
+
.trim()
|
|
377
|
+
.split('\n')
|
|
378
|
+
.filter((l) => l.length > 0));
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
// Ignore
|
|
382
|
+
}
|
|
383
|
+
group.status = 'active'; // Revert to active so user can retry
|
|
384
|
+
group.error = `Merge conflict in: ${conflicts.join(', ') || 'unknown files'}`;
|
|
385
|
+
this.saveState();
|
|
386
|
+
this.emitUpdate(group);
|
|
387
|
+
return { success: false, conflicts, error: group.error };
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
async cancelWorkGroup(groupId) {
|
|
391
|
+
const group = this.groups.get(groupId);
|
|
392
|
+
if (!group) {
|
|
393
|
+
return { success: false, error: 'Work group not found' };
|
|
394
|
+
}
|
|
395
|
+
// Find main repo dir for worktree cleanup
|
|
396
|
+
let mainRepoDir = null;
|
|
397
|
+
for (const worker of group.workers) {
|
|
398
|
+
if (worker.worktreePath) {
|
|
399
|
+
try {
|
|
400
|
+
const gitFile = path.join(worker.worktreePath, '.git');
|
|
401
|
+
if (fs.existsSync(gitFile) && fs.statSync(gitFile).isFile()) {
|
|
402
|
+
const gitContent = fs.readFileSync(gitFile, 'utf-8').trim();
|
|
403
|
+
const match = gitContent.match(/gitdir:\s*(.+)/);
|
|
404
|
+
if (match) {
|
|
405
|
+
mainRepoDir = path.resolve(path.dirname(match[1]), '..', '..');
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
// Continue
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Kill all worker sessions and clean up worktrees
|
|
416
|
+
for (const worker of group.workers) {
|
|
417
|
+
if (worker.tmuxSessionName) {
|
|
418
|
+
await this.tmux.killSession(worker.tmuxSessionName);
|
|
419
|
+
}
|
|
420
|
+
if (mainRepoDir) {
|
|
421
|
+
await this.cleanupWorker(mainRepoDir, worker, true);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
group.status = 'cancelled';
|
|
425
|
+
group.completedAt = Date.now();
|
|
426
|
+
this.saveState();
|
|
427
|
+
this.emitUpdate(group);
|
|
428
|
+
console.log(`WorkGroupManager: Cancelled group "${group.name}"`);
|
|
429
|
+
return { success: true };
|
|
430
|
+
}
|
|
431
|
+
async retryWorker(groupId, workerId) {
|
|
432
|
+
const group = this.groups.get(groupId);
|
|
433
|
+
if (!group)
|
|
434
|
+
return { success: false, error: 'Work group not found' };
|
|
435
|
+
const workerIndex = group.workers.findIndex((w) => w.id === workerId);
|
|
436
|
+
if (workerIndex < 0)
|
|
437
|
+
return { success: false, error: 'Worker not found' };
|
|
438
|
+
const oldWorker = group.workers[workerIndex];
|
|
439
|
+
if (oldWorker.status !== 'error')
|
|
440
|
+
return { success: false, error: 'Worker is not in error state' };
|
|
441
|
+
// Clean up old worker
|
|
442
|
+
if (oldWorker.tmuxSessionName) {
|
|
443
|
+
await this.tmux.killSession(oldWorker.tmuxSessionName);
|
|
444
|
+
}
|
|
445
|
+
// Find parent dir from another worker or from the foreman
|
|
446
|
+
let parentDir = null;
|
|
447
|
+
for (const w of group.workers) {
|
|
448
|
+
if (w.worktreePath && w.id !== workerId) {
|
|
449
|
+
try {
|
|
450
|
+
const gitFile = path.join(w.worktreePath, '.git');
|
|
451
|
+
if (fs.existsSync(gitFile)) {
|
|
452
|
+
const content = fs.readFileSync(gitFile, 'utf-8').trim();
|
|
453
|
+
const match = content.match(/gitdir:\s*(.+)/);
|
|
454
|
+
if (match) {
|
|
455
|
+
parentDir = path.resolve(path.dirname(match[1]), '..', '..');
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
// Continue
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (!parentDir) {
|
|
466
|
+
return { success: false, error: 'Cannot determine parent repo directory' };
|
|
467
|
+
}
|
|
468
|
+
// Clean up old worktree if it exists
|
|
469
|
+
if (oldWorker.worktreePath) {
|
|
470
|
+
await this.tmux.removeWorktree(parentDir, oldWorker.worktreePath);
|
|
471
|
+
}
|
|
472
|
+
// Re-spawn
|
|
473
|
+
const newWorker = await this.spawnWorker(parentDir, {
|
|
474
|
+
taskSlug: oldWorker.taskSlug,
|
|
475
|
+
taskDescription: oldWorker.taskDescription,
|
|
476
|
+
planSection: '', // We don't have the original plan section; it was injected at creation
|
|
477
|
+
files: [],
|
|
478
|
+
});
|
|
479
|
+
group.workers[workerIndex] = newWorker;
|
|
480
|
+
this.saveState();
|
|
481
|
+
this.emitUpdate(group);
|
|
482
|
+
return { success: true };
|
|
483
|
+
}
|
|
484
|
+
async sendWorkerInput(groupId, workerId, text) {
|
|
485
|
+
const group = this.groups.get(groupId);
|
|
486
|
+
if (!group)
|
|
487
|
+
return { success: false, error: 'Work group not found' };
|
|
488
|
+
const worker = group.workers.find((w) => w.id === workerId);
|
|
489
|
+
if (!worker)
|
|
490
|
+
return { success: false, error: 'Worker not found' };
|
|
491
|
+
if (!worker.tmuxSessionName)
|
|
492
|
+
return { success: false, error: 'Worker has no tmux session' };
|
|
493
|
+
const success = await this.injector.sendInput(text, worker.tmuxSessionName);
|
|
494
|
+
if (success) {
|
|
495
|
+
worker.status = 'working';
|
|
496
|
+
worker.lastQuestion = undefined;
|
|
497
|
+
this.saveState();
|
|
498
|
+
this.emitUpdate(group);
|
|
499
|
+
}
|
|
500
|
+
return { success };
|
|
501
|
+
}
|
|
502
|
+
async cleanupWorker(mainRepoDir, worker, deleteBranch = false) {
|
|
503
|
+
// Kill tmux session
|
|
504
|
+
if (worker.tmuxSessionName) {
|
|
505
|
+
try {
|
|
506
|
+
await this.tmux.killSession(worker.tmuxSessionName);
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
// Ignore
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// Remove worktree
|
|
513
|
+
if (worker.worktreePath) {
|
|
514
|
+
try {
|
|
515
|
+
await this.tmux.removeWorktree(mainRepoDir, worker.worktreePath);
|
|
516
|
+
}
|
|
517
|
+
catch {
|
|
518
|
+
// Ignore
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// Delete the branch (best-effort)
|
|
522
|
+
if (deleteBranch && worker.branch) {
|
|
523
|
+
try {
|
|
524
|
+
await execAsync(`git branch -D "${worker.branch}"`, { cwd: mainRepoDir });
|
|
525
|
+
}
|
|
526
|
+
catch {
|
|
527
|
+
// Branch may already be gone
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
startMonitoring() {
|
|
532
|
+
// Poll every 5 seconds to check for stale workers and update status
|
|
533
|
+
this.monitorInterval = setInterval(() => this.monitor(), 5000);
|
|
534
|
+
}
|
|
535
|
+
async monitor() {
|
|
536
|
+
for (const group of this.groups.values()) {
|
|
537
|
+
if (group.status !== 'active')
|
|
538
|
+
continue;
|
|
539
|
+
let changed = false;
|
|
540
|
+
for (const worker of group.workers) {
|
|
541
|
+
if (worker.status === 'completed' || worker.status === 'error')
|
|
542
|
+
continue;
|
|
543
|
+
// Check if tmux session is still alive
|
|
544
|
+
if (worker.tmuxSessionName) {
|
|
545
|
+
const exists = await this.tmux.sessionExists(worker.tmuxSessionName);
|
|
546
|
+
if (!exists && worker.status !== 'spawning') {
|
|
547
|
+
worker.status = 'error';
|
|
548
|
+
worker.error = 'Tmux session disappeared';
|
|
549
|
+
changed = true;
|
|
550
|
+
this.emit('worker-error', { groupName: group.name, worker });
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
// Check for worker status via watcher
|
|
554
|
+
if (worker.sessionId) {
|
|
555
|
+
const status = this.watcher.getStatus(worker.sessionId);
|
|
556
|
+
if (status.currentActivity && status.currentActivity !== worker.lastActivity) {
|
|
557
|
+
worker.lastActivity = status.currentActivity;
|
|
558
|
+
changed = true;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
if (changed) {
|
|
563
|
+
this.saveState();
|
|
564
|
+
this.emitUpdate(group);
|
|
565
|
+
this.checkGroupCompletion(group);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
emitUpdate(group) {
|
|
570
|
+
this.emit('work-group-update', group);
|
|
571
|
+
}
|
|
572
|
+
loadState() {
|
|
573
|
+
try {
|
|
574
|
+
if (fs.existsSync(STATE_FILE)) {
|
|
575
|
+
const content = fs.readFileSync(STATE_FILE, 'utf-8');
|
|
576
|
+
const groups = JSON.parse(content);
|
|
577
|
+
for (const group of groups) {
|
|
578
|
+
// Only restore active/merging groups — completed/cancelled ones are historical
|
|
579
|
+
this.groups.set(group.id, group);
|
|
580
|
+
}
|
|
581
|
+
console.log(`WorkGroupManager: Loaded ${groups.length} work groups from disk`);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
catch (err) {
|
|
585
|
+
console.error('WorkGroupManager: Failed to load state:', err);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
saveState() {
|
|
589
|
+
try {
|
|
590
|
+
const dir = path.dirname(STATE_FILE);
|
|
591
|
+
if (!fs.existsSync(dir)) {
|
|
592
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
593
|
+
}
|
|
594
|
+
const groups = Array.from(this.groups.values());
|
|
595
|
+
fs.writeFileSync(STATE_FILE, JSON.stringify(groups, null, 2));
|
|
596
|
+
}
|
|
597
|
+
catch (err) {
|
|
598
|
+
console.error('WorkGroupManager: Failed to save state:', err);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
stop() {
|
|
602
|
+
if (this.monitorInterval) {
|
|
603
|
+
clearInterval(this.monitorInterval);
|
|
604
|
+
this.monitorInterval = null;
|
|
605
|
+
}
|
|
606
|
+
this.saveState();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
exports.WorkGroupManager = WorkGroupManager;
|
|
610
|
+
//# sourceMappingURL=work-group-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-group-manager.js","sourceRoot":"","sources":["../src/work-group-manager.ts"],"names":[],"mappings":"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"}
|