@automagik/genie 0.260202.1607 → 0.260202.1833
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/claudio.js +5 -5
- package/dist/genie.js +6 -6
- package/dist/term.js +115 -53
- package/package.json +1 -1
- package/src/lib/orchestrator/completion.ts +392 -0
- package/src/lib/orchestrator/event-monitor.ts +442 -0
- package/src/lib/orchestrator/index.ts +12 -0
- package/src/lib/orchestrator/patterns.ts +277 -0
- package/src/lib/orchestrator/state-detector.ts +339 -0
- package/src/lib/version.ts +1 -1
- package/src/lib/worker-registry.ts +229 -0
- package/src/term-commands/close.ts +221 -0
- package/src/term-commands/kill.ts +143 -0
- package/src/term-commands/orchestrate.ts +844 -0
- package/src/term-commands/work.ts +415 -0
- package/src/term-commands/workers.ts +264 -0
- package/src/term.ts +189 -1
package/src/term.ts
CHANGED
|
@@ -15,6 +15,11 @@ import * as windowCmd from './term-commands/window.js';
|
|
|
15
15
|
import * as paneCmd from './term-commands/pane.js';
|
|
16
16
|
import * as statusCmd from './term-commands/status.js';
|
|
17
17
|
import * as shortcutsCmd from './term-commands/shortcuts.js';
|
|
18
|
+
import * as orchestrateCmd from './term-commands/orchestrate.js';
|
|
19
|
+
import * as workCmd from './term-commands/work.js';
|
|
20
|
+
import * as workersCmd from './term-commands/workers.js';
|
|
21
|
+
import * as closeCmd from './term-commands/close.js';
|
|
22
|
+
import * as killCmd from './term-commands/kill.js';
|
|
18
23
|
|
|
19
24
|
const program = new Command();
|
|
20
25
|
|
|
@@ -28,7 +33,14 @@ Collaborative Usage:
|
|
|
28
33
|
AI reads: term read genie
|
|
29
34
|
|
|
30
35
|
Workflow: new → exec → read → rm
|
|
31
|
-
Full control: window new/ls/rm, pane ls/rm, split, status
|
|
36
|
+
Full control: window new/ls/rm, pane ls/rm, split, status
|
|
37
|
+
|
|
38
|
+
Worker Orchestration:
|
|
39
|
+
term work <bd-id> - Spawn worker bound to beads issue
|
|
40
|
+
term work next - Work on next ready issue
|
|
41
|
+
term workers - List all workers and states
|
|
42
|
+
term close <bd-id> - Close issue, cleanup worker
|
|
43
|
+
term kill <worker> - Force kill a stuck worker`)
|
|
32
44
|
.version(VERSION);
|
|
33
45
|
|
|
34
46
|
// Session management
|
|
@@ -200,4 +212,180 @@ program
|
|
|
200
212
|
await shortcutsCmd.handleShortcuts(options);
|
|
201
213
|
});
|
|
202
214
|
|
|
215
|
+
// Worker management commands (beads + Claude orchestration)
|
|
216
|
+
program
|
|
217
|
+
.command('work <target>')
|
|
218
|
+
.description('Spawn worker bound to beads issue (target: bd-id, "next", or "wish")')
|
|
219
|
+
.option('--no-worktree', 'Use shared repo instead of worktree')
|
|
220
|
+
.option('-s, --session <name>', 'Target tmux session')
|
|
221
|
+
.option('--no-focus', 'Don\'t focus the worker pane')
|
|
222
|
+
.option('-p, --prompt <message>', 'Custom initial prompt')
|
|
223
|
+
.action(async (target: string, options: workCmd.WorkOptions) => {
|
|
224
|
+
await workCmd.workCommand(target, options);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
program
|
|
228
|
+
.command('workers')
|
|
229
|
+
.description('List all workers and their states')
|
|
230
|
+
.option('--json', 'Output as JSON')
|
|
231
|
+
.option('-w, --watch', 'Live updates (coming soon)')
|
|
232
|
+
.action(async (options: workersCmd.WorkersOptions) => {
|
|
233
|
+
if (options.watch) {
|
|
234
|
+
console.log('ℹ️ --watch mode coming in Phase 1.5');
|
|
235
|
+
}
|
|
236
|
+
await workersCmd.workersCommand(options);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
program
|
|
240
|
+
.command('close <task-id>')
|
|
241
|
+
.description('Close beads issue and cleanup worker')
|
|
242
|
+
.option('--no-sync', 'Skip bd sync')
|
|
243
|
+
.option('--keep-worktree', 'Don\'t remove the worktree')
|
|
244
|
+
.option('--merge', 'Merge worktree changes to main branch')
|
|
245
|
+
.option('-y, --yes', 'Skip confirmation')
|
|
246
|
+
.action(async (taskId: string, options: closeCmd.CloseOptions) => {
|
|
247
|
+
await closeCmd.closeCommand(taskId, options);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
program
|
|
251
|
+
.command('kill <worker>')
|
|
252
|
+
.description('Force kill a worker')
|
|
253
|
+
.option('-y, --yes', 'Skip confirmation')
|
|
254
|
+
.option('--keep-worktree', 'Don\'t remove the worktree')
|
|
255
|
+
.action(async (worker: string, options: killCmd.KillOptions) => {
|
|
256
|
+
await killCmd.killCommand(worker, options);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Approve command (shortcut to orc approve for worker use)
|
|
260
|
+
program
|
|
261
|
+
.command('approve <worker>')
|
|
262
|
+
.description('Approve pending permission request for a worker')
|
|
263
|
+
.option('--deny', 'Deny instead of approve')
|
|
264
|
+
.action(async (worker: string, options: { deny?: boolean }) => {
|
|
265
|
+
// Find worker to get pane
|
|
266
|
+
const registry = await import('./lib/worker-registry.js');
|
|
267
|
+
let workerInfo = await registry.get(worker);
|
|
268
|
+
if (!workerInfo) {
|
|
269
|
+
workerInfo = await registry.findByTask(worker);
|
|
270
|
+
}
|
|
271
|
+
if (!workerInfo) {
|
|
272
|
+
console.error(`❌ Worker "${worker}" not found. Run \`term workers\` to see workers.`);
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
await orchestrateCmd.approvePermission(workerInfo.session, {
|
|
276
|
+
pane: workerInfo.paneId,
|
|
277
|
+
deny: options.deny,
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Answer command (shortcut to orc answer for worker use)
|
|
282
|
+
program
|
|
283
|
+
.command('answer <worker> <choice>')
|
|
284
|
+
.description('Answer a question for a worker (use "text:..." for text input)')
|
|
285
|
+
.action(async (worker: string, choice: string) => {
|
|
286
|
+
const registry = await import('./lib/worker-registry.js');
|
|
287
|
+
let workerInfo = await registry.get(worker);
|
|
288
|
+
if (!workerInfo) {
|
|
289
|
+
workerInfo = await registry.findByTask(worker);
|
|
290
|
+
}
|
|
291
|
+
if (!workerInfo) {
|
|
292
|
+
console.error(`❌ Worker "${worker}" not found. Run \`term workers\` to see workers.`);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
await orchestrateCmd.answerQuestion(workerInfo.session, choice, {
|
|
296
|
+
pane: workerInfo.paneId,
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// Orchestration commands (Claude Code automation)
|
|
301
|
+
const orcProgram = program.command('orc').description('Orchestrate Claude Code sessions');
|
|
302
|
+
|
|
303
|
+
orcProgram
|
|
304
|
+
.command('start <session>')
|
|
305
|
+
.description('Start Claude Code in a session with optional monitoring')
|
|
306
|
+
.option('-p, --pane <id>', 'Target specific pane ID (e.g., %16)')
|
|
307
|
+
.option('-m, --monitor', 'Enable real-time event monitoring')
|
|
308
|
+
.option('-c, --command <cmd>', 'Command to run instead of claude')
|
|
309
|
+
.option('--json', 'Output events as JSON')
|
|
310
|
+
.action(async (session: string, options: orchestrateCmd.StartOptions) => {
|
|
311
|
+
await orchestrateCmd.startSession(session, options);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
orcProgram
|
|
315
|
+
.command('send <session> <message>')
|
|
316
|
+
.description('Send message to Claude and track completion')
|
|
317
|
+
.option('--pane <id>', 'Target specific pane ID (e.g., %16)')
|
|
318
|
+
.option('--method <name>', 'Completion detection method')
|
|
319
|
+
.option('-t, --timeout <ms>', 'Timeout in milliseconds')
|
|
320
|
+
.option('--no-wait', 'Send without waiting for completion')
|
|
321
|
+
.option('--json', 'Output as JSON')
|
|
322
|
+
.action(async (session: string, message: string, options: orchestrateCmd.SendOptions) => {
|
|
323
|
+
await orchestrateCmd.sendMessage(session, message, options);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
orcProgram
|
|
327
|
+
.command('status <session>')
|
|
328
|
+
.description('Show current Claude state and details')
|
|
329
|
+
.option('--pane <id>', 'Target specific pane ID (e.g., %16)')
|
|
330
|
+
.option('--json', 'Output as JSON')
|
|
331
|
+
.action(async (session: string, options: orchestrateCmd.StatusOptions) => {
|
|
332
|
+
await orchestrateCmd.showStatus(session, options);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
orcProgram
|
|
336
|
+
.command('watch <session>')
|
|
337
|
+
.description('Watch session events in real-time')
|
|
338
|
+
.option('--pane <id>', 'Target specific pane ID (e.g., %16)')
|
|
339
|
+
.option('--json', 'Output events as JSON')
|
|
340
|
+
.option('-p, --poll <ms>', 'Poll interval in milliseconds')
|
|
341
|
+
.action(async (session: string, options: orchestrateCmd.WatchOptions) => {
|
|
342
|
+
await orchestrateCmd.watchSession(session, options);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
orcProgram
|
|
346
|
+
.command('approve <session>')
|
|
347
|
+
.description('Approve pending permission request')
|
|
348
|
+
.option('-p, --pane <id>', 'Specific pane ID to target')
|
|
349
|
+
.option('--auto', 'Auto-approve all future permissions (dangerous!)')
|
|
350
|
+
.option('--deny', 'Deny instead of approve')
|
|
351
|
+
.action(async (session: string, options: orchestrateCmd.ApproveOptions) => {
|
|
352
|
+
await orchestrateCmd.approvePermission(session, options);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
orcProgram
|
|
356
|
+
.command('answer <session> <choice>')
|
|
357
|
+
.description('Answer a question with the given choice (use "text:..." to send feedback)')
|
|
358
|
+
.option('-p, --pane <id>', 'Specific pane ID to target')
|
|
359
|
+
.action(async (session: string, choice: string, options: { pane?: string }) => {
|
|
360
|
+
await orchestrateCmd.answerQuestion(session, choice, options);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
orcProgram
|
|
364
|
+
.command('experiment <method>')
|
|
365
|
+
.description('Test a completion detection method')
|
|
366
|
+
.option('-n, --runs <number>', 'Number of test runs')
|
|
367
|
+
.option('--task <command>', 'Test command to run')
|
|
368
|
+
.option('--json', 'Output as JSON')
|
|
369
|
+
.action(async (method: string, options: orchestrateCmd.ExperimentOptions) => {
|
|
370
|
+
await orchestrateCmd.runExperiment(method, options);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
orcProgram
|
|
374
|
+
.command('methods')
|
|
375
|
+
.description('List available completion detection methods')
|
|
376
|
+
.action(async () => {
|
|
377
|
+
await orchestrateCmd.listMethods();
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
orcProgram
|
|
381
|
+
.command('run <session> <message>')
|
|
382
|
+
.description('Send task and auto-approve until idle (fire-and-forget)')
|
|
383
|
+
.option('-p, --pane <id>', 'Target specific pane ID (e.g., %16)')
|
|
384
|
+
.option('-a, --auto-approve', 'Auto-approve permissions and plans')
|
|
385
|
+
.option('-t, --timeout <ms>', 'Timeout in milliseconds (default: 300000)')
|
|
386
|
+
.option('--json', 'Output final state as JSON')
|
|
387
|
+
.action(async (session: string, message: string, options: orchestrateCmd.RunOptions) => {
|
|
388
|
+
await orchestrateCmd.runTask(session, message, options);
|
|
389
|
+
});
|
|
390
|
+
|
|
203
391
|
program.parse();
|