mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 22:49:41 +02:00
feat: replace SpawnDetector with MCP server for spawn1337 protocol
Instead of parsing terminal output for <spawn1337> tags, spawn capabilities are now exposed as native MCP tools that Claude Code can call directly. The MCP server (stdio transport) proxies requests to the existing REST API. - Add src/mcp-server.ts with 6 tools: spawn_agent, list_agents, get_agent_status, get_agent_result, send_agent_message, cancel_agent - Remove src/spawn-detector.ts and all references in session.ts/server.ts - Add CLAUDEMAN_API_URL env var propagation to sessions and screens - Write .mcp.json to case directories during creation - Remove spawn1337 tag documentation from case-template.md - Add claudeman-mcp bin entry to package.json Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+26
-28
@@ -1036,6 +1036,9 @@ export class WebServer extends EventEmitter {
|
||||
const claudeMd = generateClaudeMd(name, description || '', templatePath);
|
||||
writeFileSync(join(casePath, 'CLAUDE.md'), claudeMd);
|
||||
|
||||
// Write .mcp.json for Claude Code to discover spawn tools
|
||||
this.writeMcpConfig(casePath);
|
||||
|
||||
this.broadcast('case:created', { name, path: casePath });
|
||||
|
||||
return { success: true, case: { name, path: casePath } };
|
||||
@@ -1173,6 +1176,9 @@ export class WebServer extends EventEmitter {
|
||||
const claudeMd = generateClaudeMd(caseName, '', templatePath);
|
||||
writeFileSync(join(casePath, 'CLAUDE.md'), claudeMd);
|
||||
|
||||
// Write .mcp.json for Claude Code to discover spawn tools
|
||||
this.writeMcpConfig(casePath);
|
||||
|
||||
this.broadcast('case:created', { name: caseName, path: casePath });
|
||||
} catch (err) {
|
||||
return { success: false, error: `Failed to create case: ${getErrorMessage(err)}` };
|
||||
@@ -1636,34 +1642,6 @@ export class WebServer extends EventEmitter {
|
||||
this.broadcast('session:ralphCompletionDetected', { sessionId: session.id, phrase });
|
||||
});
|
||||
|
||||
// Spawn1337 protocol events
|
||||
session.on('spawnRequested', (filePath: string) => {
|
||||
this.spawnOrchestrator.handleSpawnRequest(
|
||||
filePath,
|
||||
session.id,
|
||||
session.workingDir,
|
||||
session.parentAgentId ? 1 : 0 // Simple depth tracking
|
||||
).catch(err => {
|
||||
console.error(`[Server] Spawn request failed for session ${session.id}:`, getErrorMessage(err));
|
||||
});
|
||||
});
|
||||
|
||||
session.on('spawnStatusRequested', (agentId: string) => {
|
||||
const status = this.spawnOrchestrator.getAgentStatus(agentId);
|
||||
this.broadcast('spawn:statusResponse', { sessionId: session.id, agentId, status });
|
||||
});
|
||||
|
||||
session.on('spawnCancelRequested', (agentId: string) => {
|
||||
this.spawnOrchestrator.cancelAgent(agentId, 'Cancelled by parent session').catch(err => {
|
||||
console.error(`[Server] Spawn cancel failed:`, getErrorMessage(err));
|
||||
});
|
||||
});
|
||||
|
||||
session.on('spawnMessageToChild', (agentId: string, content: string) => {
|
||||
this.spawnOrchestrator.sendMessageToAgent(agentId, content).catch(err => {
|
||||
console.error(`[Server] Spawn message failed:`, getErrorMessage(err));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private setupRespawnListeners(sessionId: string, controller: RespawnController): void {
|
||||
@@ -1829,6 +1807,23 @@ export class WebServer extends EventEmitter {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write .mcp.json to a case directory for Claude Code to discover spawn MCP tools.
|
||||
*/
|
||||
private writeMcpConfig(casePath: string): void {
|
||||
const projectRoot = join(__dirname, '..', '..');
|
||||
const mcpServerPath = join(projectRoot, 'dist', 'mcp-server.js');
|
||||
const mcpConfig = {
|
||||
mcpServers: {
|
||||
'claudeman-spawn': {
|
||||
command: 'node',
|
||||
args: [mcpServerPath],
|
||||
},
|
||||
},
|
||||
};
|
||||
writeFileSync(join(casePath, '.mcp.json'), JSON.stringify(mcpConfig, null, 2) + '\n');
|
||||
}
|
||||
|
||||
private async startScheduledRun(prompt: string, workingDir: string, durationMinutes: number): Promise<ScheduledRun> {
|
||||
const id = uuidv4();
|
||||
const now = Date.now();
|
||||
@@ -2164,6 +2159,9 @@ export class WebServer extends EventEmitter {
|
||||
await this.app.listen({ port: this.port, host: '0.0.0.0' });
|
||||
console.log(`Claudeman web interface running at http://localhost:${this.port}`);
|
||||
|
||||
// Set API URL for child processes (MCP server, spawned sessions)
|
||||
process.env.CLAUDEMAN_API_URL = `http://localhost:${this.port}`;
|
||||
|
||||
// Start scheduled runs cleanup timer
|
||||
this.scheduledCleanupTimer = setInterval(() => {
|
||||
this.cleanupScheduledRuns();
|
||||
|
||||
Reference in New Issue
Block a user