@automagik/genie 0.260202.1607 → 0.260202.1901
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/.beads/README.md +81 -0
- package/.beads/config.yaml +67 -0
- package/.beads/interactions.jsonl +0 -0
- package/.beads/issues.jsonl +0 -0
- package/.beads/metadata.json +4 -0
- package/.gitattributes +3 -0
- package/AGENTS.md +40 -0
- package/dist/claudio.js +5 -5
- package/dist/genie.js +6 -6
- package/dist/term.js +116 -53
- package/package.json +1 -1
- package/src/lib/beads-registry.ts +546 -0
- 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/tmux.ts +15 -1
- package/src/lib/version.ts +1 -1
- package/src/lib/worker-registry.ts +229 -0
- package/src/term-commands/close.ts +256 -0
- package/src/term-commands/daemon.ts +176 -0
- package/src/term-commands/kill.ts +186 -0
- package/src/term-commands/orchestrate.ts +844 -0
- package/src/term-commands/split.ts +8 -7
- package/src/term-commands/work.ts +497 -0
- package/src/term-commands/workers.ts +298 -0
- package/src/term.ts +227 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kill command - Force kill a worker
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* term kill <worker> - Kill worker by ID or pane
|
|
6
|
+
*
|
|
7
|
+
* Options:
|
|
8
|
+
* -y, --yes - Skip confirmation
|
|
9
|
+
* --keep-worktree - Don't remove the worktree
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { confirm } from '@inquirer/prompts';
|
|
13
|
+
import * as tmux from '../lib/tmux.js';
|
|
14
|
+
import * as registry from '../lib/worker-registry.js';
|
|
15
|
+
import * as beadsRegistry from '../lib/beads-registry.js';
|
|
16
|
+
import { WorktreeManager } from '../lib/worktree.js';
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
import { homedir } from 'os';
|
|
19
|
+
|
|
20
|
+
// Use beads registry when enabled
|
|
21
|
+
const useBeads = beadsRegistry.isBeadsRegistryEnabled();
|
|
22
|
+
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Types
|
|
25
|
+
// ============================================================================
|
|
26
|
+
|
|
27
|
+
export interface KillOptions {
|
|
28
|
+
yes?: boolean;
|
|
29
|
+
keepWorktree?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Configuration
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
const WORKTREE_BASE = join(homedir(), '.local', 'share', 'term', 'worktrees');
|
|
37
|
+
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Helper Functions
|
|
40
|
+
// ============================================================================
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Kill worker pane
|
|
44
|
+
*/
|
|
45
|
+
async function killWorkerPane(paneId: string): Promise<boolean> {
|
|
46
|
+
try {
|
|
47
|
+
await tmux.killPane(paneId);
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false; // Pane may already be gone
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Remove worktree
|
|
56
|
+
* Uses bd worktree when beads registry is enabled
|
|
57
|
+
* Falls back to WorktreeManager otherwise
|
|
58
|
+
*/
|
|
59
|
+
async function removeWorktree(taskId: string, repoPath: string): Promise<boolean> {
|
|
60
|
+
// Try bd worktree first when beads is enabled
|
|
61
|
+
if (useBeads) {
|
|
62
|
+
try {
|
|
63
|
+
const removed = await beadsRegistry.removeWorktree(taskId);
|
|
64
|
+
if (removed) return true;
|
|
65
|
+
// Fall through to WorktreeManager if bd worktree fails
|
|
66
|
+
} catch {
|
|
67
|
+
// Fall through
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Fallback to WorktreeManager
|
|
72
|
+
try {
|
|
73
|
+
const manager = new WorktreeManager({
|
|
74
|
+
baseDir: WORKTREE_BASE,
|
|
75
|
+
repoPath,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (await manager.worktreeExists(taskId)) {
|
|
79
|
+
await manager.removeWorktree(taskId);
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return true; // Already doesn't exist
|
|
83
|
+
} catch (error: any) {
|
|
84
|
+
console.error(`⚠️ Failed to remove worktree: ${error.message}`);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// Main Command
|
|
91
|
+
// ============================================================================
|
|
92
|
+
|
|
93
|
+
export async function killCommand(
|
|
94
|
+
target: string,
|
|
95
|
+
options: KillOptions = {}
|
|
96
|
+
): Promise<void> {
|
|
97
|
+
try {
|
|
98
|
+
// Find worker by ID or pane (check both registries during transition)
|
|
99
|
+
let worker = await registry.get(target);
|
|
100
|
+
|
|
101
|
+
if (!worker && useBeads) {
|
|
102
|
+
// Try beads registry
|
|
103
|
+
worker = await beadsRegistry.getWorker(target);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!worker) {
|
|
107
|
+
// Try finding by pane ID
|
|
108
|
+
worker = await registry.findByPane(target);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!worker && useBeads) {
|
|
112
|
+
worker = await beadsRegistry.findByPane(target);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!worker) {
|
|
116
|
+
// Try finding by task ID
|
|
117
|
+
worker = await registry.findByTask(target);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!worker && useBeads) {
|
|
121
|
+
worker = await beadsRegistry.findByTask(target);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!worker) {
|
|
125
|
+
console.error(`❌ Worker "${target}" not found.`);
|
|
126
|
+
console.log(` Run \`term workers\` to see active workers.`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Confirm with user
|
|
131
|
+
if (!options.yes) {
|
|
132
|
+
const confirmed = await confirm({
|
|
133
|
+
message: `Kill worker ${worker.id} (pane ${worker.paneId})?`,
|
|
134
|
+
default: true,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (!confirmed) {
|
|
138
|
+
console.log('Cancelled.');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 1. Kill worker pane
|
|
144
|
+
console.log(`💀 Killing worker pane ${worker.paneId}...`);
|
|
145
|
+
const killed = await killWorkerPane(worker.paneId);
|
|
146
|
+
if (killed) {
|
|
147
|
+
console.log(` ✅ Pane killed`);
|
|
148
|
+
} else {
|
|
149
|
+
console.log(` ℹ️ Pane already gone`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 2. Remove worktree (unless --keep-worktree)
|
|
153
|
+
if (worker.worktree && !options.keepWorktree) {
|
|
154
|
+
console.log(`🌳 Removing worktree...`);
|
|
155
|
+
const removed = await removeWorktree(worker.taskId, worker.repoPath);
|
|
156
|
+
if (removed) {
|
|
157
|
+
console.log(` ✅ Worktree removed`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 3. Unregister worker from both registries
|
|
162
|
+
if (useBeads) {
|
|
163
|
+
try {
|
|
164
|
+
// Unbind work from agent
|
|
165
|
+
await beadsRegistry.unbindWork(worker.id);
|
|
166
|
+
// Set agent state to error (killed, not done)
|
|
167
|
+
await beadsRegistry.setAgentState(worker.id, 'error');
|
|
168
|
+
// Delete agent bead
|
|
169
|
+
await beadsRegistry.deleteAgent(worker.id);
|
|
170
|
+
} catch {
|
|
171
|
+
// Non-fatal if beads cleanup fails
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
await registry.unregister(worker.id);
|
|
175
|
+
console.log(` ✅ Worker unregistered`);
|
|
176
|
+
|
|
177
|
+
// 4. Note about task status
|
|
178
|
+
console.log(`\n⚠️ Task ${worker.taskId} is still in_progress in beads.`);
|
|
179
|
+
console.log(` Run \`bd update ${worker.taskId} --status open\` to reopen,`);
|
|
180
|
+
console.log(` or \`term work ${worker.taskId}\` to start a new worker.`);
|
|
181
|
+
|
|
182
|
+
} catch (error: any) {
|
|
183
|
+
console.error(`❌ Error: ${error.message}`);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|