nightshift-mcp 1.0.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 +670 -0
- package/dist/agent-spawner.d.ts +55 -0
- package/dist/agent-spawner.d.ts.map +1 -0
- package/dist/agent-spawner.js +468 -0
- package/dist/agent-spawner.js.map +1 -0
- package/dist/chat-manager.d.ts +72 -0
- package/dist/chat-manager.d.ts.map +1 -0
- package/dist/chat-manager.js +331 -0
- package/dist/chat-manager.js.map +1 -0
- package/dist/daemon.d.ts +65 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +563 -0
- package/dist/daemon.js.map +1 -0
- package/dist/file-lock.d.ts +41 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +157 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2433 -0
- package/dist/index.js.map +1 -0
- package/dist/ralph-manager.d.ts +148 -0
- package/dist/ralph-manager.d.ts.map +1 -0
- package/dist/ralph-manager.js +399 -0
- package/dist/ralph-manager.js.map +1 -0
- package/dist/tool-registry.d.ts +130 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +280 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/agents.d.ts +7 -0
- package/dist/tools/agents.d.ts.map +1 -0
- package/dist/tools/agents.js +366 -0
- package/dist/tools/agents.js.map +1 -0
- package/dist/tools/bugs.d.ts +6 -0
- package/dist/tools/bugs.d.ts.map +1 -0
- package/dist/tools/bugs.js +184 -0
- package/dist/tools/bugs.js.map +1 -0
- package/dist/tools/chat.d.ts +10 -0
- package/dist/tools/chat.d.ts.map +1 -0
- package/dist/tools/chat.js +287 -0
- package/dist/tools/chat.js.map +1 -0
- package/dist/tools/index.d.ts +33 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +51 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/prd.d.ts +8 -0
- package/dist/tools/prd.d.ts.map +1 -0
- package/dist/tools/prd.js +275 -0
- package/dist/tools/prd.js.map +1 -0
- package/dist/tools/progress.d.ts +5 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +81 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/tools/savepoints.d.ts +5 -0
- package/dist/tools/savepoints.d.ts.map +1 -0
- package/dist/tools/savepoints.js +100 -0
- package/dist/tools/savepoints.js.map +1 -0
- package/dist/tools/utility.d.ts +4 -0
- package/dist/tools/utility.d.ts.map +1 -0
- package/dist/tools/utility.js +375 -0
- package/dist/tools/utility.js.map +1 -0
- package/dist/tools/workflow.d.ts +10 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +321 -0
- package/dist/tools/workflow.js.map +1 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/workflow-manager.d.ts +154 -0
- package/dist/workflow-manager.d.ts.map +1 -0
- package/dist/workflow-manager.js +356 -0
- package/dist/workflow-manager.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type AgentType = "claude" | "codex" | "gemini" | "vibe";
|
|
2
|
+
export interface SpawnOptions {
|
|
3
|
+
agent: AgentType;
|
|
4
|
+
prompt: string;
|
|
5
|
+
projectPath: string;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
background?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SpawnResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
output: string;
|
|
12
|
+
exitCode: number | null;
|
|
13
|
+
pid?: number;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Spawn an AI agent as a subprocess
|
|
18
|
+
* For agents requiring PTY, uses script command to allocate one
|
|
19
|
+
*/
|
|
20
|
+
export declare function spawnAgent(options: SpawnOptions): Promise<SpawnResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Spawn an agent in the background (non-blocking)
|
|
23
|
+
* Uses safe prompt escaping to prevent command injection
|
|
24
|
+
* Uses PTY allocation via `script` command for agents that require it (like Codex)
|
|
25
|
+
*/
|
|
26
|
+
export declare function spawnAgentBackground(options: SpawnOptions): {
|
|
27
|
+
pid: number | undefined;
|
|
28
|
+
outputFile: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Check if an agent CLI is available (binary exists)
|
|
33
|
+
*/
|
|
34
|
+
export declare function isAgentAvailable(agent: AgentType): Promise<boolean>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if an agent can actually run (verifies PTY requirements are met)
|
|
37
|
+
*/
|
|
38
|
+
export declare function canAgentRun(agent: AgentType): Promise<{
|
|
39
|
+
available: boolean;
|
|
40
|
+
canRun: boolean;
|
|
41
|
+
reason?: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Get list of available agents with their run status
|
|
45
|
+
*/
|
|
46
|
+
export declare function getAvailableAgents(): Promise<AgentType[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Get detailed status of all agents
|
|
49
|
+
*/
|
|
50
|
+
export declare function getAgentStatus(): Promise<Record<AgentType, {
|
|
51
|
+
available: boolean;
|
|
52
|
+
canRun: boolean;
|
|
53
|
+
reason?: string;
|
|
54
|
+
}>>;
|
|
55
|
+
//# sourceMappingURL=agent-spawner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-spawner.d.ts","sourceRoot":"","sources":["../src/agent-spawner.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAI/D,MAAM,WAAW,YAAY;IAE3B,KAAK,EAAE,SAAS,CAAC;IAEjB,MAAM,EAAE,MAAM,CAAC;IAEf,WAAW,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,UAAU,CAAC,EAAE,OAAO,CAAC;CAEtB;AAID,MAAM,WAAW,WAAW;IAE1B,OAAO,EAAE,OAAO,CAAC;IAEjB,MAAM,EAAE,MAAM,CAAC;IAEf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,KAAK,CAAC,EAAE,MAAM,CAAC;CAEhB;AAuFD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsG5E;AAmJD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG;IAC3D,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAwHA;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAczE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;IAC3D,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAyBD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAW/D;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAC7C,MAAM,CAAC,SAAS,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAC5E,CAYA"}
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { spawn, execSync } from "child_process";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
/**
|
|
5
|
+
* Check if the `script` command is available (for PTY allocation)
|
|
6
|
+
*/
|
|
7
|
+
function hasScriptCommand() {
|
|
8
|
+
try {
|
|
9
|
+
execSync("which script", { stdio: "ignore" });
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the CLI command and configuration for each agent type
|
|
18
|
+
*/
|
|
19
|
+
function getAgentConfig(agent) {
|
|
20
|
+
switch (agent) {
|
|
21
|
+
case "claude":
|
|
22
|
+
return {
|
|
23
|
+
cmd: "claude",
|
|
24
|
+
args: ["--dangerously-skip-permissions", "--print"],
|
|
25
|
+
requiresPty: false, // Claude works well without PTY
|
|
26
|
+
promptDelivery: "stdin",
|
|
27
|
+
};
|
|
28
|
+
case "codex":
|
|
29
|
+
// Use `codex exec` for non-interactive mode - no PTY required
|
|
30
|
+
return {
|
|
31
|
+
cmd: "codex",
|
|
32
|
+
args: ["exec", "--dangerously-bypass-approvals-and-sandbox"],
|
|
33
|
+
requiresPty: false, // exec subcommand works without PTY
|
|
34
|
+
promptDelivery: "stdin",
|
|
35
|
+
};
|
|
36
|
+
case "gemini":
|
|
37
|
+
// Use --yolo to auto-approve all tool actions (like file writes)
|
|
38
|
+
return {
|
|
39
|
+
cmd: "gemini",
|
|
40
|
+
args: ["--yolo"],
|
|
41
|
+
requiresPty: false, // Gemini works without PTY
|
|
42
|
+
promptDelivery: "stdin",
|
|
43
|
+
};
|
|
44
|
+
case "vibe":
|
|
45
|
+
// -p enables programmatic mode with auto-approve
|
|
46
|
+
// --output text gives clean output without JSON wrapper
|
|
47
|
+
return {
|
|
48
|
+
cmd: "vibe",
|
|
49
|
+
args: ["--output", "text"],
|
|
50
|
+
requiresPty: false,
|
|
51
|
+
promptDelivery: "flag",
|
|
52
|
+
promptFlag: "-p",
|
|
53
|
+
};
|
|
54
|
+
default:
|
|
55
|
+
throw new Error(`Unknown agent type: ${agent}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated Use getAgentConfig instead
|
|
60
|
+
*/
|
|
61
|
+
function getAgentCommand(agent) {
|
|
62
|
+
const config = getAgentConfig(agent);
|
|
63
|
+
return { cmd: config.cmd, args: config.args };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Spawn an AI agent as a subprocess
|
|
67
|
+
* For agents requiring PTY, uses script command to allocate one
|
|
68
|
+
*/
|
|
69
|
+
export async function spawnAgent(options) {
|
|
70
|
+
const { agent, prompt, projectPath, timeout = 5 * 60 * 1000 } = options;
|
|
71
|
+
const config = getAgentConfig(agent);
|
|
72
|
+
const { cmd, args, requiresPty, promptDelivery, promptFlag } = config;
|
|
73
|
+
// For agents that require PTY, we need to use the script command
|
|
74
|
+
if (requiresPty) {
|
|
75
|
+
return spawnAgentWithPty(options);
|
|
76
|
+
}
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
let output = "";
|
|
79
|
+
let errorOutput = "";
|
|
80
|
+
let timedOut = false;
|
|
81
|
+
const finalArgs = [...args];
|
|
82
|
+
if (promptDelivery === "flag") {
|
|
83
|
+
if (!promptFlag) {
|
|
84
|
+
throw new Error(`Agent '${agent}' is configured for flag-based prompt delivery but no promptFlag is defined.`);
|
|
85
|
+
}
|
|
86
|
+
finalArgs.push(promptFlag, prompt);
|
|
87
|
+
}
|
|
88
|
+
const proc = spawn(cmd, finalArgs, {
|
|
89
|
+
cwd: projectPath,
|
|
90
|
+
env: {
|
|
91
|
+
...process.env,
|
|
92
|
+
ROBOT_CHAT_PROJECT_PATH: projectPath,
|
|
93
|
+
},
|
|
94
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
95
|
+
});
|
|
96
|
+
// Set timeout - also kill process group to handle child processes
|
|
97
|
+
const timeoutId = setTimeout(() => {
|
|
98
|
+
timedOut = true;
|
|
99
|
+
// Try SIGTERM first
|
|
100
|
+
proc.kill("SIGTERM");
|
|
101
|
+
// Force kill after 5 seconds if still alive
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
try {
|
|
104
|
+
// Kill process group if possible (negative PID)
|
|
105
|
+
if (proc.pid) {
|
|
106
|
+
process.kill(-proc.pid, "SIGKILL");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Process may already be dead
|
|
111
|
+
proc.kill("SIGKILL");
|
|
112
|
+
}
|
|
113
|
+
}, 5000);
|
|
114
|
+
}, timeout);
|
|
115
|
+
// Capture stdout
|
|
116
|
+
proc.stdout.on("data", (data) => {
|
|
117
|
+
output += data.toString();
|
|
118
|
+
});
|
|
119
|
+
// Capture stderr
|
|
120
|
+
proc.stderr.on("data", (data) => {
|
|
121
|
+
errorOutput += data.toString();
|
|
122
|
+
});
|
|
123
|
+
// Send prompt via stdin if required
|
|
124
|
+
if (promptDelivery === "stdin") {
|
|
125
|
+
proc.stdin.write(prompt);
|
|
126
|
+
proc.stdin.end();
|
|
127
|
+
}
|
|
128
|
+
// Handle completion
|
|
129
|
+
proc.on("close", (code) => {
|
|
130
|
+
clearTimeout(timeoutId);
|
|
131
|
+
if (timedOut) {
|
|
132
|
+
resolve({
|
|
133
|
+
success: false,
|
|
134
|
+
output,
|
|
135
|
+
exitCode: code,
|
|
136
|
+
error: `Agent timed out after ${timeout / 1000} seconds`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
resolve({
|
|
141
|
+
success: code === 0,
|
|
142
|
+
output: output || errorOutput,
|
|
143
|
+
exitCode: code,
|
|
144
|
+
pid: proc.pid,
|
|
145
|
+
error: code !== 0 ? errorOutput || `Exit code: ${code}` : undefined,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
proc.on("error", (err) => {
|
|
150
|
+
clearTimeout(timeoutId);
|
|
151
|
+
resolve({
|
|
152
|
+
success: false,
|
|
153
|
+
output: "",
|
|
154
|
+
exitCode: null,
|
|
155
|
+
error: `Failed to spawn ${agent}: ${err.message}`,
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Spawn an agent that requires a PTY using the script command
|
|
162
|
+
*/
|
|
163
|
+
async function spawnAgentWithPty(options) {
|
|
164
|
+
const { agent, prompt, projectPath, timeout = 5 * 60 * 1000 } = options;
|
|
165
|
+
const config = getAgentConfig(agent);
|
|
166
|
+
const { cmd, args } = config;
|
|
167
|
+
// Check for script command
|
|
168
|
+
if (!hasScriptCommand()) {
|
|
169
|
+
return {
|
|
170
|
+
success: false,
|
|
171
|
+
output: "",
|
|
172
|
+
exitCode: 1,
|
|
173
|
+
error: `Agent ${agent} requires a PTY but 'script' command is not available. Please install util-linux or bsdmainutils.`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// Create temp directory for prompt file
|
|
177
|
+
const outputDir = path.join(projectPath, ".robot-chat");
|
|
178
|
+
if (!fs.existsSync(outputDir)) {
|
|
179
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
180
|
+
}
|
|
181
|
+
const timestamp = Date.now();
|
|
182
|
+
const promptFile = path.join(outputDir, `prompt-${agent}-${timestamp}.txt`);
|
|
183
|
+
fs.writeFileSync(promptFile, prompt, "utf-8");
|
|
184
|
+
// Build the command
|
|
185
|
+
const agentCmd = `cat "${promptFile}" | ${cmd} ${args.join(" ")}`;
|
|
186
|
+
// Build script command based on platform
|
|
187
|
+
const platform = process.platform;
|
|
188
|
+
let scriptArgs;
|
|
189
|
+
if (platform === "darwin") {
|
|
190
|
+
// macOS: script -q /dev/null <shell-command>
|
|
191
|
+
scriptArgs = ["-q", "/dev/null", "bash", "-c", agentCmd];
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Linux: script -q -c <command> /dev/null
|
|
195
|
+
scriptArgs = ["-q", "-c", agentCmd, "/dev/null"];
|
|
196
|
+
}
|
|
197
|
+
return new Promise((resolve) => {
|
|
198
|
+
let output = "";
|
|
199
|
+
let errorOutput = "";
|
|
200
|
+
let timedOut = false;
|
|
201
|
+
const proc = spawn("script", scriptArgs, {
|
|
202
|
+
cwd: projectPath,
|
|
203
|
+
env: {
|
|
204
|
+
...process.env,
|
|
205
|
+
ROBOT_CHAT_PROJECT_PATH: projectPath,
|
|
206
|
+
TERM: "xterm-256color", // Provide a terminal type
|
|
207
|
+
},
|
|
208
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
209
|
+
});
|
|
210
|
+
// Set timeout
|
|
211
|
+
const timeoutId = setTimeout(() => {
|
|
212
|
+
timedOut = true;
|
|
213
|
+
proc.kill("SIGTERM");
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
try {
|
|
216
|
+
if (proc.pid) {
|
|
217
|
+
process.kill(-proc.pid, "SIGKILL");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
proc.kill("SIGKILL");
|
|
222
|
+
}
|
|
223
|
+
}, 5000);
|
|
224
|
+
}, timeout);
|
|
225
|
+
// Capture stdout
|
|
226
|
+
proc.stdout.on("data", (data) => {
|
|
227
|
+
output += data.toString();
|
|
228
|
+
});
|
|
229
|
+
// Capture stderr
|
|
230
|
+
proc.stderr.on("data", (data) => {
|
|
231
|
+
errorOutput += data.toString();
|
|
232
|
+
});
|
|
233
|
+
// Handle completion
|
|
234
|
+
proc.on("close", (code) => {
|
|
235
|
+
clearTimeout(timeoutId);
|
|
236
|
+
// Clean up prompt file
|
|
237
|
+
try {
|
|
238
|
+
if (fs.existsSync(promptFile)) {
|
|
239
|
+
fs.unlinkSync(promptFile);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// Ignore cleanup errors
|
|
244
|
+
}
|
|
245
|
+
// Strip terminal escape sequences from output
|
|
246
|
+
const cleanOutput = stripAnsiEscapes(output);
|
|
247
|
+
if (timedOut) {
|
|
248
|
+
resolve({
|
|
249
|
+
success: false,
|
|
250
|
+
output: cleanOutput,
|
|
251
|
+
exitCode: code,
|
|
252
|
+
error: `Agent timed out after ${timeout / 1000} seconds`,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
resolve({
|
|
257
|
+
success: code === 0,
|
|
258
|
+
output: cleanOutput || errorOutput,
|
|
259
|
+
exitCode: code,
|
|
260
|
+
pid: proc.pid,
|
|
261
|
+
error: code !== 0 ? errorOutput || `Exit code: ${code}` : undefined,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
proc.on("error", (err) => {
|
|
266
|
+
clearTimeout(timeoutId);
|
|
267
|
+
// Clean up prompt file
|
|
268
|
+
try {
|
|
269
|
+
if (fs.existsSync(promptFile)) {
|
|
270
|
+
fs.unlinkSync(promptFile);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
// Ignore cleanup errors
|
|
275
|
+
}
|
|
276
|
+
resolve({
|
|
277
|
+
success: false,
|
|
278
|
+
output: "",
|
|
279
|
+
exitCode: null,
|
|
280
|
+
error: `Failed to spawn ${agent} with PTY: ${err.message}`,
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Strip ANSI escape sequences from output
|
|
287
|
+
*/
|
|
288
|
+
function stripAnsiEscapes(str) {
|
|
289
|
+
// eslint-disable-next-line no-control-regex
|
|
290
|
+
return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Spawn an agent in the background (non-blocking)
|
|
294
|
+
* Uses safe prompt escaping to prevent command injection
|
|
295
|
+
* Uses PTY allocation via `script` command for agents that require it (like Codex)
|
|
296
|
+
*/
|
|
297
|
+
export function spawnAgentBackground(options) {
|
|
298
|
+
const { agent, prompt, projectPath } = options;
|
|
299
|
+
const config = getAgentConfig(agent);
|
|
300
|
+
const { cmd, args, requiresPty, promptDelivery, promptFlag } = config;
|
|
301
|
+
// Create output file for capturing results
|
|
302
|
+
const outputDir = path.join(projectPath, ".robot-chat");
|
|
303
|
+
if (!fs.existsSync(outputDir)) {
|
|
304
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
305
|
+
}
|
|
306
|
+
const timestamp = Date.now();
|
|
307
|
+
const outputFile = path.join(outputDir, `agent-${agent}-${timestamp}.log`);
|
|
308
|
+
// Write prompt to a temporary file to avoid shell injection entirely
|
|
309
|
+
const promptFile = path.join(outputDir, `prompt-${agent}-${timestamp}.txt`);
|
|
310
|
+
fs.writeFileSync(promptFile, prompt, "utf-8");
|
|
311
|
+
// Check if PTY is needed but script command is unavailable
|
|
312
|
+
if (requiresPty && !hasScriptCommand()) {
|
|
313
|
+
fs.writeFileSync(outputFile, `Agent: ${agent}\nStarted: ${new Date().toISOString()}\n---\nError: Agent ${agent} requires a PTY but 'script' command is not available.\nPlease install 'script' (usually part of util-linux or bsdmainutils).\n---\nFinished: ${new Date().toISOString()}\nExit Code: 1\n`);
|
|
314
|
+
return {
|
|
315
|
+
pid: undefined,
|
|
316
|
+
outputFile,
|
|
317
|
+
error: `Agent ${agent} requires a PTY but 'script' command is not available`,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
// Build the command that will run the agent
|
|
321
|
+
let agentCmd;
|
|
322
|
+
if (promptDelivery === "flag") {
|
|
323
|
+
if (!promptFlag) {
|
|
324
|
+
throw new Error(`Agent '${agent}' is configured for flag-based prompt delivery but no promptFlag is defined.`);
|
|
325
|
+
}
|
|
326
|
+
// Note: This can be subject to ARG_MAX limits if the prompt is very large
|
|
327
|
+
agentCmd = `${cmd} ${args.join(" ")} ${promptFlag} "$(cat '${promptFile}')"`;
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
// Assumes stdin
|
|
331
|
+
agentCmd = `cat "${promptFile}" | ${cmd} ${args.join(" ")}`;
|
|
332
|
+
}
|
|
333
|
+
// Create wrapper script based on PTY requirements
|
|
334
|
+
let wrapperScript;
|
|
335
|
+
if (requiresPty) {
|
|
336
|
+
// Use 'script' command to allocate a PTY for agents that need it
|
|
337
|
+
// macOS: script -q <outputfile> <command>
|
|
338
|
+
// Linux: script -q -c <command> <outputfile>
|
|
339
|
+
const platform = process.platform;
|
|
340
|
+
if (platform === "darwin") {
|
|
341
|
+
// macOS version of script
|
|
342
|
+
wrapperScript = `
|
|
343
|
+
echo "Agent: ${agent}" > "${outputFile}"
|
|
344
|
+
echo "Started: $(date)" >> "${outputFile}"
|
|
345
|
+
echo "PTY: allocated via script (macOS)" >> "${outputFile}"
|
|
346
|
+
echo "---" >> "${outputFile}"
|
|
347
|
+
script -q /dev/null bash -c '${agentCmd}' >> "${outputFile}" 2>&1
|
|
348
|
+
EXIT_CODE=$?
|
|
349
|
+
echo "---" >> "${outputFile}"
|
|
350
|
+
echo "Finished: $(date)" >> "${outputFile}"
|
|
351
|
+
echo "Exit Code: $EXIT_CODE" >> "${outputFile}"
|
|
352
|
+
rm -f "${promptFile}"
|
|
353
|
+
exit $EXIT_CODE
|
|
354
|
+
`;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
// Linux version of script
|
|
358
|
+
wrapperScript = `
|
|
359
|
+
echo "Agent: ${agent}" > "${outputFile}"
|
|
360
|
+
echo "Started: $(date)" >> "${outputFile}"
|
|
361
|
+
echo "PTY: allocated via script (Linux)" >> "${outputFile}"
|
|
362
|
+
echo "---" >> "${outputFile}"
|
|
363
|
+
script -q -c '${agentCmd}' /dev/null >> "${outputFile}" 2>&1
|
|
364
|
+
EXIT_CODE=$?
|
|
365
|
+
echo "---" >> "${outputFile}"
|
|
366
|
+
echo "Finished: $(date)" >> "${outputFile}"
|
|
367
|
+
echo "Exit Code: $EXIT_CODE" >> "${outputFile}"
|
|
368
|
+
rm -f "${promptFile}"
|
|
369
|
+
exit $EXIT_CODE
|
|
370
|
+
`;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
// Standard spawning without PTY
|
|
375
|
+
wrapperScript = `
|
|
376
|
+
echo "Agent: ${agent}" > "${outputFile}"
|
|
377
|
+
echo "Started: $(date)" >> "${outputFile}"
|
|
378
|
+
echo "---" >> "${outputFile}"
|
|
379
|
+
${agentCmd} >> "${outputFile}" 2>&1
|
|
380
|
+
EXIT_CODE=$?
|
|
381
|
+
echo "---" >> "${outputFile}"
|
|
382
|
+
echo "Finished: $(date)" >> "${outputFile}"
|
|
383
|
+
echo "Exit Code: $EXIT_CODE" >> "${outputFile}"
|
|
384
|
+
rm -f "${promptFile}"
|
|
385
|
+
exit $EXIT_CODE
|
|
386
|
+
`;
|
|
387
|
+
}
|
|
388
|
+
const proc = spawn("bash", ["-c", wrapperScript], {
|
|
389
|
+
cwd: projectPath,
|
|
390
|
+
env: {
|
|
391
|
+
...process.env,
|
|
392
|
+
ROBOT_CHAT_PROJECT_PATH: projectPath,
|
|
393
|
+
},
|
|
394
|
+
detached: true,
|
|
395
|
+
stdio: "ignore",
|
|
396
|
+
});
|
|
397
|
+
proc.unref();
|
|
398
|
+
return {
|
|
399
|
+
pid: proc.pid,
|
|
400
|
+
outputFile,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Check if an agent CLI is available (binary exists)
|
|
405
|
+
*/
|
|
406
|
+
export async function isAgentAvailable(agent) {
|
|
407
|
+
const config = getAgentConfig(agent);
|
|
408
|
+
return new Promise((resolve) => {
|
|
409
|
+
const proc = spawn("which", [config.cmd]);
|
|
410
|
+
proc.on("close", (code) => {
|
|
411
|
+
resolve(code === 0);
|
|
412
|
+
});
|
|
413
|
+
proc.on("error", () => {
|
|
414
|
+
resolve(false);
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Check if an agent can actually run (verifies PTY requirements are met)
|
|
420
|
+
*/
|
|
421
|
+
export async function canAgentRun(agent) {
|
|
422
|
+
const config = getAgentConfig(agent);
|
|
423
|
+
const available = await isAgentAvailable(agent);
|
|
424
|
+
if (!available) {
|
|
425
|
+
return {
|
|
426
|
+
available: false,
|
|
427
|
+
canRun: false,
|
|
428
|
+
reason: `${agent} CLI not found in PATH`,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
// Check PTY requirements
|
|
432
|
+
if (config.requiresPty && !hasScriptCommand()) {
|
|
433
|
+
return {
|
|
434
|
+
available: true,
|
|
435
|
+
canRun: false,
|
|
436
|
+
reason: `${agent} requires a PTY but 'script' command is not available`,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
available: true,
|
|
441
|
+
canRun: true,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Get list of available agents with their run status
|
|
446
|
+
*/
|
|
447
|
+
export async function getAvailableAgents() {
|
|
448
|
+
const agents = ["claude", "codex", "gemini", "vibe"];
|
|
449
|
+
const available = [];
|
|
450
|
+
for (const agent of agents) {
|
|
451
|
+
if (await isAgentAvailable(agent)) {
|
|
452
|
+
available.push(agent);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return available;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Get detailed status of all agents
|
|
459
|
+
*/
|
|
460
|
+
export async function getAgentStatus() {
|
|
461
|
+
const agents = ["claude", "codex", "gemini", "vibe"];
|
|
462
|
+
const status = {};
|
|
463
|
+
for (const agent of agents) {
|
|
464
|
+
status[agent] = await canAgentRun(agent);
|
|
465
|
+
}
|
|
466
|
+
return status;
|
|
467
|
+
}
|
|
468
|
+
//# sourceMappingURL=agent-spawner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-spawner.js","sourceRoot":"","sources":["../src/agent-spawner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ChatMessage, MessageType, ReadOptions, UnclaimedFailover, WriteOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manages reading and writing to the robot chat file
|
|
4
|
+
*/
|
|
5
|
+
export declare class ChatManager {
|
|
6
|
+
private readonly chatDir;
|
|
7
|
+
private readonly chatFile;
|
|
8
|
+
constructor(projectPath: string);
|
|
9
|
+
/**
|
|
10
|
+
* Ensure the chat directory and file exist
|
|
11
|
+
*/
|
|
12
|
+
private ensureChatFile;
|
|
13
|
+
/**
|
|
14
|
+
* Parse the chat file into structured messages
|
|
15
|
+
* Includes robust error handling for malformed content
|
|
16
|
+
*/
|
|
17
|
+
parseMessages(): ChatMessage[];
|
|
18
|
+
/**
|
|
19
|
+
* Read messages with optional filtering
|
|
20
|
+
*/
|
|
21
|
+
readMessages(options?: ReadOptions): ChatMessage[];
|
|
22
|
+
/**
|
|
23
|
+
* Write a new message to the chat file (with file locking)
|
|
24
|
+
*/
|
|
25
|
+
writeMessage(options: WriteOptions): Promise<ChatMessage>;
|
|
26
|
+
/**
|
|
27
|
+
* Write a message synchronously (for backwards compatibility)
|
|
28
|
+
* Prefer writeMessage() for new code
|
|
29
|
+
*/
|
|
30
|
+
writeMessageSync(options: WriteOptions): ChatMessage;
|
|
31
|
+
/**
|
|
32
|
+
* Find unclaimed failover requests
|
|
33
|
+
* Fixed logic: now correctly matches FAILOVER_CLAIMED to specific FAILOVER_NEEDED
|
|
34
|
+
*/
|
|
35
|
+
findUnclaimedFailovers(): UnclaimedFailover[];
|
|
36
|
+
/**
|
|
37
|
+
* Claim a failover by writing a FAILOVER_CLAIMED message
|
|
38
|
+
*/
|
|
39
|
+
claimFailover(agent: string, originalAgent: string, task?: string): Promise<ChatMessage>;
|
|
40
|
+
/**
|
|
41
|
+
* Get the chat file path
|
|
42
|
+
*/
|
|
43
|
+
getChatFilePath(): string;
|
|
44
|
+
/**
|
|
45
|
+
* List all agents who have posted, with their last activity
|
|
46
|
+
*/
|
|
47
|
+
listAgents(): Array<{
|
|
48
|
+
agent: string;
|
|
49
|
+
lastSeen: string;
|
|
50
|
+
lastMessageType: MessageType;
|
|
51
|
+
messageCount: number;
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* Get messages since a specific line number (for watching/polling)
|
|
55
|
+
*/
|
|
56
|
+
getMessagesSince(sinceLineNumber: number): ChatMessage[];
|
|
57
|
+
/**
|
|
58
|
+
* Get the last line number in the chat (for watch cursor)
|
|
59
|
+
* Fixed: now counts actual lines in file instead of estimating
|
|
60
|
+
*/
|
|
61
|
+
getLastLineNumber(): number;
|
|
62
|
+
/**
|
|
63
|
+
* Archive old messages to a separate file (with file locking)
|
|
64
|
+
* @param keepRecent Number of recent messages to keep in main chat
|
|
65
|
+
* @returns Number of messages archived
|
|
66
|
+
*/
|
|
67
|
+
archiveMessages(keepRecent?: number): Promise<{
|
|
68
|
+
archived: number;
|
|
69
|
+
archiveFile: string;
|
|
70
|
+
}>;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=chat-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-manager.d.ts","sourceRoot":"","sources":["../src/chat-manager.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,WAAW,EAAE,MAAM;IAK/B;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;;OAGG;IACH,aAAa,IAAI,WAAW,EAAE;IA+E9B;;OAEG;IACH,YAAY,CAAC,OAAO,GAAE,WAAgB,GAAG,WAAW,EAAE;IA0BtD;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAoB/D;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW;IAqBpD;;;OAGG;IACH,sBAAsB,IAAI,iBAAiB,EAAE;IA2E7C;;OAEG;IACG,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,CAAC;IAavB;;OAEG;IACH,eAAe,IAAI,MAAM;IAKzB;;OAEG;IACH,UAAU,IAAI,KAAK,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,WAAW,CAAC;QAC7B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IA6BF;;OAEG;IACH,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,EAAE;IAKxD;;;OAGG;IACH,iBAAiB,IAAI,MAAM;IAe3B;;;;OAIG;IACG,eAAe,CAAC,UAAU,GAAE,MAAW,GAAG,OAAO,CAAC;QACtD,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CA+CH"}
|