@hexidecibel/companion 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/__tests__/task-parser.test.js +29 -29
  2. package/dist/__tests__/task-parser.test.js.map +1 -1
  3. package/dist/anthropic-usage.d.ts.map +1 -1
  4. package/dist/anthropic-usage.js +1 -1
  5. package/dist/anthropic-usage.js.map +1 -1
  6. package/dist/cert-generator.d.ts.map +1 -1
  7. package/dist/cert-generator.js +4 -21
  8. package/dist/cert-generator.js.map +1 -1
  9. package/dist/cli.d.ts +9 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +413 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +1 -7
  15. package/dist/config.js.map +1 -1
  16. package/dist/escalation.d.ts +51 -0
  17. package/dist/escalation.d.ts.map +1 -0
  18. package/dist/escalation.js +198 -0
  19. package/dist/escalation.js.map +1 -0
  20. package/dist/index.js +67 -30
  21. package/dist/index.js.map +1 -1
  22. package/dist/input-injector.d.ts.map +1 -1
  23. package/dist/input-injector.js +9 -5
  24. package/dist/input-injector.js.map +1 -1
  25. package/dist/notification-store.d.ts +35 -0
  26. package/dist/notification-store.d.ts.map +1 -0
  27. package/dist/notification-store.js +272 -0
  28. package/dist/notification-store.js.map +1 -0
  29. package/dist/parser.d.ts +15 -1
  30. package/dist/parser.d.ts.map +1 -1
  31. package/dist/parser.js +106 -61
  32. package/dist/parser.js.map +1 -1
  33. package/dist/push.d.ts +18 -26
  34. package/dist/push.d.ts.map +1 -1
  35. package/dist/push.js +90 -184
  36. package/dist/push.js.map +1 -1
  37. package/dist/qr-server.d.ts.map +1 -1
  38. package/dist/qr-server.js +134 -135
  39. package/dist/qr-server.js.map +1 -1
  40. package/dist/rules-engine.d.ts +20 -0
  41. package/dist/rules-engine.d.ts.map +1 -0
  42. package/dist/rules-engine.js +71 -0
  43. package/dist/rules-engine.js.map +1 -0
  44. package/dist/scaffold/claude-commands.d.ts +18 -0
  45. package/dist/scaffold/claude-commands.d.ts.map +1 -0
  46. package/dist/scaffold/claude-commands.js +352 -0
  47. package/dist/scaffold/claude-commands.js.map +1 -0
  48. package/dist/scaffold/generator.d.ts.map +1 -1
  49. package/dist/scaffold/generator.js +26 -1
  50. package/dist/scaffold/generator.js.map +1 -1
  51. package/dist/scaffold/scorer.d.ts +19 -0
  52. package/dist/scaffold/scorer.d.ts.map +1 -0
  53. package/dist/scaffold/scorer.js +92 -0
  54. package/dist/scaffold/scorer.js.map +1 -0
  55. package/dist/scaffold/templates/go-cli.d.ts +3 -0
  56. package/dist/scaffold/templates/go-cli.d.ts.map +1 -0
  57. package/dist/scaffold/templates/go-cli.js +249 -0
  58. package/dist/scaffold/templates/go-cli.js.map +1 -0
  59. package/dist/scaffold/templates/index.d.ts.map +1 -1
  60. package/dist/scaffold/templates/index.js +8 -2
  61. package/dist/scaffold/templates/index.js.map +1 -1
  62. package/dist/scaffold/templates/nextjs.d.ts +3 -0
  63. package/dist/scaffold/templates/nextjs.d.ts.map +1 -0
  64. package/dist/scaffold/templates/nextjs.js +336 -0
  65. package/dist/scaffold/templates/nextjs.js.map +1 -0
  66. package/dist/scaffold/templates/node-express.d.ts.map +1 -1
  67. package/dist/scaffold/templates/node-express.js +170 -157
  68. package/dist/scaffold/templates/node-express.js.map +1 -1
  69. package/dist/scaffold/templates/python-fastapi.d.ts.map +1 -1
  70. package/dist/scaffold/templates/python-fastapi.js +234 -221
  71. package/dist/scaffold/templates/python-fastapi.js.map +1 -1
  72. package/dist/scaffold/templates/react-mui-website.d.ts.map +1 -1
  73. package/dist/scaffold/templates/react-mui-website.js +337 -324
  74. package/dist/scaffold/templates/react-mui-website.js.map +1 -1
  75. package/dist/scaffold/templates/react-typescript.d.ts.map +1 -1
  76. package/dist/scaffold/templates/react-typescript.js +219 -206
  77. package/dist/scaffold/templates/react-typescript.js.map +1 -1
  78. package/dist/scaffold/templates/typescript-library.d.ts +3 -0
  79. package/dist/scaffold/templates/typescript-library.d.ts.map +1 -0
  80. package/dist/scaffold/templates/typescript-library.js +241 -0
  81. package/dist/scaffold/templates/typescript-library.js.map +1 -0
  82. package/dist/scaffold/types.d.ts +7 -0
  83. package/dist/scaffold/types.d.ts.map +1 -1
  84. package/dist/subagent-watcher.d.ts.map +1 -1
  85. package/dist/subagent-watcher.js +3 -3
  86. package/dist/subagent-watcher.js.map +1 -1
  87. package/dist/tmux-manager.d.ts +37 -0
  88. package/dist/tmux-manager.d.ts.map +1 -1
  89. package/dist/tmux-manager.js +165 -5
  90. package/dist/tmux-manager.js.map +1 -1
  91. package/dist/tool-config.d.ts.map +1 -1
  92. package/dist/tool-config.js +2 -2
  93. package/dist/tool-config.js.map +1 -1
  94. package/dist/types.d.ts +85 -0
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js +18 -0
  97. package/dist/types.js.map +1 -1
  98. package/dist/watcher.d.ts +7 -0
  99. package/dist/watcher.d.ts.map +1 -1
  100. package/dist/watcher.js +118 -9
  101. package/dist/watcher.js.map +1 -1
  102. package/dist/websocket.d.ts +16 -2
  103. package/dist/websocket.d.ts.map +1 -1
  104. package/dist/websocket.js +758 -117
  105. package/dist/websocket.js.map +1 -1
  106. package/dist/work-group-manager.d.ts +69 -0
  107. package/dist/work-group-manager.d.ts.map +1 -0
  108. package/dist/work-group-manager.js +610 -0
  109. package/dist/work-group-manager.js.map +1 -0
  110. 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexidecibel/companion",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Server daemon for Companion - watches coding sessions and serves data to mobile app",
5
5
  "main": "dist/index.js",
6
6
  "bin": {