@xagent-ai/cli 1.3.6 → 1.4.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/README.md +9 -0
- package/README_CN.md +9 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -1
- package/dist/mcp.d.ts +8 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +53 -20
- package/dist/mcp.js.map +1 -1
- package/dist/sdk-output-adapter.d.ts +79 -0
- package/dist/sdk-output-adapter.d.ts.map +1 -1
- package/dist/sdk-output-adapter.js +118 -0
- package/dist/sdk-output-adapter.js.map +1 -1
- package/dist/session.d.ts +88 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +351 -5
- package/dist/session.js.map +1 -1
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +3 -5
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +1 -0
- package/dist/smart-approval.js.map +1 -1
- package/dist/system-prompt-generator.d.ts +15 -1
- package/dist/system-prompt-generator.d.ts.map +1 -1
- package/dist/system-prompt-generator.js +36 -27
- package/dist/system-prompt-generator.js.map +1 -1
- package/dist/team-manager/index.d.ts +6 -0
- package/dist/team-manager/index.d.ts.map +1 -0
- package/dist/team-manager/index.js +6 -0
- package/dist/team-manager/index.js.map +1 -0
- package/dist/team-manager/message-broker.d.ts +128 -0
- package/dist/team-manager/message-broker.d.ts.map +1 -0
- package/dist/team-manager/message-broker.js +638 -0
- package/dist/team-manager/message-broker.js.map +1 -0
- package/dist/team-manager/team-coordinator.d.ts +45 -0
- package/dist/team-manager/team-coordinator.d.ts.map +1 -0
- package/dist/team-manager/team-coordinator.js +887 -0
- package/dist/team-manager/team-coordinator.js.map +1 -0
- package/dist/team-manager/team-store.d.ts +49 -0
- package/dist/team-manager/team-store.d.ts.map +1 -0
- package/dist/team-manager/team-store.js +436 -0
- package/dist/team-manager/team-store.js.map +1 -0
- package/dist/team-manager/teammate-spawner.d.ts +86 -0
- package/dist/team-manager/teammate-spawner.d.ts.map +1 -0
- package/dist/team-manager/teammate-spawner.js +605 -0
- package/dist/team-manager/teammate-spawner.js.map +1 -0
- package/dist/team-manager/types.d.ts +164 -0
- package/dist/team-manager/types.d.ts.map +1 -0
- package/dist/team-manager/types.js +27 -0
- package/dist/team-manager/types.js.map +1 -0
- package/dist/tools.d.ts +41 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +288 -32
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +20 -0
- package/src/mcp.ts +64 -25
- package/src/sdk-output-adapter.ts +177 -0
- package/src/session.ts +423 -15
- package/src/slash-commands.ts +3 -7
- package/src/smart-approval.ts +1 -0
- package/src/system-prompt-generator.ts +59 -26
- package/src/team-manager/index.ts +5 -0
- package/src/team-manager/message-broker.ts +751 -0
- package/src/team-manager/team-coordinator.ts +1117 -0
- package/src/team-manager/team-store.ts +558 -0
- package/src/team-manager/teammate-spawner.ts +800 -0
- package/src/team-manager/types.ts +206 -0
- package/src/tools.ts +316 -33
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { spawn, execSync } from 'child_process';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { getTeamStore } from './team-store.js';
|
|
7
|
+
import { colors, icons } from '../theme.js';
|
|
8
|
+
const generateId = () => crypto.randomUUID();
|
|
9
|
+
// Graceful shutdown timeout in milliseconds
|
|
10
|
+
const GRACEFUL_SHUTDOWN_TIMEOUT_MS = 30000;
|
|
11
|
+
function getXagentCommand() {
|
|
12
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
13
|
+
const projectRoot = path.resolve(path.dirname(currentFile), '../..');
|
|
14
|
+
const cliPath = path.join(projectRoot, 'dist', 'cli.js');
|
|
15
|
+
return cliPath;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if CLI exists, throw descriptive error if not
|
|
19
|
+
*/
|
|
20
|
+
function validateCliPath() {
|
|
21
|
+
const cliPath = getXagentCommand();
|
|
22
|
+
if (!fs.existsSync(cliPath)) {
|
|
23
|
+
throw new Error(`xAgent CLI not found at ${cliPath}. ` +
|
|
24
|
+
`Please ensure the project is built (run 'npm run build' or 'tsc').`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class TeammateSpawner {
|
|
28
|
+
store;
|
|
29
|
+
activeProcesses = new Map();
|
|
30
|
+
tmuxSessionName = null;
|
|
31
|
+
warnedAboutWindows = false;
|
|
32
|
+
// Output filtering configuration
|
|
33
|
+
static IGNORED_PATTERNS = [
|
|
34
|
+
/^╔[═]+╗$/, // Banner top border
|
|
35
|
+
/^║[^║]+║$/, // Banner content
|
|
36
|
+
/^╚[═]+╝$/, // Banner bottom border
|
|
37
|
+
/^─+$/, // Separator lines
|
|
38
|
+
/^✨ Welcome to XAGENT CLI!$/, // Welcome message
|
|
39
|
+
/^Type \/help to see available commands$/, // Help hint
|
|
40
|
+
/^ℹ Current Mode:$/, // Mode info
|
|
41
|
+
/^\s*✨\s*\w+/, // Mode indicator
|
|
42
|
+
/^\s*🧠 (Local|Remote) Models:$/, // Model info header
|
|
43
|
+
/^\s*→ (LLM|VLM):/, // Model info lines
|
|
44
|
+
/^📝 Registering MCP server/, // MCP registration
|
|
45
|
+
/^🧠 Connecting to \d+ MCP server/, // MCP connection
|
|
46
|
+
/^Connecting to MCP Server/, // MCP connection detail
|
|
47
|
+
/^Loaded \d+ tools from MCP Server/, // MCP tools loaded
|
|
48
|
+
/^MCP Server connected$/, // MCP connected
|
|
49
|
+
/^✓ \d+\/\d+ MCP server/, // MCP summary
|
|
50
|
+
/^\[MCP\] Registered \d+ tool/, // MCP tools registered
|
|
51
|
+
/^✔ Initialization complete$/, // Init complete
|
|
52
|
+
];
|
|
53
|
+
// Patterns that indicate important output (should always show)
|
|
54
|
+
static IMPORTANT_PATTERNS = [
|
|
55
|
+
/✅|✓|✔/, // Success markers
|
|
56
|
+
/❌|✗|✖/, // Error markers
|
|
57
|
+
/⚠|⚠️/, // Warning markers
|
|
58
|
+
/🔍|🔎/, // Search/action markers
|
|
59
|
+
/📝|📄/, // Document markers
|
|
60
|
+
/Tool|tool/, // Tool execution
|
|
61
|
+
/Error|error|ERROR/, // Errors
|
|
62
|
+
/Task completed|completed/, // Task completion
|
|
63
|
+
/Found \d+/, // Search results
|
|
64
|
+
];
|
|
65
|
+
constructor(store) {
|
|
66
|
+
this.store = store || getTeamStore();
|
|
67
|
+
// Validate CLI on construction
|
|
68
|
+
validateCliPath();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check if a line should be filtered out (not displayed)
|
|
72
|
+
*/
|
|
73
|
+
shouldFilterLine(line) {
|
|
74
|
+
const trimmed = line.trim();
|
|
75
|
+
if (!trimmed)
|
|
76
|
+
return true;
|
|
77
|
+
// Check if line matches any ignored pattern
|
|
78
|
+
for (const pattern of TeammateSpawner.IGNORED_PATTERNS) {
|
|
79
|
+
if (pattern.test(trimmed)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Format a teammate output line with proper styling
|
|
87
|
+
*/
|
|
88
|
+
formatOutputLine(memberName, line) {
|
|
89
|
+
const trimmed = line.trim();
|
|
90
|
+
// Use compact prefix format: [name] content
|
|
91
|
+
const prefix = colors.primary(`[${memberName}]`);
|
|
92
|
+
return `${prefix} ${trimmed}`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Format an error line with error styling
|
|
96
|
+
*/
|
|
97
|
+
formatErrorLine(memberName, line) {
|
|
98
|
+
const trimmed = line.trim();
|
|
99
|
+
const prefix = colors.error(`[${memberName}]`);
|
|
100
|
+
return `${prefix} ${trimmed}`;
|
|
101
|
+
}
|
|
102
|
+
isTmuxAvailable() {
|
|
103
|
+
if (process.platform === 'win32') {
|
|
104
|
+
// this.warnWindowsUser('tmux');
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
execSync('which tmux', { stdio: 'ignore' });
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
isInsideTmux() {
|
|
116
|
+
return !!process.env.TMUX;
|
|
117
|
+
}
|
|
118
|
+
isIterm2Available() {
|
|
119
|
+
if (process.platform !== 'darwin') {
|
|
120
|
+
if (process.platform === 'win32') {
|
|
121
|
+
// this.warnWindowsUser('iTerm2');
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
execSync('which it2', { stdio: 'ignore' });
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// /**
|
|
134
|
+
// * Display Windows compatibility warning (only once per session)
|
|
135
|
+
// */
|
|
136
|
+
// private warnWindowsUser(feature: string): void {
|
|
137
|
+
// if (this.warnedAboutWindows) return;
|
|
138
|
+
// this.warnedAboutWindows = true;
|
|
139
|
+
// console.log(colors.warning(
|
|
140
|
+
// `\n[Windows] ${feature} is not available on Windows. ` +
|
|
141
|
+
// `Using 'in-process' mode for parallel agents.\n` +
|
|
142
|
+
// `Note: In-process mode runs teammates in the same terminal. ` +
|
|
143
|
+
// `For true terminal multiplexing on Windows, consider using Windows Terminal with multiple tabs.\n`
|
|
144
|
+
// ));
|
|
145
|
+
// }
|
|
146
|
+
async spawnTeammate(teamId, config, workDir, displayMode = 'auto', brokerPort, initialTaskId, leadId) {
|
|
147
|
+
// Validate required fields with clear error messages
|
|
148
|
+
if (!config.name || config.name.trim() === '') {
|
|
149
|
+
throw new Error('Teammate name is required. ' +
|
|
150
|
+
'Please provide a valid "name" field in the teammates config. ' +
|
|
151
|
+
'Example: { name: "developer", role: "coder", prompt: "..." }');
|
|
152
|
+
}
|
|
153
|
+
if (!config.role || config.role.trim() === '') {
|
|
154
|
+
throw new Error(`Teammate role is required for "${config.name}". ` +
|
|
155
|
+
'Please provide a valid "role" field in the teammates config.');
|
|
156
|
+
}
|
|
157
|
+
if (!config.prompt || config.prompt.trim() === '') {
|
|
158
|
+
throw new Error(`Teammate prompt is required for "${config.name}". ` +
|
|
159
|
+
'Please provide a valid "prompt" field in the teammates config.');
|
|
160
|
+
}
|
|
161
|
+
const memberId = generateId();
|
|
162
|
+
const memberName = config.name.trim();
|
|
163
|
+
const member = {
|
|
164
|
+
memberId,
|
|
165
|
+
name: memberName,
|
|
166
|
+
memberRole: config.role,
|
|
167
|
+
model: config.model,
|
|
168
|
+
status: 'spawning',
|
|
169
|
+
displayMode: 'in-process'
|
|
170
|
+
};
|
|
171
|
+
const savedMember = await this.store.addMember(teamId, member);
|
|
172
|
+
const actualMode = this.resolveDisplayMode(displayMode);
|
|
173
|
+
let processInfo;
|
|
174
|
+
try {
|
|
175
|
+
switch (actualMode) {
|
|
176
|
+
case 'tmux':
|
|
177
|
+
processInfo = await this.spawnWithTmux(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId);
|
|
178
|
+
break;
|
|
179
|
+
case 'iterm2':
|
|
180
|
+
processInfo = await this.spawnWithIterm2(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId);
|
|
181
|
+
break;
|
|
182
|
+
case 'in-process':
|
|
183
|
+
default:
|
|
184
|
+
processInfo = await this.spawnWithNode(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
// Update member status on failure
|
|
190
|
+
await this.store.updateMember(teamId, memberId, {
|
|
191
|
+
status: 'shutdown',
|
|
192
|
+
lastActivity: Date.now()
|
|
193
|
+
});
|
|
194
|
+
// Re-throw with more context
|
|
195
|
+
throw new Error(`Failed to spawn teammate "${config.name}" in ${actualMode} mode: ${error.message}. ` +
|
|
196
|
+
`Consider using a different displayMode or check system requirements.`);
|
|
197
|
+
}
|
|
198
|
+
savedMember.status = 'active';
|
|
199
|
+
savedMember.processId = processInfo.processId;
|
|
200
|
+
savedMember.displayMode = actualMode;
|
|
201
|
+
await this.store.updateMember(teamId, memberId, {
|
|
202
|
+
status: 'active',
|
|
203
|
+
processId: savedMember.processId,
|
|
204
|
+
displayMode: actualMode
|
|
205
|
+
});
|
|
206
|
+
return savedMember;
|
|
207
|
+
}
|
|
208
|
+
resolveDisplayMode(mode) {
|
|
209
|
+
if (mode === 'in-process')
|
|
210
|
+
return 'in-process';
|
|
211
|
+
if (mode === 'tmux' || mode === 'auto') {
|
|
212
|
+
if (this.isTmuxAvailable()) {
|
|
213
|
+
return 'tmux';
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (mode === 'iterm2' || mode === 'auto') {
|
|
217
|
+
if (this.isIterm2Available()) {
|
|
218
|
+
return 'iterm2';
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return 'in-process';
|
|
222
|
+
}
|
|
223
|
+
async spawnWithTmux(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId) {
|
|
224
|
+
const paneName = `xagent-${config.name.replace(/\s+/g, '-')}`;
|
|
225
|
+
const args = this.buildCommandArgs(teamId, memberId, config, brokerPort, false, undefined, initialTaskId, leadId);
|
|
226
|
+
const cliPath = getXagentCommand();
|
|
227
|
+
const cmd = `node "${cliPath}" ${args.join(' ')}`;
|
|
228
|
+
let paneId;
|
|
229
|
+
let windowId;
|
|
230
|
+
const sessionId = this.tmuxSessionName || teamId;
|
|
231
|
+
try {
|
|
232
|
+
if (this.isInsideTmux()) {
|
|
233
|
+
// Split current window and capture the new pane ID
|
|
234
|
+
execSync(`tmux split-window -v -p 50 -P -F '#{pane_id}'`, { cwd: workDir, stdio: ['ignore', 'pipe', 'ignore'] });
|
|
235
|
+
// Get the pane ID of the new pane
|
|
236
|
+
paneId = execSync(`tmux display-message -p '#{pane_id}'`, { cwd: workDir, encoding: 'utf-8' }).trim();
|
|
237
|
+
execSync(`tmux send-keys -t :.+ '${cmd}' Enter`, { cwd: workDir, stdio: 'ignore' });
|
|
238
|
+
execSync(`tmux select-pane -T "${paneName}"`, { cwd: workDir, stdio: 'ignore' });
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// Create or attach to session
|
|
242
|
+
try {
|
|
243
|
+
execSync(`tmux new-session -d -s ${teamId} -x 200 -y 50 -P -F '#{session_id}'`, { cwd: workDir, stdio: 'ignore' });
|
|
244
|
+
this.tmuxSessionName = teamId;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// Session might already exist, that's okay
|
|
248
|
+
}
|
|
249
|
+
// Create new window and get its ID
|
|
250
|
+
windowId = execSync(`tmux new-window -t ${teamId} -n "${paneName}" -P -F '#{window_id}' "${cmd}"`, { cwd: workDir, encoding: 'utf-8' }).trim();
|
|
251
|
+
paneId = execSync(`tmux display-message -t ${windowId} -p '#{pane_id}'`, { encoding: 'utf-8' }).trim();
|
|
252
|
+
}
|
|
253
|
+
// Track the external process
|
|
254
|
+
const external = {
|
|
255
|
+
type: 'tmux',
|
|
256
|
+
paneId,
|
|
257
|
+
windowId,
|
|
258
|
+
sessionId,
|
|
259
|
+
startedAt: Date.now()
|
|
260
|
+
};
|
|
261
|
+
// Store tracking info
|
|
262
|
+
this.activeProcesses.set(memberId, {
|
|
263
|
+
memberId,
|
|
264
|
+
teamId,
|
|
265
|
+
config,
|
|
266
|
+
external
|
|
267
|
+
});
|
|
268
|
+
// Generate a unique process ID for tracking (using hash of pane info)
|
|
269
|
+
const processId = this.generateProcessId('tmux', paneId || windowId || sessionId);
|
|
270
|
+
return { processId, external };
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
console.log(colors.warning(`tmux spawn failed: ${error.message}, falling back to in-process`));
|
|
274
|
+
return this.spawnWithNode(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async spawnWithIterm2(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId) {
|
|
278
|
+
const args = this.buildCommandArgs(teamId, memberId, config, brokerPort, false, undefined, initialTaskId, leadId);
|
|
279
|
+
const cliPath = getXagentCommand();
|
|
280
|
+
const cmd = `node "${cliPath}" ${args.join(' ')}`;
|
|
281
|
+
try {
|
|
282
|
+
// Split pane and get session ID
|
|
283
|
+
const sessionId = execSync(`it2 splitpane -v --session-id`, {
|
|
284
|
+
cwd: workDir,
|
|
285
|
+
encoding: 'utf-8'
|
|
286
|
+
}).trim();
|
|
287
|
+
execSync(`it2 send "${cmd}"`, { cwd: workDir, stdio: 'ignore' });
|
|
288
|
+
const external = {
|
|
289
|
+
type: 'iterm2',
|
|
290
|
+
sessionId,
|
|
291
|
+
startedAt: Date.now()
|
|
292
|
+
};
|
|
293
|
+
this.activeProcesses.set(memberId, {
|
|
294
|
+
memberId,
|
|
295
|
+
teamId,
|
|
296
|
+
config,
|
|
297
|
+
external
|
|
298
|
+
});
|
|
299
|
+
const processId = this.generateProcessId('iterm2', sessionId);
|
|
300
|
+
return { processId, external };
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
console.log(colors.warning(`iTerm2 spawn failed: ${error.message}, falling back to in-process`));
|
|
304
|
+
return this.spawnWithNode(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
async spawnWithNode(teamId, memberId, config, workDir, brokerPort, initialTaskId, leadId) {
|
|
308
|
+
const args = this.buildCommandArgs(teamId, memberId, config, brokerPort, false, undefined, initialTaskId, leadId);
|
|
309
|
+
const cliPath = getXagentCommand();
|
|
310
|
+
const env = {
|
|
311
|
+
...process.env,
|
|
312
|
+
XAGENT_TEAM_MODE: 'true',
|
|
313
|
+
XAGENT_TEAM_ID: teamId,
|
|
314
|
+
XAGENT_MEMBER_ID: memberId,
|
|
315
|
+
XAGENT_MEMBER_NAME: config.name,
|
|
316
|
+
XAGENT_SPAWN_PROMPT: config.prompt,
|
|
317
|
+
};
|
|
318
|
+
if (brokerPort) {
|
|
319
|
+
env.XAGENT_BROKER_PORT = String(brokerPort);
|
|
320
|
+
}
|
|
321
|
+
if (initialTaskId) {
|
|
322
|
+
env.XAGENT_INITIAL_TASK_ID = initialTaskId;
|
|
323
|
+
}
|
|
324
|
+
if (leadId) {
|
|
325
|
+
env.XAGENT_LEAD_ID = leadId;
|
|
326
|
+
}
|
|
327
|
+
let childProcess;
|
|
328
|
+
try {
|
|
329
|
+
childProcess = spawn('node', [cliPath, ...args], {
|
|
330
|
+
cwd: workDir,
|
|
331
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
332
|
+
env
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
throw new Error(`Failed to spawn Node.js process: ${error.message}. ` +
|
|
337
|
+
`Ensure Node.js is installed and the CLI is built.`);
|
|
338
|
+
}
|
|
339
|
+
// Track the process
|
|
340
|
+
this.activeProcesses.set(memberId, {
|
|
341
|
+
childProcess,
|
|
342
|
+
memberId,
|
|
343
|
+
teamId,
|
|
344
|
+
config
|
|
345
|
+
});
|
|
346
|
+
childProcess.stdout?.on('data', (data) => {
|
|
347
|
+
const lines = data.toString().split('\n');
|
|
348
|
+
for (const line of lines) {
|
|
349
|
+
if (!this.shouldFilterLine(line)) {
|
|
350
|
+
console.log(this.formatOutputLine(config.name, line));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
childProcess.stderr?.on('data', (data) => {
|
|
355
|
+
const lines = data.toString().split('\n');
|
|
356
|
+
for (const line of lines) {
|
|
357
|
+
if (line.trim()) {
|
|
358
|
+
console.error(this.formatErrorLine(config.name, line));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
childProcess.on('exit', async (code) => {
|
|
363
|
+
this.activeProcesses.delete(memberId);
|
|
364
|
+
await this.store.updateMember(teamId, memberId, {
|
|
365
|
+
status: 'shutdown',
|
|
366
|
+
lastActivity: Date.now()
|
|
367
|
+
});
|
|
368
|
+
console.log(colors.textMuted(`[${config.name}] ${icons.arrow} exited with code ${code}`));
|
|
369
|
+
});
|
|
370
|
+
childProcess.on('error', (error) => {
|
|
371
|
+
console.error(colors.error(`[${config.name}] SPAWN ERROR: ${error.message}`));
|
|
372
|
+
this.activeProcesses.delete(memberId);
|
|
373
|
+
});
|
|
374
|
+
return { processId: childProcess.pid || Date.now() };
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Generate a deterministic process ID for external processes
|
|
378
|
+
*/
|
|
379
|
+
generateProcessId(type, identifier) {
|
|
380
|
+
// Create a hash from type and identifier to get a consistent number
|
|
381
|
+
const hash = crypto.createHash('md5').update(`${type}:${identifier}`).digest();
|
|
382
|
+
return hash.readUInt32BE(0);
|
|
383
|
+
}
|
|
384
|
+
buildCommandArgs(teamId, memberId, config, brokerPort, isLead = false, isSdk, initialTaskId, leadId) {
|
|
385
|
+
const args = [
|
|
386
|
+
'start',
|
|
387
|
+
'--team-mode',
|
|
388
|
+
'--team-id', teamId,
|
|
389
|
+
'--member-id', memberId,
|
|
390
|
+
'--member-name', config.name,
|
|
391
|
+
];
|
|
392
|
+
const useSdk = isSdk ?? (process.env.XAGENT_SDK === 'true');
|
|
393
|
+
if (useSdk) {
|
|
394
|
+
args.push('--sdk');
|
|
395
|
+
}
|
|
396
|
+
if (isLead) {
|
|
397
|
+
args.push('--is-team-lead');
|
|
398
|
+
}
|
|
399
|
+
if (config.model) {
|
|
400
|
+
args.push('--model', config.model);
|
|
401
|
+
}
|
|
402
|
+
if (brokerPort) {
|
|
403
|
+
args.push('--broker-port', String(brokerPort));
|
|
404
|
+
}
|
|
405
|
+
if (config.prompt) {
|
|
406
|
+
args.push('--initial-prompt', config.prompt);
|
|
407
|
+
}
|
|
408
|
+
if (initialTaskId) {
|
|
409
|
+
args.push('--initial-task-id', initialTaskId);
|
|
410
|
+
}
|
|
411
|
+
if (leadId) {
|
|
412
|
+
args.push('--lead-id', leadId);
|
|
413
|
+
}
|
|
414
|
+
return args;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Gracefully shutdown a teammate with a timeout for task completion.
|
|
418
|
+
*/
|
|
419
|
+
async shutdownTeammate(teamId, memberId, options) {
|
|
420
|
+
const { force = false, timeout = GRACEFUL_SHUTDOWN_TIMEOUT_MS } = options || {};
|
|
421
|
+
const team = await this.store.getTeam(teamId);
|
|
422
|
+
if (!team) {
|
|
423
|
+
return { success: false, reason: `Team ${teamId} not found` };
|
|
424
|
+
}
|
|
425
|
+
const member = team.members.find(m => m.memberId === memberId);
|
|
426
|
+
if (!member) {
|
|
427
|
+
return { success: false, reason: `Member ${memberId} not found` };
|
|
428
|
+
}
|
|
429
|
+
if (member.status !== 'active') {
|
|
430
|
+
return { success: true, reason: `Member already ${member.status}` };
|
|
431
|
+
}
|
|
432
|
+
const tracked = this.activeProcesses.get(memberId);
|
|
433
|
+
// Handle tmux processes
|
|
434
|
+
if (member.displayMode === 'tmux' && tracked?.external) {
|
|
435
|
+
return this.shutdownTmuxProcess(teamId, memberId, tracked.external, force, timeout);
|
|
436
|
+
}
|
|
437
|
+
// Handle iTerm2 processes
|
|
438
|
+
if (member.displayMode === 'iterm2' && tracked?.external) {
|
|
439
|
+
return this.shutdownIterm2Process(teamId, memberId, tracked.external, force, timeout);
|
|
440
|
+
}
|
|
441
|
+
// Handle in-process (ChildProcess)
|
|
442
|
+
if (tracked?.childProcess) {
|
|
443
|
+
return this.shutdownChildProcess(teamId, memberId, tracked.childProcess, force, timeout);
|
|
444
|
+
}
|
|
445
|
+
// No tracked process, just update status
|
|
446
|
+
await this.store.updateMember(teamId, memberId, { status: 'shutdown' });
|
|
447
|
+
return { success: true, reason: 'No active process found' };
|
|
448
|
+
}
|
|
449
|
+
async shutdownTmuxProcess(teamId, memberId, external, force, timeout) {
|
|
450
|
+
try {
|
|
451
|
+
if (!force) {
|
|
452
|
+
// Send graceful shutdown signal via message
|
|
453
|
+
// The teammate should handle this and exit cleanly
|
|
454
|
+
console.log(colors.info(`[Shutdown] Sending graceful shutdown signal to tmux pane...`));
|
|
455
|
+
// Try to send Ctrl+C to the pane for graceful shutdown
|
|
456
|
+
if (external.paneId) {
|
|
457
|
+
execSync(`tmux send-keys -t ${external.paneId} C-c`, { stdio: 'ignore' });
|
|
458
|
+
// Wait for process to exit or timeout
|
|
459
|
+
const startTime = Date.now();
|
|
460
|
+
while (Date.now() - startTime < timeout) {
|
|
461
|
+
try {
|
|
462
|
+
// Check if pane still exists
|
|
463
|
+
execSync(`tmux list-panes -t ${external.paneId}`, { stdio: 'ignore' });
|
|
464
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
// Pane no longer exists
|
|
468
|
+
this.activeProcesses.delete(memberId);
|
|
469
|
+
await this.store.updateMember(teamId, memberId, { status: 'shutdown' });
|
|
470
|
+
return { success: true, reason: 'Graceful shutdown completed' };
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
// Force kill the pane
|
|
476
|
+
if (external.paneId) {
|
|
477
|
+
execSync(`tmux kill-pane -t ${external.paneId}`, { stdio: 'ignore' });
|
|
478
|
+
}
|
|
479
|
+
else if (external.windowId && this.tmuxSessionName) {
|
|
480
|
+
execSync(`tmux kill-window -t ${this.tmuxSessionName}:${external.windowId}`, { stdio: 'ignore' });
|
|
481
|
+
}
|
|
482
|
+
this.activeProcesses.delete(memberId);
|
|
483
|
+
await this.store.updateMember(teamId, memberId, { status: 'shutdown' });
|
|
484
|
+
return { success: true, reason: force ? 'Force killed' : 'Timeout, force killed' };
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
// Pane might already be closed
|
|
488
|
+
this.activeProcesses.delete(memberId);
|
|
489
|
+
await this.store.updateMember(teamId, memberId, { status: 'shutdown' });
|
|
490
|
+
return { success: true, reason: `Process cleanup: ${error.message}` };
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
async shutdownIterm2Process(teamId, memberId, external, force, timeout) {
|
|
494
|
+
try {
|
|
495
|
+
if (!force && external.sessionId) {
|
|
496
|
+
// iTerm2 doesn't have great graceful shutdown support
|
|
497
|
+
// We'll try sending Ctrl+C via the session
|
|
498
|
+
console.log(colors.info(`[Shutdown] Sending graceful shutdown signal to iTerm2 session...`));
|
|
499
|
+
execSync(`it2 send --session ${external.sessionId} \\x03`, { stdio: 'ignore' });
|
|
500
|
+
// Wait briefly for graceful shutdown
|
|
501
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(timeout, 5000)));
|
|
502
|
+
}
|
|
503
|
+
// iTerm2 panes can't be killed programmatically easily
|
|
504
|
+
// The user will need to close the pane manually
|
|
505
|
+
console.log(colors.warning(`[Shutdown] iTerm2 pane for member ${memberId} should be closed manually. ` +
|
|
506
|
+
`The process has been marked as shutdown.`));
|
|
507
|
+
this.activeProcesses.delete(memberId);
|
|
508
|
+
await this.store.updateMember(teamId, memberId, { status: 'shutdown' });
|
|
509
|
+
return { success: true, reason: 'iTerm2 session marked as shutdown (close manually)' };
|
|
510
|
+
}
|
|
511
|
+
catch (error) {
|
|
512
|
+
this.activeProcesses.delete(memberId);
|
|
513
|
+
await this.store.updateMember(teamId, memberId, { status: 'shutdown' });
|
|
514
|
+
return { success: true, reason: `Process cleanup: ${error.message}` };
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
async shutdownChildProcess(teamId, memberId, childProcess, force, timeout) {
|
|
518
|
+
return new Promise((resolve) => {
|
|
519
|
+
const cleanup = () => {
|
|
520
|
+
this.activeProcesses.delete(memberId);
|
|
521
|
+
this.store.updateMember(teamId, memberId, { status: 'shutdown' }).catch(() => { });
|
|
522
|
+
};
|
|
523
|
+
// Set up timeout for force kill
|
|
524
|
+
const timeoutId = setTimeout(() => {
|
|
525
|
+
console.log(colors.warning(`[Shutdown] Timeout reached, force killing process ${childProcess.pid}`));
|
|
526
|
+
childProcess.kill('SIGKILL');
|
|
527
|
+
cleanup();
|
|
528
|
+
resolve({ success: true, reason: 'Timeout, force killed with SIGKILL' });
|
|
529
|
+
}, timeout);
|
|
530
|
+
// Handle process exit
|
|
531
|
+
childProcess.once('exit', (code) => {
|
|
532
|
+
clearTimeout(timeoutId);
|
|
533
|
+
cleanup();
|
|
534
|
+
resolve({ success: true, reason: `Process exited with code ${code}` });
|
|
535
|
+
});
|
|
536
|
+
if (force) {
|
|
537
|
+
// Force kill immediately
|
|
538
|
+
childProcess.kill('SIGKILL');
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
// Send SIGTERM for graceful shutdown
|
|
542
|
+
console.log(colors.info(`[Shutdown] Sending SIGTERM to process ${childProcess.pid}`));
|
|
543
|
+
childProcess.kill('SIGTERM');
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
async shutdownAllTeammates(teamId) {
|
|
548
|
+
const team = await this.store.getTeam(teamId);
|
|
549
|
+
if (!team) {
|
|
550
|
+
return { success: false, results: new Map() };
|
|
551
|
+
}
|
|
552
|
+
const results = new Map();
|
|
553
|
+
for (const member of team.members) {
|
|
554
|
+
if (member.status === 'active' && member.role !== 'lead') {
|
|
555
|
+
const result = await this.shutdownTeammate(teamId, member.memberId);
|
|
556
|
+
results.set(member.memberId, result);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
// Clean up tmux session
|
|
560
|
+
if (this.tmuxSessionName) {
|
|
561
|
+
try {
|
|
562
|
+
execSync(`tmux kill-session -t ${this.tmuxSessionName}`, { stdio: 'ignore' });
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
// Session might already be closed
|
|
566
|
+
}
|
|
567
|
+
this.tmuxSessionName = null;
|
|
568
|
+
}
|
|
569
|
+
return {
|
|
570
|
+
success: Array.from(results.values()).every(r => r.success),
|
|
571
|
+
results
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
getActiveProcesses() {
|
|
575
|
+
return Array.from(this.activeProcesses.keys());
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Get detailed info about a tracked process
|
|
579
|
+
*/
|
|
580
|
+
getProcessInfo(memberId) {
|
|
581
|
+
return this.activeProcesses.get(memberId);
|
|
582
|
+
}
|
|
583
|
+
isDisplayModeAvailable(mode) {
|
|
584
|
+
switch (mode) {
|
|
585
|
+
case 'tmux':
|
|
586
|
+
return this.isTmuxAvailable();
|
|
587
|
+
case 'iterm2':
|
|
588
|
+
return this.isIterm2Available();
|
|
589
|
+
case 'in-process':
|
|
590
|
+
return true;
|
|
591
|
+
case 'auto':
|
|
592
|
+
return true;
|
|
593
|
+
default:
|
|
594
|
+
return false;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
let teammateSpawnerInstance = null;
|
|
599
|
+
export function getTeammateSpawner(store) {
|
|
600
|
+
if (!teammateSpawnerInstance) {
|
|
601
|
+
teammateSpawnerInstance = new TeammateSpawner(store);
|
|
602
|
+
}
|
|
603
|
+
return teammateSpawnerInstance;
|
|
604
|
+
}
|
|
605
|
+
//# sourceMappingURL=teammate-spawner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teammate-spawner.js","sourceRoot":"","sources":["../../src/team-manager/teammate-spawner.ts"],"names":[],"mappings":"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"}
|