doomcode 0.1.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/dist/agent/agent-manager.d.ts +57 -0
- package/dist/agent/agent-manager.d.ts.map +1 -0
- package/dist/agent/agent-manager.js +545 -0
- package/dist/agent/agent-manager.js.map +1 -0
- package/dist/agent/diff-extractor.d.ts +15 -0
- package/dist/agent/diff-extractor.d.ts.map +1 -0
- package/dist/agent/diff-extractor.js +124 -0
- package/dist/agent/diff-extractor.js.map +1 -0
- package/dist/agent/patch-tracker.d.ts +62 -0
- package/dist/agent/patch-tracker.d.ts.map +1 -0
- package/dist/agent/patch-tracker.js +258 -0
- package/dist/agent/patch-tracker.js.map +1 -0
- package/dist/agent/permission-detector.d.ts +10 -0
- package/dist/agent/permission-detector.d.ts.map +1 -0
- package/dist/agent/permission-detector.js +83 -0
- package/dist/agent/permission-detector.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/session.d.ts +54 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +367 -0
- package/dist/session.js.map +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages the Claude Code or Codex CLI process.
|
|
5
|
+
*/
|
|
6
|
+
import type { PermissionRequestMessage, PermissionResponseMessage, DiffPatchMessage, PatchDecisionMessage } from '@doomcode/protocol';
|
|
7
|
+
export type AgentStatus = 'idle' | 'running' | 'waiting_input' | 'error';
|
|
8
|
+
export interface AgentManagerOptions {
|
|
9
|
+
agent: 'claude' | 'codex';
|
|
10
|
+
workingDirectory: string;
|
|
11
|
+
onOutput: (stream: 'stdout' | 'stderr', data: string) => void;
|
|
12
|
+
onPermissionRequest: (request: PermissionRequestMessage) => void;
|
|
13
|
+
onDiff: (diff: DiffPatchMessage) => void;
|
|
14
|
+
onExit: (code: number) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class AgentManager {
|
|
17
|
+
private options;
|
|
18
|
+
private ptyProcess;
|
|
19
|
+
private process;
|
|
20
|
+
private status;
|
|
21
|
+
private permissionDetector;
|
|
22
|
+
private diffExtractor;
|
|
23
|
+
private debugPty;
|
|
24
|
+
private enterMode;
|
|
25
|
+
private typewriteDelayMs;
|
|
26
|
+
private typewriteOverride;
|
|
27
|
+
private pendingPermissions;
|
|
28
|
+
private pendingPatches;
|
|
29
|
+
private outputBuffer;
|
|
30
|
+
constructor(options: AgentManagerOptions);
|
|
31
|
+
private logDebug;
|
|
32
|
+
private normalizeEnterMode;
|
|
33
|
+
private getEnterSuffix;
|
|
34
|
+
private sendEnter;
|
|
35
|
+
private typewrite;
|
|
36
|
+
/**
|
|
37
|
+
* Force submit the current input using multiple methods:
|
|
38
|
+
* - Ctrl+M (0x0d) = Carriage Return
|
|
39
|
+
* - Ctrl+J (0x0a) = Line Feed / Newline
|
|
40
|
+
* This should work regardless of terminal mode.
|
|
41
|
+
*/
|
|
42
|
+
private forceSubmit;
|
|
43
|
+
private writeToAgent;
|
|
44
|
+
private sendLine;
|
|
45
|
+
private buildPtyEnv;
|
|
46
|
+
private spawnPty;
|
|
47
|
+
private spawnPythonPtyBridge;
|
|
48
|
+
private findClaudePath;
|
|
49
|
+
start(initialPrompt?: string): Promise<void>;
|
|
50
|
+
private handleOutput;
|
|
51
|
+
handlePermissionResponse(response: PermissionResponseMessage): void;
|
|
52
|
+
handlePatchDecision(decision: PatchDecisionMessage): void;
|
|
53
|
+
sendPrompt(prompt: string): void;
|
|
54
|
+
getStatus(): AgentStatus;
|
|
55
|
+
stop(): void;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=agent-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-manager.d.ts","sourceRoot":"","sources":["../../src/agent/agent-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAI5B,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,eAAe,GAAG,OAAO,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,mBAAmB,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACjE,MAAM,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,OAAO,CAA+C;IAC9D,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,SAAS,CAA4D;IAC7E,OAAO,CAAC,gBAAgB,CAA0D;IAClF,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,kBAAkB,CACd;IACZ,OAAO,CAAC,cAAc,CAAoE;IAC1F,OAAO,CAAC,YAAY,CAAM;gBAEd,OAAO,EAAE,mBAAmB;IAMxC,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,SAAS;IA+BjB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,QAAQ;IAkBhB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,oBAAoB;IA6J5B,OAAO,CAAC,cAAc;IA+BhB,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0HlD,OAAO,CAAC,YAAY;IAwCpB,wBAAwB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI;IAQnE,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAQzD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAsBhC,SAAS,IAAI,WAAW;IAIxB,IAAI,IAAI,IAAI;CAoBb"}
|
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages the Claude Code or Codex CLI process.
|
|
5
|
+
*/
|
|
6
|
+
import { execSync, spawn } from 'child_process';
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as pty from 'node-pty';
|
|
11
|
+
import { PermissionDetector } from './permission-detector.js';
|
|
12
|
+
import { DiffExtractor } from './diff-extractor.js';
|
|
13
|
+
export class AgentManager {
|
|
14
|
+
options;
|
|
15
|
+
ptyProcess = null;
|
|
16
|
+
process = null;
|
|
17
|
+
status = 'idle';
|
|
18
|
+
permissionDetector;
|
|
19
|
+
diffExtractor;
|
|
20
|
+
debugPty = process.env.DOOMCODE_DEBUG_PTY === '1';
|
|
21
|
+
enterMode = this.normalizeEnterMode(process.env.DOOMCODE_ENTER_MODE);
|
|
22
|
+
typewriteDelayMs = Number(process.env.DOOMCODE_TYPEWRITE_DELAY_MS ?? '5');
|
|
23
|
+
typewriteOverride = process.env.DOOMCODE_TYPEWRITE;
|
|
24
|
+
pendingPermissions = new Map();
|
|
25
|
+
pendingPatches = new Map();
|
|
26
|
+
outputBuffer = '';
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.permissionDetector = new PermissionDetector();
|
|
30
|
+
this.diffExtractor = new DiffExtractor();
|
|
31
|
+
}
|
|
32
|
+
logDebug(message) {
|
|
33
|
+
if (this.debugPty) {
|
|
34
|
+
console.log(message);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
normalizeEnterMode(mode) {
|
|
38
|
+
const value = (mode ?? 'cr').toLowerCase();
|
|
39
|
+
if (value === 'lf' || value === 'crlf')
|
|
40
|
+
return value;
|
|
41
|
+
return 'cr';
|
|
42
|
+
}
|
|
43
|
+
getEnterSuffix() {
|
|
44
|
+
switch (this.enterMode) {
|
|
45
|
+
case 'lf':
|
|
46
|
+
return '\n';
|
|
47
|
+
case 'crlf':
|
|
48
|
+
return '\r\n';
|
|
49
|
+
case 'cr':
|
|
50
|
+
default:
|
|
51
|
+
return '\r';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
sendEnter() {
|
|
55
|
+
const suffix = this.getEnterSuffix();
|
|
56
|
+
this.logDebug(`>>> [AGENT] sendEnter: ${JSON.stringify(suffix)}`);
|
|
57
|
+
this.writeToAgent(suffix);
|
|
58
|
+
}
|
|
59
|
+
typewrite(text) {
|
|
60
|
+
const chars = Array.from(text);
|
|
61
|
+
const delay = Math.max(0, this.typewriteDelayMs);
|
|
62
|
+
// For python bridge, send Escape first to ensure Claude is ready for input
|
|
63
|
+
const isPythonBridge = !!this.process && !this.ptyProcess;
|
|
64
|
+
if (isPythonBridge) {
|
|
65
|
+
this.logDebug('>>> [AGENT] Sending Escape (0x1b) to prepare input');
|
|
66
|
+
this.writeToAgent('\x1b');
|
|
67
|
+
}
|
|
68
|
+
const startDelay = isPythonBridge ? 50 : 0;
|
|
69
|
+
if (chars.length === 0) {
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
this.forceSubmit();
|
|
72
|
+
}, startDelay);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
chars.forEach((char, index) => {
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
this.writeToAgent(char);
|
|
78
|
+
}, startDelay + delay * index);
|
|
79
|
+
});
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
this.forceSubmit();
|
|
82
|
+
}, startDelay + delay * chars.length + 20);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Force submit the current input using multiple methods:
|
|
86
|
+
* - Ctrl+M (0x0d) = Carriage Return
|
|
87
|
+
* - Ctrl+J (0x0a) = Line Feed / Newline
|
|
88
|
+
* This should work regardless of terminal mode.
|
|
89
|
+
*/
|
|
90
|
+
forceSubmit() {
|
|
91
|
+
this.logDebug('>>> [AGENT] forceSubmit: sending Ctrl+M (0x0d) then Ctrl+J (0x0a)');
|
|
92
|
+
// Send CR (Ctrl+M)
|
|
93
|
+
this.writeToAgent('\x0d');
|
|
94
|
+
// Small delay, then send LF (Ctrl+J)
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
this.writeToAgent('\x0a');
|
|
97
|
+
}, 10);
|
|
98
|
+
}
|
|
99
|
+
writeToAgent(data) {
|
|
100
|
+
const bytes = Buffer.from(data);
|
|
101
|
+
this.logDebug(`>>> [AGENT] writeToAgent: ${bytes.length} bytes, hex: ${bytes.toString('hex')}`);
|
|
102
|
+
try {
|
|
103
|
+
if (this.ptyProcess) {
|
|
104
|
+
this.logDebug('>>> [AGENT] Writing to node-pty...');
|
|
105
|
+
this.ptyProcess.write(data);
|
|
106
|
+
this.logDebug('>>> [AGENT] node-pty write complete');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (this.process?.stdin) {
|
|
110
|
+
this.logDebug('>>> [AGENT] Writing to python bridge stdin...');
|
|
111
|
+
const written = this.process.stdin.write(data);
|
|
112
|
+
this.logDebug(`>>> [AGENT] stdin.write returned: ${written}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
console.error('>>> [AGENT] Failed to write to agent:', e);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
sendLine(line) {
|
|
120
|
+
this.logDebug(`>>> [AGENT] sendLine: "${line}"`);
|
|
121
|
+
if (this.ptyProcess) {
|
|
122
|
+
const suffix = this.getEnterSuffix();
|
|
123
|
+
this.logDebug(`>>> [AGENT] Using node-pty path, appending ${JSON.stringify(suffix)}`);
|
|
124
|
+
this.writeToAgent(line);
|
|
125
|
+
setTimeout(() => this.sendEnter(), 5);
|
|
126
|
+
}
|
|
127
|
+
else if (this.process) {
|
|
128
|
+
// Python PTY bridge: use forceSubmit for reliable Enter
|
|
129
|
+
this.logDebug('>>> [AGENT] Using python-bridge path with forceSubmit');
|
|
130
|
+
this.writeToAgent(line);
|
|
131
|
+
setTimeout(() => this.forceSubmit(), 10);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.log('>>> [AGENT] ERROR: No process to write to!');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
buildPtyEnv(fullPath) {
|
|
138
|
+
// node-pty expects env values to be strings (no undefined).
|
|
139
|
+
const baseEnv = Object.fromEntries(Object.entries(process.env).filter(([, v]) => typeof v === 'string'));
|
|
140
|
+
return {
|
|
141
|
+
...baseEnv,
|
|
142
|
+
PATH: fullPath,
|
|
143
|
+
TERM: 'xterm-256color',
|
|
144
|
+
FORCE_COLOR: '1',
|
|
145
|
+
// Tell Claude we are NOT a CI environment (some CLIs change behavior under CI)
|
|
146
|
+
CI: 'false',
|
|
147
|
+
CLAUDE_CODE_ENTRYPOINT: 'doomcode',
|
|
148
|
+
// Ensure shell is set (some CLIs assume it)
|
|
149
|
+
SHELL: baseEnv.SHELL || '/bin/zsh',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
spawnPty(command, args, fullPath) {
|
|
153
|
+
const env = this.buildPtyEnv(fullPath);
|
|
154
|
+
this.ptyProcess = pty.spawn(command, args, {
|
|
155
|
+
name: 'xterm-256color',
|
|
156
|
+
cols: 120,
|
|
157
|
+
rows: 40,
|
|
158
|
+
cwd: this.options.workingDirectory,
|
|
159
|
+
env,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
spawnPythonPtyBridge(command, args, fullPath) {
|
|
163
|
+
// node-pty is failing on some macOS setups (posix_spawnp failed). We still need a
|
|
164
|
+
// real PTY *and* programmatic stdin/stdout so prompts can come from the phone.
|
|
165
|
+
//
|
|
166
|
+
// This Python bridge uses only the standard library to:
|
|
167
|
+
// - allocate a PTY
|
|
168
|
+
// - spawn the agent with stdin/stdout/stderr attached to the PTY slave
|
|
169
|
+
// - forward PTY master output to stdout
|
|
170
|
+
// - forward our stdin to the PTY master
|
|
171
|
+
//
|
|
172
|
+
// Node then talks to the bridge over pipes (works in any environment).
|
|
173
|
+
const env = this.buildPtyEnv(fullPath);
|
|
174
|
+
// Claude appears to accept LF more reliably under the python bridge; default to LF unless overridden.
|
|
175
|
+
if (!process.env.DOOMCODE_ENTER_MODE) {
|
|
176
|
+
this.enterMode = 'lf';
|
|
177
|
+
env.DOOMCODE_ENTER_MODE = 'lf';
|
|
178
|
+
}
|
|
179
|
+
// Use explicit byte values to avoid any JS/Python escaping issues
|
|
180
|
+
const bridgeSource = `#!/usr/bin/env python3
|
|
181
|
+
import os, pty, sys, selectors, subprocess, termios
|
|
182
|
+
|
|
183
|
+
DEBUG = os.environ.get("DOOMCODE_DEBUG_PTY") == "1"
|
|
184
|
+
ENTER_MODE = os.environ.get("DOOMCODE_ENTER_MODE", "cr").lower()
|
|
185
|
+
|
|
186
|
+
def log(msg):
|
|
187
|
+
if not DEBUG:
|
|
188
|
+
return
|
|
189
|
+
# Write to stderr with flush - use explicit newline byte
|
|
190
|
+
os.write(2, ("[PTY-BRIDGE] " + str(msg) + chr(10)).encode())
|
|
191
|
+
|
|
192
|
+
def main():
|
|
193
|
+
log("Python PTY bridge starting...")
|
|
194
|
+
|
|
195
|
+
if len(sys.argv) < 2:
|
|
196
|
+
log("ERROR: No command provided")
|
|
197
|
+
return 2
|
|
198
|
+
|
|
199
|
+
cmd = sys.argv[1:]
|
|
200
|
+
log(f"Command: {cmd}")
|
|
201
|
+
|
|
202
|
+
# Fork a PTY with a proper controlling terminal for the child.
|
|
203
|
+
pid, master_fd = pty.fork()
|
|
204
|
+
if pid == 0:
|
|
205
|
+
# Child process: configure line discipline on stdin (the PTY slave)
|
|
206
|
+
try:
|
|
207
|
+
attrs = termios.tcgetattr(0)
|
|
208
|
+
if ENTER_MODE == "cr":
|
|
209
|
+
# Map CR to NL in canonical input processing
|
|
210
|
+
attrs[0] |= termios.ICRNL
|
|
211
|
+
attrs[0] &= ~termios.INLCR
|
|
212
|
+
attrs[0] &= ~termios.IGNCR
|
|
213
|
+
else:
|
|
214
|
+
# Don't translate CR/LF automatically; app receives exact bytes
|
|
215
|
+
attrs[0] &= ~termios.ICRNL
|
|
216
|
+
attrs[0] &= ~termios.INLCR
|
|
217
|
+
attrs[0] &= ~termios.IGNCR
|
|
218
|
+
termios.tcsetattr(0, termios.TCSANOW, attrs)
|
|
219
|
+
except Exception:
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
os.execvpe(cmd[0], cmd, os.environ.copy())
|
|
223
|
+
os._exit(1)
|
|
224
|
+
|
|
225
|
+
log(f"PTY forked: master={master_fd}, child_pid={pid}, enter_mode={ENTER_MODE}")
|
|
226
|
+
|
|
227
|
+
sel = selectors.DefaultSelector()
|
|
228
|
+
sel.register(master_fd, selectors.EVENT_READ, "pty")
|
|
229
|
+
sel.register(0, selectors.EVENT_READ, "stdin") # fd 0 = stdin
|
|
230
|
+
|
|
231
|
+
try:
|
|
232
|
+
while True:
|
|
233
|
+
child_exited = False
|
|
234
|
+
try:
|
|
235
|
+
finished_pid, status = os.waitpid(pid, os.WNOHANG)
|
|
236
|
+
if finished_pid != 0:
|
|
237
|
+
child_exited = True
|
|
238
|
+
if os.WIFEXITED(status):
|
|
239
|
+
log(f"Child exited with code {os.WEXITSTATUS(status)}")
|
|
240
|
+
elif os.WIFSIGNALED(status):
|
|
241
|
+
log(f"Child exited with signal {os.WTERMSIG(status)}")
|
|
242
|
+
except ChildProcessError:
|
|
243
|
+
child_exited = True
|
|
244
|
+
|
|
245
|
+
if child_exited:
|
|
246
|
+
# Drain remaining output
|
|
247
|
+
try:
|
|
248
|
+
data = os.read(master_fd, 65536)
|
|
249
|
+
if data:
|
|
250
|
+
os.write(1, data)
|
|
251
|
+
except OSError:
|
|
252
|
+
pass
|
|
253
|
+
break
|
|
254
|
+
|
|
255
|
+
for key, _ in sel.select(timeout=0.1):
|
|
256
|
+
if key.data == "pty":
|
|
257
|
+
try:
|
|
258
|
+
data = os.read(master_fd, 65536)
|
|
259
|
+
except OSError:
|
|
260
|
+
data = b""
|
|
261
|
+
if data:
|
|
262
|
+
os.write(1, data) # Write to stdout (fd 1)
|
|
263
|
+
else:
|
|
264
|
+
# Read from stdin (fd 0)
|
|
265
|
+
try:
|
|
266
|
+
data = os.read(0, 65536)
|
|
267
|
+
except OSError as e:
|
|
268
|
+
log(f"stdin read error: {e}")
|
|
269
|
+
data = b""
|
|
270
|
+
|
|
271
|
+
if not data:
|
|
272
|
+
log("stdin closed, exiting")
|
|
273
|
+
try:
|
|
274
|
+
os.close(master_fd)
|
|
275
|
+
except OSError:
|
|
276
|
+
pass
|
|
277
|
+
return 0
|
|
278
|
+
|
|
279
|
+
log(f"RECV {len(data)} bytes: {data!r}")
|
|
280
|
+
|
|
281
|
+
# Pass-through bytes as-is. We control line endings on the Node side.
|
|
282
|
+
out = data
|
|
283
|
+
|
|
284
|
+
log(f"SEND {len(out)} bytes: {out!r}")
|
|
285
|
+
|
|
286
|
+
try:
|
|
287
|
+
os.write(master_fd, out)
|
|
288
|
+
except OSError as e:
|
|
289
|
+
log(f"PTY write error: {e}")
|
|
290
|
+
except Exception as e:
|
|
291
|
+
log(f"Main loop error: {e}")
|
|
292
|
+
finally:
|
|
293
|
+
try:
|
|
294
|
+
sel.close()
|
|
295
|
+
except Exception:
|
|
296
|
+
pass
|
|
297
|
+
try:
|
|
298
|
+
os.close(master_fd)
|
|
299
|
+
except Exception:
|
|
300
|
+
pass
|
|
301
|
+
|
|
302
|
+
return 0
|
|
303
|
+
|
|
304
|
+
if __name__ == "__main__":
|
|
305
|
+
raise SystemExit(main())
|
|
306
|
+
`;
|
|
307
|
+
const tmpPath = path.join(os.tmpdir(), `doomcode-pty-bridge-${process.pid}.py`);
|
|
308
|
+
fs.writeFileSync(tmpPath, bridgeSource, { encoding: 'utf8' });
|
|
309
|
+
this.process = spawn('python3', ['-u', tmpPath, command, ...args], {
|
|
310
|
+
cwd: this.options.workingDirectory,
|
|
311
|
+
env,
|
|
312
|
+
stdio: 'pipe',
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
findClaudePath() {
|
|
316
|
+
// Try to find claude in common locations
|
|
317
|
+
const possiblePaths = [
|
|
318
|
+
'/opt/homebrew/bin/claude',
|
|
319
|
+
'/usr/local/bin/claude',
|
|
320
|
+
path.join(os.homedir(), '.npm-global/bin/claude'),
|
|
321
|
+
path.join(os.homedir(), '.local/bin/claude'),
|
|
322
|
+
];
|
|
323
|
+
for (const p of possiblePaths) {
|
|
324
|
+
if (fs.existsSync(p)) {
|
|
325
|
+
console.log(`Found claude at: ${p}`);
|
|
326
|
+
return p;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Try to find via 'which'
|
|
330
|
+
try {
|
|
331
|
+
const result = execSync('which claude', { encoding: 'utf-8' }).trim();
|
|
332
|
+
if (result) {
|
|
333
|
+
console.log(`Found claude via which: ${result}`);
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// which failed
|
|
339
|
+
}
|
|
340
|
+
console.error('Could not find claude CLI. Tried:', possiblePaths.join(', '));
|
|
341
|
+
throw new Error('Claude CLI not found. Please ensure it is installed and in PATH.');
|
|
342
|
+
}
|
|
343
|
+
async start(initialPrompt) {
|
|
344
|
+
let command;
|
|
345
|
+
const args = [];
|
|
346
|
+
try {
|
|
347
|
+
if (this.options.agent === 'claude') {
|
|
348
|
+
command = this.findClaudePath();
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
command = '/usr/local/bin/codex';
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
console.error('Failed to find agent:', error);
|
|
356
|
+
this.status = 'error';
|
|
357
|
+
this.options.onOutput('stderr', `Error: ${error}\n`);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
// For Claude, we need to use interactive mode
|
|
361
|
+
// Use --dangerously-skip-permissions to avoid TTY requirement for permissions
|
|
362
|
+
if (this.options.agent === 'claude') {
|
|
363
|
+
// Don't add any special flags - let it run in default interactive mode
|
|
364
|
+
// The user will send prompts via stdin
|
|
365
|
+
}
|
|
366
|
+
if (initialPrompt) {
|
|
367
|
+
// Use chat mode with initial prompt
|
|
368
|
+
args.push(initialPrompt);
|
|
369
|
+
}
|
|
370
|
+
console.log(`Starting ${this.options.agent} agent...`);
|
|
371
|
+
console.log(`Command: ${command} ${args.join(' ')}`);
|
|
372
|
+
console.log(`Working directory: ${this.options.workingDirectory}`);
|
|
373
|
+
this.logDebug(`>>> [AGENT] Enter mode: ${this.enterMode}`);
|
|
374
|
+
this.logDebug(`>>> [AGENT] Typewrite override: ${this.typewriteOverride ?? 'auto'} (delay=${this.typewriteDelayMs}ms)`);
|
|
375
|
+
// Ensure PATH includes common locations for CLI tools
|
|
376
|
+
const envPath = process.env.PATH || '';
|
|
377
|
+
const additionalPaths = ['/opt/homebrew/bin', '/usr/local/bin', '/usr/bin'];
|
|
378
|
+
const fullPath = [...new Set([...additionalPaths, ...envPath.split(':')])].join(':');
|
|
379
|
+
try {
|
|
380
|
+
// Run the agent inside a real pseudo-terminal (PTY). Many interactive CLIs
|
|
381
|
+
// (including Claude) behave differently without a TTY and may produce no output.
|
|
382
|
+
try {
|
|
383
|
+
this.spawnPty(command, args, fullPath);
|
|
384
|
+
const ptyProc = this.ptyProcess;
|
|
385
|
+
if (!ptyProc) {
|
|
386
|
+
throw new Error('Failed to start PTY process');
|
|
387
|
+
}
|
|
388
|
+
console.log(`Agent started with PID: ${ptyProc.pid}`);
|
|
389
|
+
this.status = 'running';
|
|
390
|
+
// PTY output is a single stream; treat as stdout for the protocol.
|
|
391
|
+
ptyProc.onData((text) => {
|
|
392
|
+
console.log('[Agent pty]:', text.substring(0, 200));
|
|
393
|
+
this.handleOutput('stdout', text);
|
|
394
|
+
});
|
|
395
|
+
ptyProc.onExit(({ exitCode, signal }) => {
|
|
396
|
+
console.log(`Agent exited with code ${exitCode}, signal ${signal}`);
|
|
397
|
+
this.status = 'idle';
|
|
398
|
+
this.options.onExit(exitCode ?? 0);
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
catch (e) {
|
|
402
|
+
// node-pty is failing on some macOS setups with `posix_spawnp failed`.
|
|
403
|
+
// Fall back to a python-based PTY bridge (still supports programmatic stdin/stdout).
|
|
404
|
+
console.warn('PTY spawn failed, falling back to python PTY bridge:', e);
|
|
405
|
+
this.ptyProcess = null;
|
|
406
|
+
this.spawnPythonPtyBridge(command, args, fullPath);
|
|
407
|
+
if (!this.process?.pid) {
|
|
408
|
+
throw new Error('Failed to start agent via python PTY bridge');
|
|
409
|
+
}
|
|
410
|
+
console.log(`Agent started (python PTY bridge) with PID: ${this.process.pid}`);
|
|
411
|
+
this.status = 'running';
|
|
412
|
+
this.process.stdout.on('data', (buf) => this.handleOutput('stdout', buf.toString()));
|
|
413
|
+
// Python bridge stderr contains debug info - print to console only when enabled
|
|
414
|
+
this.process.stderr.on('data', (buf) => {
|
|
415
|
+
if (!this.debugPty)
|
|
416
|
+
return;
|
|
417
|
+
const text = buf.toString().trim();
|
|
418
|
+
if (text) {
|
|
419
|
+
console.log(`>>> [PTY-BRIDGE-STDERR] ${text}`);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
this.process.on('exit', (code, signal) => {
|
|
423
|
+
console.log(`Agent exited with code ${code}, signal ${signal}`);
|
|
424
|
+
this.status = 'idle';
|
|
425
|
+
this.options.onExit(code ?? 0);
|
|
426
|
+
});
|
|
427
|
+
this.process.on('error', (err) => {
|
|
428
|
+
console.error('Process spawn error:', err.message);
|
|
429
|
+
this.status = 'error';
|
|
430
|
+
this.options.onOutput('stderr', `Process error: ${err.message}\n`);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
// Send a small test to see if process is responsive
|
|
434
|
+
setTimeout(() => {
|
|
435
|
+
if ((this.ptyProcess || this.process) && this.status === 'running') {
|
|
436
|
+
console.log('Agent appears to be running. Waiting for user input from mobile.');
|
|
437
|
+
this.options.onOutput('stdout', 'DoomCode: Agent ready. Send a prompt from your mobile device.\n');
|
|
438
|
+
}
|
|
439
|
+
}, 1000);
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
console.error('Failed to spawn agent:', error);
|
|
443
|
+
this.status = 'error';
|
|
444
|
+
const errMsg = error instanceof Error
|
|
445
|
+
? `${error.message}\n${error.stack ?? ''}`
|
|
446
|
+
: String(error);
|
|
447
|
+
this.options.onOutput('stderr', `Failed to start agent: ${error}\n`);
|
|
448
|
+
this.options.onOutput('stderr', `Details: ${errMsg}\n`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
handleOutput(stream, data) {
|
|
452
|
+
// Buffer output for pattern detection
|
|
453
|
+
this.outputBuffer += data;
|
|
454
|
+
// Check for permission requests
|
|
455
|
+
const permissionRequest = this.permissionDetector.detect(this.outputBuffer);
|
|
456
|
+
if (permissionRequest) {
|
|
457
|
+
this.status = 'waiting_input';
|
|
458
|
+
this.options.onPermissionRequest(permissionRequest);
|
|
459
|
+
// Store pending permission handler
|
|
460
|
+
this.pendingPermissions.set(permissionRequest.requestId, (response) => {
|
|
461
|
+
if (response.decision === 'approve' || response.decision === 'approve_always') {
|
|
462
|
+
this.sendLine('y');
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
this.sendLine('n');
|
|
466
|
+
}
|
|
467
|
+
this.status = 'running';
|
|
468
|
+
});
|
|
469
|
+
// Clear buffer after detection
|
|
470
|
+
this.outputBuffer = '';
|
|
471
|
+
}
|
|
472
|
+
// Check for diff output
|
|
473
|
+
const diff = this.diffExtractor.extract(this.outputBuffer);
|
|
474
|
+
if (diff) {
|
|
475
|
+
this.options.onDiff(diff);
|
|
476
|
+
this.outputBuffer = '';
|
|
477
|
+
}
|
|
478
|
+
// Keep buffer from growing too large
|
|
479
|
+
if (this.outputBuffer.length > 10000) {
|
|
480
|
+
this.outputBuffer = this.outputBuffer.slice(-5000);
|
|
481
|
+
}
|
|
482
|
+
// Forward output
|
|
483
|
+
this.options.onOutput(stream, data);
|
|
484
|
+
}
|
|
485
|
+
handlePermissionResponse(response) {
|
|
486
|
+
const handler = this.pendingPermissions.get(response.requestId);
|
|
487
|
+
if (handler) {
|
|
488
|
+
handler(response);
|
|
489
|
+
this.pendingPermissions.delete(response.requestId);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
handlePatchDecision(decision) {
|
|
493
|
+
const handler = this.pendingPatches.get(decision.patchId);
|
|
494
|
+
if (handler) {
|
|
495
|
+
handler(decision);
|
|
496
|
+
this.pendingPatches.delete(decision.patchId);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
sendPrompt(prompt) {
|
|
500
|
+
this.logDebug(`>>> [AGENT] sendPrompt called with: "${prompt}"`);
|
|
501
|
+
if (!this.ptyProcess && !this.process) {
|
|
502
|
+
console.error('>>> [AGENT] ERROR: Cannot send prompt: no process running');
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
const mode = this.ptyProcess ? 'node-pty' : 'python-bridge';
|
|
506
|
+
this.logDebug(`>>> [AGENT] Sending via ${mode}, prompt length: ${prompt.length}`);
|
|
507
|
+
try {
|
|
508
|
+
const useTypewrite = this.typewriteOverride === '1' ? true : this.typewriteOverride === '0' ? false : !!this.process;
|
|
509
|
+
if (useTypewrite)
|
|
510
|
+
this.typewrite(prompt);
|
|
511
|
+
else
|
|
512
|
+
this.sendLine(prompt);
|
|
513
|
+
this.logDebug('>>> [AGENT] sendLine() completed');
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
console.error('>>> [AGENT] Failed to write to PTY:', error);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
getStatus() {
|
|
520
|
+
return this.status;
|
|
521
|
+
}
|
|
522
|
+
stop() {
|
|
523
|
+
if (this.ptyProcess) {
|
|
524
|
+
try {
|
|
525
|
+
this.ptyProcess.kill();
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
// ignore
|
|
529
|
+
}
|
|
530
|
+
this.ptyProcess = null;
|
|
531
|
+
this.status = 'idle';
|
|
532
|
+
}
|
|
533
|
+
if (this.process) {
|
|
534
|
+
try {
|
|
535
|
+
this.process.kill();
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
// ignore
|
|
539
|
+
}
|
|
540
|
+
this.process = null;
|
|
541
|
+
this.status = 'idle';
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=agent-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-manager.js","sourceRoot":"","sources":["../../src/agent/agent-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Extractor
|
|
3
|
+
*
|
|
4
|
+
* Extracts git diffs from agent output.
|
|
5
|
+
*/
|
|
6
|
+
import type { DiffPatchMessage } from '@doomcode/protocol';
|
|
7
|
+
export declare class DiffExtractor {
|
|
8
|
+
private diffBuffer;
|
|
9
|
+
private inDiff;
|
|
10
|
+
extract(output: string): DiffPatchMessage | null;
|
|
11
|
+
private isEndOfDiff;
|
|
12
|
+
private generateSummary;
|
|
13
|
+
private estimateRisk;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=diff-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-extractor.d.ts","sourceRoot":"","sources":["../../src/agent/diff-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,oBAAoB,CAAC;AAIhF,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAoDhD,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,YAAY;CAgCrB"}
|