agent-relay 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/CHANGELOG.md +11 -0
- package/LICENSE +22 -0
- package/PROTOCOL.md +319 -0
- package/README.md +791 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1591 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/daemon/connection.d.ts +60 -0
- package/dist/daemon/connection.d.ts.map +1 -0
- package/dist/daemon/connection.js +245 -0
- package/dist/daemon/connection.js.map +1 -0
- package/dist/daemon/index.d.ts +4 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +4 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/router.d.ts +72 -0
- package/dist/daemon/router.d.ts.map +1 -0
- package/dist/daemon/router.js +183 -0
- package/dist/daemon/router.js.map +1 -0
- package/dist/daemon/server.d.ts +52 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +186 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/dashboard/public/index.html +690 -0
- package/dist/dashboard/server.d.ts +2 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +220 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/games/index.d.ts +2 -0
- package/dist/games/index.d.ts.map +1 -0
- package/dist/games/index.js +2 -0
- package/dist/games/index.js.map +1 -0
- package/dist/games/tictactoe.d.ts +24 -0
- package/dist/games/tictactoe.d.ts.map +1 -0
- package/dist/games/tictactoe.js +160 -0
- package/dist/games/tictactoe.js.map +1 -0
- package/dist/hooks/inbox-check/hook.d.ts +28 -0
- package/dist/hooks/inbox-check/hook.d.ts.map +1 -0
- package/dist/hooks/inbox-check/hook.js +97 -0
- package/dist/hooks/inbox-check/hook.js.map +1 -0
- package/dist/hooks/inbox-check/index.d.ts +8 -0
- package/dist/hooks/inbox-check/index.d.ts.map +1 -0
- package/dist/hooks/inbox-check/index.js +8 -0
- package/dist/hooks/inbox-check/index.js.map +1 -0
- package/dist/hooks/inbox-check/types.d.ts +31 -0
- package/dist/hooks/inbox-check/types.d.ts.map +1 -0
- package/dist/hooks/inbox-check/types.js +5 -0
- package/dist/hooks/inbox-check/types.js.map +1 -0
- package/dist/hooks/inbox-check/utils.d.ts +44 -0
- package/dist/hooks/inbox-check/utils.d.ts.map +1 -0
- package/dist/hooks/inbox-check/utils.js +107 -0
- package/dist/hooks/inbox-check/utils.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/framing.d.ts +32 -0
- package/dist/protocol/framing.d.ts.map +1 -0
- package/dist/protocol/framing.js +71 -0
- package/dist/protocol/framing.js.map +1 -0
- package/dist/protocol/index.d.ts +3 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +3 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/types.d.ts +104 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +6 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/state/agent-state.d.ts +40 -0
- package/dist/state/agent-state.d.ts.map +1 -0
- package/dist/state/agent-state.js +120 -0
- package/dist/state/agent-state.js.map +1 -0
- package/dist/storage/adapter.d.ts +29 -0
- package/dist/storage/adapter.d.ts.map +1 -0
- package/dist/storage/adapter.js +2 -0
- package/dist/storage/adapter.js.map +1 -0
- package/dist/storage/sqlite-adapter.d.ts +15 -0
- package/dist/storage/sqlite-adapter.d.ts.map +1 -0
- package/dist/storage/sqlite-adapter.js +116 -0
- package/dist/storage/sqlite-adapter.js.map +1 -0
- package/dist/supervisor/inbox.d.ts +38 -0
- package/dist/supervisor/inbox.d.ts.map +1 -0
- package/dist/supervisor/inbox.js +162 -0
- package/dist/supervisor/inbox.js.map +1 -0
- package/dist/supervisor/index.d.ts +10 -0
- package/dist/supervisor/index.d.ts.map +1 -0
- package/dist/supervisor/index.js +10 -0
- package/dist/supervisor/index.js.map +1 -0
- package/dist/supervisor/spawner.d.ts +54 -0
- package/dist/supervisor/spawner.d.ts.map +1 -0
- package/dist/supervisor/spawner.js +282 -0
- package/dist/supervisor/spawner.js.map +1 -0
- package/dist/supervisor/state.d.ts +132 -0
- package/dist/supervisor/state.d.ts.map +1 -0
- package/dist/supervisor/state.js +465 -0
- package/dist/supervisor/state.js.map +1 -0
- package/dist/supervisor/supervisor.d.ts +67 -0
- package/dist/supervisor/supervisor.d.ts.map +1 -0
- package/dist/supervisor/supervisor.js +263 -0
- package/dist/supervisor/supervisor.js.map +1 -0
- package/dist/supervisor/types.d.ts +139 -0
- package/dist/supervisor/types.d.ts.map +1 -0
- package/dist/supervisor/types.js +12 -0
- package/dist/supervisor/types.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/name-generator.d.ts +17 -0
- package/dist/utils/name-generator.d.ts.map +1 -0
- package/dist/utils/name-generator.js +52 -0
- package/dist/utils/name-generator.js.map +1 -0
- package/dist/webhook/spawner.d.ts +79 -0
- package/dist/webhook/spawner.d.ts.map +1 -0
- package/dist/webhook/spawner.js +288 -0
- package/dist/webhook/spawner.js.map +1 -0
- package/dist/wrapper/client.d.ts +72 -0
- package/dist/wrapper/client.d.ts.map +1 -0
- package/dist/wrapper/client.js +306 -0
- package/dist/wrapper/client.js.map +1 -0
- package/dist/wrapper/inbox.d.ts +37 -0
- package/dist/wrapper/inbox.d.ts.map +1 -0
- package/dist/wrapper/inbox.js +73 -0
- package/dist/wrapper/inbox.js.map +1 -0
- package/dist/wrapper/index.d.ts +4 -0
- package/dist/wrapper/index.d.ts.map +1 -0
- package/dist/wrapper/index.js +7 -0
- package/dist/wrapper/index.js.map +1 -0
- package/dist/wrapper/parser.d.ts +94 -0
- package/dist/wrapper/parser.d.ts.map +1 -0
- package/dist/wrapper/parser.js +360 -0
- package/dist/wrapper/parser.js.map +1 -0
- package/dist/wrapper/pty-wrapper.d.ts +125 -0
- package/dist/wrapper/pty-wrapper.d.ts.map +1 -0
- package/dist/wrapper/pty-wrapper.js +494 -0
- package/dist/wrapper/pty-wrapper.js.map +1 -0
- package/dist/wrapper/tmux-wrapper.d.ts +131 -0
- package/dist/wrapper/tmux-wrapper.d.ts.map +1 -0
- package/dist/wrapper/tmux-wrapper.js +427 -0
- package/dist/wrapper/tmux-wrapper.js.map +1 -0
- package/install.sh +69 -0
- package/package.json +82 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PTY Wrapper
|
|
3
|
+
* Wraps an agent CLI command in a pseudo-terminal and intercepts
|
|
4
|
+
* relay commands from output while injecting incoming messages.
|
|
5
|
+
*/
|
|
6
|
+
export interface WrapperConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
command: string;
|
|
9
|
+
args?: string[];
|
|
10
|
+
socketPath?: string;
|
|
11
|
+
cols?: number;
|
|
12
|
+
rows?: number;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
env?: Record<string, string>;
|
|
15
|
+
/** Raw mode - bypass all parsing for terminal-heavy CLIs */
|
|
16
|
+
raw?: boolean;
|
|
17
|
+
/** Use tmux for message injection (more reliable) */
|
|
18
|
+
useTmux?: boolean;
|
|
19
|
+
/** Use osascript for OS-level keyboard simulation (macOS only) */
|
|
20
|
+
useOsascript?: boolean;
|
|
21
|
+
/** Use file-based inbox instead of stdin injection */
|
|
22
|
+
useInbox?: boolean;
|
|
23
|
+
/** Custom inbox directory */
|
|
24
|
+
inboxDir?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare class PtyWrapper {
|
|
27
|
+
private config;
|
|
28
|
+
private ptyProcess?;
|
|
29
|
+
private client;
|
|
30
|
+
private parser;
|
|
31
|
+
private inbox?;
|
|
32
|
+
private running;
|
|
33
|
+
private lastOutputTime;
|
|
34
|
+
private messageQueue;
|
|
35
|
+
private processingMessage;
|
|
36
|
+
private recentlySentMessages;
|
|
37
|
+
private tmuxSessionName?;
|
|
38
|
+
private pendingRelayMessages;
|
|
39
|
+
private outputBuffer;
|
|
40
|
+
private lastOutputFlush;
|
|
41
|
+
constructor(config: WrapperConfig);
|
|
42
|
+
/**
|
|
43
|
+
* Start the wrapped agent process.
|
|
44
|
+
*/
|
|
45
|
+
start(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Start with tmux for message injection.
|
|
48
|
+
*/
|
|
49
|
+
private startWithTmux;
|
|
50
|
+
/**
|
|
51
|
+
* Start directly without tmux.
|
|
52
|
+
*/
|
|
53
|
+
private startDirect;
|
|
54
|
+
/**
|
|
55
|
+
* Set up PTY event handlers.
|
|
56
|
+
*/
|
|
57
|
+
private setupPtyHandlers;
|
|
58
|
+
/**
|
|
59
|
+
* Stop the wrapped process.
|
|
60
|
+
*/
|
|
61
|
+
stop(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Handle output from the PTY process.
|
|
64
|
+
*/
|
|
65
|
+
private handlePtyOutput;
|
|
66
|
+
/**
|
|
67
|
+
* Schedule message injection after output settles.
|
|
68
|
+
* We inject messages when there's been a pause in output (tool finished).
|
|
69
|
+
*/
|
|
70
|
+
private scheduleMessageInjection;
|
|
71
|
+
/**
|
|
72
|
+
* Inject pending relay messages into the output stream.
|
|
73
|
+
* Claude will see these as part of the terminal output.
|
|
74
|
+
* Then send a minimal trigger to stdin to prompt processing.
|
|
75
|
+
*/
|
|
76
|
+
private injectPendingMessages;
|
|
77
|
+
/**
|
|
78
|
+
* Send a parsed relay command to the daemon.
|
|
79
|
+
* Includes deduplication to prevent sending the same message multiple times.
|
|
80
|
+
*/
|
|
81
|
+
private sendRelayCommand;
|
|
82
|
+
/**
|
|
83
|
+
* Handle incoming message from relay.
|
|
84
|
+
*
|
|
85
|
+
* Strategy:
|
|
86
|
+
* - Always show notification in terminal (real-time visual cue)
|
|
87
|
+
* - If inbox mode: also write to inbox file (for hook polling)
|
|
88
|
+
* - No stdin injection (unreliable after a few rounds)
|
|
89
|
+
*/
|
|
90
|
+
private handleIncomingMessage;
|
|
91
|
+
/**
|
|
92
|
+
* Process the next message in the queue when Claude is idle.
|
|
93
|
+
*/
|
|
94
|
+
private processNextMessage;
|
|
95
|
+
/**
|
|
96
|
+
* Inject message using osascript (macOS keyboard simulation).
|
|
97
|
+
* This sends keystrokes at the OS level to the frontmost application.
|
|
98
|
+
*/
|
|
99
|
+
private injectViaOsascript;
|
|
100
|
+
/**
|
|
101
|
+
* Inject message using tmux send-keys.
|
|
102
|
+
*/
|
|
103
|
+
private injectViaTmux;
|
|
104
|
+
/**
|
|
105
|
+
* Inject message using direct PTY write.
|
|
106
|
+
*/
|
|
107
|
+
private injectViaPty;
|
|
108
|
+
/**
|
|
109
|
+
* Wait until Claude has been idle (no output) for a period.
|
|
110
|
+
*/
|
|
111
|
+
private waitForIdle;
|
|
112
|
+
/**
|
|
113
|
+
* Simulate human typing by sending characters one at a time.
|
|
114
|
+
*/
|
|
115
|
+
private simulateTyping;
|
|
116
|
+
/**
|
|
117
|
+
* Check if wrapper is running.
|
|
118
|
+
*/
|
|
119
|
+
get isRunning(): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Get agent name.
|
|
122
|
+
*/
|
|
123
|
+
get name(): string;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=pty-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-wrapper.d.ts","sourceRoot":"","sources":["../../src/wrapper/pty-wrapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,4DAA4D;IAC5D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAC,CAAW;IAC9B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,YAAY,CAAqD;IACzE,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,oBAAoB,CAA6C;IACzE,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,eAAe,CAAK;gBAEhB,MAAM,EAAE,aAAa;IAiCjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC5B;;OAEG;YACW,aAAa;IAwC3B;;OAEG;YACW,WAAW;IAkBzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4CxB;;OAEG;IACH,IAAI,IAAI,IAAI;IAYZ;;OAEG;IACH,OAAO,CAAC,eAAe;IA0BvB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAahC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA2C1B;;;OAGG;YACW,kBAAkB;IA6BhC;;OAEG;YACW,aAAa;IA2B3B;;OAEG;YACW,YAAY;IAqB1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAkCnB;;OAEG;YACW,cAAc;IAQ5B;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PTY Wrapper
|
|
3
|
+
* Wraps an agent CLI command in a pseudo-terminal and intercepts
|
|
4
|
+
* relay commands from output while injecting incoming messages.
|
|
5
|
+
*/
|
|
6
|
+
import * as pty from 'node-pty';
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
import { RelayClient } from './client.js';
|
|
9
|
+
import { OutputParser } from './parser.js';
|
|
10
|
+
import { InboxManager } from './inbox.js';
|
|
11
|
+
export class PtyWrapper {
|
|
12
|
+
config;
|
|
13
|
+
ptyProcess;
|
|
14
|
+
client;
|
|
15
|
+
parser;
|
|
16
|
+
inbox;
|
|
17
|
+
running = false;
|
|
18
|
+
lastOutputTime = 0;
|
|
19
|
+
messageQueue = [];
|
|
20
|
+
processingMessage = false;
|
|
21
|
+
recentlySentMessages = new Map(); // hash -> timestamp
|
|
22
|
+
tmuxSessionName;
|
|
23
|
+
pendingRelayMessages = [];
|
|
24
|
+
outputBuffer = '';
|
|
25
|
+
lastOutputFlush = 0;
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.config = {
|
|
28
|
+
// Use actual terminal size, fallback to defaults
|
|
29
|
+
cols: process.stdout.columns || 120,
|
|
30
|
+
rows: process.stdout.rows || 40,
|
|
31
|
+
...config,
|
|
32
|
+
};
|
|
33
|
+
this.client = new RelayClient({
|
|
34
|
+
agentName: config.name,
|
|
35
|
+
socketPath: config.socketPath,
|
|
36
|
+
});
|
|
37
|
+
this.parser = new OutputParser();
|
|
38
|
+
// Initialize inbox if using file-based messaging
|
|
39
|
+
if (config.useInbox) {
|
|
40
|
+
this.inbox = new InboxManager({
|
|
41
|
+
agentName: config.name,
|
|
42
|
+
inboxDir: config.inboxDir,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// Handle incoming messages
|
|
46
|
+
this.client.onMessage = (from, payload) => {
|
|
47
|
+
this.handleIncomingMessage(from, payload);
|
|
48
|
+
};
|
|
49
|
+
this.client.onStateChange = (state) => {
|
|
50
|
+
process.stderr.write(`[wrapper:${this.config.name}] Relay state: ${state}\n`);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Start the wrapped agent process.
|
|
55
|
+
*/
|
|
56
|
+
async start() {
|
|
57
|
+
if (this.running)
|
|
58
|
+
return;
|
|
59
|
+
// Initialize inbox if using file-based messaging
|
|
60
|
+
if (this.inbox) {
|
|
61
|
+
this.inbox.init();
|
|
62
|
+
const inboxPath = this.inbox.getInboxPath();
|
|
63
|
+
process.stderr.write(`[wrapper:${this.config.name}] Inbox mode enabled\n`);
|
|
64
|
+
process.stderr.write(`[wrapper:${this.config.name}] Inbox path: ${inboxPath}\n`);
|
|
65
|
+
process.stderr.write(`[wrapper:${this.config.name}] Tell agent: "After each response, read ${inboxPath} for messages"\n`);
|
|
66
|
+
}
|
|
67
|
+
// Connect to relay daemon
|
|
68
|
+
try {
|
|
69
|
+
await this.client.connect();
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
process.stderr.write(`[wrapper:${this.config.name}] Failed to connect to relay: ${err}\n`);
|
|
73
|
+
// Continue without relay - agent can still run standalone
|
|
74
|
+
}
|
|
75
|
+
// Parse command
|
|
76
|
+
const [cmd, ...defaultArgs] = this.config.command.split(' ');
|
|
77
|
+
const args = this.config.args ?? defaultArgs;
|
|
78
|
+
if (this.config.useTmux) {
|
|
79
|
+
await this.startWithTmux(cmd, args);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await this.startDirect(cmd, args);
|
|
83
|
+
}
|
|
84
|
+
process.stderr.write(`[wrapper:${this.config.name}] Started: ${this.config.command}${this.config.useTmux ? ' (tmux mode)' : ''}${this.config.useInbox ? ' (inbox mode)' : ''}\n`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Start with tmux for message injection.
|
|
88
|
+
*/
|
|
89
|
+
async startWithTmux(cmd, args) {
|
|
90
|
+
// Create a unique tmux session name
|
|
91
|
+
this.tmuxSessionName = `relay-${this.config.name}-${Date.now()}`;
|
|
92
|
+
const fullCommand = [cmd, ...args].join(' ');
|
|
93
|
+
// Kill any existing session with this name
|
|
94
|
+
try {
|
|
95
|
+
execSync(`tmux kill-session -t ${this.tmuxSessionName} 2>/dev/null`, { encoding: 'utf-8' });
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Session doesn't exist, that's fine
|
|
99
|
+
}
|
|
100
|
+
// Create tmux session running the command
|
|
101
|
+
const tmuxCmd = `tmux new-session -d -s ${this.tmuxSessionName} -x ${this.config.cols} -y ${this.config.rows} '${fullCommand}'`;
|
|
102
|
+
execSync(tmuxCmd, {
|
|
103
|
+
cwd: this.config.cwd ?? process.cwd(),
|
|
104
|
+
env: {
|
|
105
|
+
...process.env,
|
|
106
|
+
...this.config.env,
|
|
107
|
+
AGENT_RELAY_NAME: this.config.name,
|
|
108
|
+
TERM: 'xterm-256color',
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
// Attach to tmux session via PTY (so we can capture output)
|
|
112
|
+
this.ptyProcess = pty.spawn('tmux', ['attach-session', '-t', this.tmuxSessionName], {
|
|
113
|
+
name: 'xterm-256color',
|
|
114
|
+
cols: this.config.cols,
|
|
115
|
+
rows: this.config.rows,
|
|
116
|
+
cwd: this.config.cwd ?? process.cwd(),
|
|
117
|
+
env: {
|
|
118
|
+
...process.env,
|
|
119
|
+
TERM: 'xterm-256color',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
this.running = true;
|
|
123
|
+
this.setupPtyHandlers();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Start directly without tmux.
|
|
127
|
+
*/
|
|
128
|
+
async startDirect(cmd, args) {
|
|
129
|
+
this.ptyProcess = pty.spawn(cmd, args, {
|
|
130
|
+
name: 'xterm-256color',
|
|
131
|
+
cols: this.config.cols,
|
|
132
|
+
rows: this.config.rows,
|
|
133
|
+
cwd: this.config.cwd ?? process.cwd(),
|
|
134
|
+
env: {
|
|
135
|
+
...process.env,
|
|
136
|
+
...this.config.env,
|
|
137
|
+
AGENT_RELAY_NAME: this.config.name,
|
|
138
|
+
TERM: 'xterm-256color',
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
this.running = true;
|
|
142
|
+
this.setupPtyHandlers();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Set up PTY event handlers.
|
|
146
|
+
*/
|
|
147
|
+
setupPtyHandlers() {
|
|
148
|
+
if (!this.ptyProcess)
|
|
149
|
+
return;
|
|
150
|
+
// Handle PTY output
|
|
151
|
+
this.ptyProcess.onData((data) => {
|
|
152
|
+
this.handlePtyOutput(data);
|
|
153
|
+
});
|
|
154
|
+
// Handle PTY exit
|
|
155
|
+
this.ptyProcess.onExit(({ exitCode, signal }) => {
|
|
156
|
+
process.stderr.write(`[wrapper:${this.config.name}] Process exited (code: ${exitCode}, signal: ${signal})\n`);
|
|
157
|
+
this.running = false;
|
|
158
|
+
this.client.destroy();
|
|
159
|
+
// Clean up tmux session if using tmux
|
|
160
|
+
if (this.tmuxSessionName) {
|
|
161
|
+
try {
|
|
162
|
+
execSync(`tmux kill-session -t ${this.tmuxSessionName} 2>/dev/null`);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Ignore
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Exit the wrapper process with the same code as the wrapped process
|
|
169
|
+
process.exit(exitCode);
|
|
170
|
+
});
|
|
171
|
+
// Forward stdin to PTY
|
|
172
|
+
process.stdin.setRawMode?.(true);
|
|
173
|
+
process.stdin.resume();
|
|
174
|
+
process.stdin.on('data', (data) => {
|
|
175
|
+
if (this.ptyProcess) {
|
|
176
|
+
this.ptyProcess.write(data.toString());
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
// Handle terminal resize
|
|
180
|
+
process.stdout.on('resize', () => {
|
|
181
|
+
if (this.ptyProcess) {
|
|
182
|
+
this.ptyProcess.resize(process.stdout.columns, process.stdout.rows);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Stop the wrapped process.
|
|
188
|
+
*/
|
|
189
|
+
stop() {
|
|
190
|
+
if (!this.running)
|
|
191
|
+
return;
|
|
192
|
+
if (this.ptyProcess) {
|
|
193
|
+
this.ptyProcess.kill();
|
|
194
|
+
this.ptyProcess = undefined;
|
|
195
|
+
}
|
|
196
|
+
this.client.destroy();
|
|
197
|
+
this.running = false;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Handle output from the PTY process.
|
|
201
|
+
*/
|
|
202
|
+
handlePtyOutput(data) {
|
|
203
|
+
// Track output timing for idle detection
|
|
204
|
+
this.lastOutputTime = Date.now();
|
|
205
|
+
// Raw mode: pass through everything without parsing
|
|
206
|
+
if (this.config.raw) {
|
|
207
|
+
process.stdout.write(data);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
// Parse for relay commands
|
|
211
|
+
const { commands, output } = this.parser.parse(data);
|
|
212
|
+
// Send any extracted commands to relay
|
|
213
|
+
for (const cmd of commands) {
|
|
214
|
+
this.sendRelayCommand(cmd);
|
|
215
|
+
}
|
|
216
|
+
// Output to terminal (with relay commands filtered)
|
|
217
|
+
process.stdout.write(output);
|
|
218
|
+
// Buffer output and check for injection opportunity
|
|
219
|
+
this.outputBuffer += data;
|
|
220
|
+
this.scheduleMessageInjection();
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Schedule message injection after output settles.
|
|
224
|
+
* We inject messages when there's been a pause in output (tool finished).
|
|
225
|
+
*/
|
|
226
|
+
scheduleMessageInjection() {
|
|
227
|
+
// Clear any existing timer
|
|
228
|
+
if (this.lastOutputFlush) {
|
|
229
|
+
clearTimeout(this.lastOutputFlush);
|
|
230
|
+
}
|
|
231
|
+
// Schedule injection after 500ms of quiet (output stopped)
|
|
232
|
+
this.lastOutputFlush = Date.now();
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
this.injectPendingMessages();
|
|
235
|
+
}, 500);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Inject pending relay messages into the output stream.
|
|
239
|
+
* Claude will see these as part of the terminal output.
|
|
240
|
+
* Then send a minimal trigger to stdin to prompt processing.
|
|
241
|
+
*/
|
|
242
|
+
injectPendingMessages() {
|
|
243
|
+
if (this.pendingRelayMessages.length === 0)
|
|
244
|
+
return;
|
|
245
|
+
if (!this.running || !this.ptyProcess)
|
|
246
|
+
return;
|
|
247
|
+
// Check if output has actually settled (no new output in 500ms)
|
|
248
|
+
const timeSinceOutput = Date.now() - this.lastOutputTime;
|
|
249
|
+
if (timeSinceOutput < 400) {
|
|
250
|
+
// Output still active, reschedule
|
|
251
|
+
this.scheduleMessageInjection();
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
// Inject all pending messages to stdout (visible context)
|
|
255
|
+
const messages = this.pendingRelayMessages.splice(0);
|
|
256
|
+
for (const msg of messages) {
|
|
257
|
+
const notification = `\n\n📨 [RELAY MESSAGE FROM ${msg.from}]: ${msg.body}\n`;
|
|
258
|
+
process.stdout.write(notification);
|
|
259
|
+
process.stderr.write(`[relay] Injected message from ${msg.from} into output\n`);
|
|
260
|
+
}
|
|
261
|
+
// Clear output buffer
|
|
262
|
+
this.outputBuffer = '';
|
|
263
|
+
// Now send a minimal trigger to stdin to prompt Claude to process
|
|
264
|
+
// Using a short trigger instead of the full message for reliability
|
|
265
|
+
setTimeout(() => {
|
|
266
|
+
if (this.ptyProcess && this.running) {
|
|
267
|
+
process.stderr.write(`[relay] Sending minimal trigger to stdin\n`);
|
|
268
|
+
this.ptyProcess.write('respond to the relay message above\r');
|
|
269
|
+
}
|
|
270
|
+
}, 300);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Send a parsed relay command to the daemon.
|
|
274
|
+
* Includes deduplication to prevent sending the same message multiple times.
|
|
275
|
+
*/
|
|
276
|
+
sendRelayCommand(cmd) {
|
|
277
|
+
// Create a hash of the message for deduplication
|
|
278
|
+
const msgHash = `${cmd.to}:${cmd.body}`;
|
|
279
|
+
const now = Date.now();
|
|
280
|
+
const lastSent = this.recentlySentMessages.get(msgHash);
|
|
281
|
+
// Skip if same message was sent in the last 5 seconds
|
|
282
|
+
if (lastSent && now - lastSent < 5000) {
|
|
283
|
+
process.stderr.write(`[relay] Skipping duplicate message to ${cmd.to}\n`);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const success = this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data);
|
|
287
|
+
if (success) {
|
|
288
|
+
this.recentlySentMessages.set(msgHash, now);
|
|
289
|
+
// Clean up old entries
|
|
290
|
+
for (const [hash, ts] of this.recentlySentMessages) {
|
|
291
|
+
if (now - ts > 10000)
|
|
292
|
+
this.recentlySentMessages.delete(hash);
|
|
293
|
+
}
|
|
294
|
+
process.stderr.write(`[relay → ${cmd.to}] ${cmd.body.substring(0, 50)}${cmd.body.length > 50 ? '...' : ''}\n`);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
process.stderr.write(`[relay] Failed to send to ${cmd.to}\n`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Handle incoming message from relay.
|
|
302
|
+
*
|
|
303
|
+
* Strategy:
|
|
304
|
+
* - Always show notification in terminal (real-time visual cue)
|
|
305
|
+
* - If inbox mode: also write to inbox file (for hook polling)
|
|
306
|
+
* - No stdin injection (unreliable after a few rounds)
|
|
307
|
+
*/
|
|
308
|
+
handleIncomingMessage(from, payload) {
|
|
309
|
+
// Log to stderr
|
|
310
|
+
process.stderr.write(`\n[relay ← ${from}] ${payload.body}\n`);
|
|
311
|
+
if (!this.running || !this.ptyProcess)
|
|
312
|
+
return;
|
|
313
|
+
// Sanitize the message for display
|
|
314
|
+
const sanitizedBody = payload.body.replace(/[\r\n]+/g, ' ').trim();
|
|
315
|
+
// Always show notification in terminal (real-time visual cue)
|
|
316
|
+
const notification = `\n\n📨 [RELAY MESSAGE FROM ${from}]: ${sanitizedBody}\n`;
|
|
317
|
+
process.stdout.write(notification);
|
|
318
|
+
// If inbox mode, also write to file for hook polling
|
|
319
|
+
if (this.inbox) {
|
|
320
|
+
this.inbox.addMessage(from, payload.body);
|
|
321
|
+
process.stderr.write(`[relay] Message written to inbox file (hook will poll)\n`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Process the next message in the queue when Claude is idle.
|
|
326
|
+
*/
|
|
327
|
+
processNextMessage() {
|
|
328
|
+
if (this.messageQueue.length === 0) {
|
|
329
|
+
this.processingMessage = false;
|
|
330
|
+
process.stderr.write(`[inject] Queue empty, done processing\n`);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
this.processingMessage = true;
|
|
334
|
+
const msg = this.messageQueue.shift();
|
|
335
|
+
process.stderr.write(`[inject] Processing message from ${msg.from}, waiting for idle...\n`);
|
|
336
|
+
// Wait for Claude to be idle (no output for 2 seconds)
|
|
337
|
+
this.waitForIdle().then(() => {
|
|
338
|
+
if (!this.running) {
|
|
339
|
+
this.processingMessage = false;
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
process.stderr.write(`[inject] Claude is idle, injecting message\n`);
|
|
343
|
+
// Sanitize message: replace newlines with spaces, trim
|
|
344
|
+
const sanitizedBody = msg.payload.body.replace(/[\r\n]+/g, ' ').trim();
|
|
345
|
+
const injection = `Relay message from ${msg.from}: ${sanitizedBody}`;
|
|
346
|
+
if (this.config.useOsascript) {
|
|
347
|
+
// Use OS-level keyboard simulation (macOS)
|
|
348
|
+
this.injectViaOsascript(injection).then(() => {
|
|
349
|
+
setTimeout(() => this.processNextMessage(), 1000);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
else if (this.config.useTmux && this.tmuxSessionName) {
|
|
353
|
+
// Use tmux send-keys for injection
|
|
354
|
+
this.injectViaTmux(injection).then(() => {
|
|
355
|
+
setTimeout(() => this.processNextMessage(), 1000);
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
// Use direct PTY injection
|
|
360
|
+
this.injectViaPty(injection).then(() => {
|
|
361
|
+
setTimeout(() => this.processNextMessage(), 1000);
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Inject message using osascript (macOS keyboard simulation).
|
|
368
|
+
* This sends keystrokes at the OS level to the frontmost application.
|
|
369
|
+
*/
|
|
370
|
+
async injectViaOsascript(message) {
|
|
371
|
+
try {
|
|
372
|
+
// Escape special characters for AppleScript
|
|
373
|
+
const escaped = message
|
|
374
|
+
.replace(/\\/g, '\\\\')
|
|
375
|
+
.replace(/"/g, '\\"')
|
|
376
|
+
.replace(/'/g, "'");
|
|
377
|
+
// First, send Escape to exit any special modes
|
|
378
|
+
execSync(`osascript -e 'tell application "System Events" to key code 53'`); // ESC
|
|
379
|
+
await new Promise(r => setTimeout(r, 100));
|
|
380
|
+
// Clear line with Cmd+A then delete (select all in input, delete)
|
|
381
|
+
execSync(`osascript -e 'tell application "System Events" to keystroke "u" using control down'`); // Ctrl+U
|
|
382
|
+
await new Promise(r => setTimeout(r, 50));
|
|
383
|
+
// Type the message
|
|
384
|
+
process.stderr.write(`[inject] Sending via osascript: ${message.substring(0, 50)}...\n`);
|
|
385
|
+
execSync(`osascript -e 'tell application "System Events" to keystroke "${escaped}"'`);
|
|
386
|
+
await new Promise(r => setTimeout(r, 100));
|
|
387
|
+
// Send Enter
|
|
388
|
+
process.stderr.write(`[inject] Sending Enter via osascript\n`);
|
|
389
|
+
execSync(`osascript -e 'tell application "System Events" to key code 36'`); // Enter
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
process.stderr.write(`[inject] osascript error: ${err}\n`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Inject message using tmux send-keys.
|
|
397
|
+
*/
|
|
398
|
+
async injectViaTmux(message) {
|
|
399
|
+
if (!this.tmuxSessionName)
|
|
400
|
+
return;
|
|
401
|
+
try {
|
|
402
|
+
// Escape special characters for tmux
|
|
403
|
+
const escaped = message.replace(/'/g, "'\\''");
|
|
404
|
+
// Send ESC to exit any special modes
|
|
405
|
+
execSync(`tmux send-keys -t ${this.tmuxSessionName} Escape`);
|
|
406
|
+
await new Promise(r => setTimeout(r, 50));
|
|
407
|
+
// Clear line
|
|
408
|
+
execSync(`tmux send-keys -t ${this.tmuxSessionName} C-u`);
|
|
409
|
+
await new Promise(r => setTimeout(r, 50));
|
|
410
|
+
// Send the message
|
|
411
|
+
execSync(`tmux send-keys -t ${this.tmuxSessionName} '${escaped}'`);
|
|
412
|
+
await new Promise(r => setTimeout(r, 100));
|
|
413
|
+
// Send Enter
|
|
414
|
+
process.stderr.write(`[inject] Sending Enter via tmux\n`);
|
|
415
|
+
execSync(`tmux send-keys -t ${this.tmuxSessionName} Enter`);
|
|
416
|
+
}
|
|
417
|
+
catch (err) {
|
|
418
|
+
process.stderr.write(`[inject] tmux send-keys error: ${err}\n`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Inject message using direct PTY write.
|
|
423
|
+
*/
|
|
424
|
+
async injectViaPty(message) {
|
|
425
|
+
if (!this.ptyProcess || !this.running)
|
|
426
|
+
return;
|
|
427
|
+
// Exit any special modes (INSERT, etc) first
|
|
428
|
+
this.ptyProcess.write('\x1b'); // ESC
|
|
429
|
+
this.ptyProcess.write('\x1b'); // Double ESC to be sure
|
|
430
|
+
this.ptyProcess.write('\x15'); // Ctrl+U to clear line
|
|
431
|
+
await new Promise(r => setTimeout(r, 100));
|
|
432
|
+
// Type character by character
|
|
433
|
+
await this.simulateTyping(message);
|
|
434
|
+
await new Promise(r => setTimeout(r, 200));
|
|
435
|
+
if (this.ptyProcess && this.running) {
|
|
436
|
+
process.stderr.write(`[inject] Typing done, sending Enter\n`);
|
|
437
|
+
this.ptyProcess.write('\r'); // Submit
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Wait until Claude has been idle (no output) for a period.
|
|
442
|
+
*/
|
|
443
|
+
waitForIdle(idleMs = 2000, maxWaitMs = 30000) {
|
|
444
|
+
return new Promise((resolve) => {
|
|
445
|
+
const startTime = Date.now();
|
|
446
|
+
const checkIdle = () => {
|
|
447
|
+
if (!this.running) {
|
|
448
|
+
resolve();
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
const timeSinceOutput = Date.now() - this.lastOutputTime;
|
|
452
|
+
const totalWait = Date.now() - startTime;
|
|
453
|
+
// If idle for long enough, or max wait exceeded, proceed
|
|
454
|
+
if (timeSinceOutput >= idleMs) {
|
|
455
|
+
process.stderr.write(`[inject] Idle detected (${timeSinceOutput}ms since output)\n`);
|
|
456
|
+
resolve();
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (totalWait >= maxWaitMs) {
|
|
460
|
+
process.stderr.write(`[inject] Max wait exceeded (${totalWait}ms), forcing inject\n`);
|
|
461
|
+
resolve();
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
// Check again in 100ms
|
|
465
|
+
setTimeout(checkIdle, 100);
|
|
466
|
+
};
|
|
467
|
+
checkIdle();
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Simulate human typing by sending characters one at a time.
|
|
472
|
+
*/
|
|
473
|
+
async simulateTyping(text) {
|
|
474
|
+
for (const char of text) {
|
|
475
|
+
if (!this.ptyProcess || !this.running)
|
|
476
|
+
return;
|
|
477
|
+
this.ptyProcess.write(char);
|
|
478
|
+
await new Promise(resolve => setTimeout(resolve, 5)); // 5ms per character
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Check if wrapper is running.
|
|
483
|
+
*/
|
|
484
|
+
get isRunning() {
|
|
485
|
+
return this.running;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Get agent name.
|
|
489
|
+
*/
|
|
490
|
+
get name() {
|
|
491
|
+
return this.config.name;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
//# sourceMappingURL=pty-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-wrapper.js","sourceRoot":"","sources":["../../src/wrapper/pty-wrapper.ts"],"names":[],"mappings":"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"}
|