@bytespell/amux 0.0.11 → 0.0.13
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/.claude/settings.local.json +11 -0
- package/CLAUDE.md +104 -0
- package/LICENSE +21 -0
- package/README.md +215 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +118 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +68 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +135 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/{lib/mentions.d.ts → message-parser.d.ts} +3 -5
- package/dist/message-parser.d.ts.map +1 -0
- package/dist/message-parser.js +45 -0
- package/dist/message-parser.js.map +1 -0
- package/dist/message-parser.test.d.ts +2 -0
- package/dist/message-parser.test.d.ts.map +1 -0
- package/dist/message-parser.test.js +188 -0
- package/dist/message-parser.test.js.map +1 -0
- package/dist/server.d.ts +24 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +356 -0
- package/dist/server.js.map +1 -0
- package/dist/session-updates.d.ts +26 -0
- package/dist/session-updates.d.ts.map +1 -0
- package/dist/session-updates.js +68 -0
- package/dist/session-updates.js.map +1 -0
- package/dist/session-updates.test.d.ts +2 -0
- package/dist/session-updates.test.d.ts.map +1 -0
- package/dist/session-updates.test.js +223 -0
- package/dist/session-updates.test.js.map +1 -0
- package/dist/session.d.ts +208 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +580 -0
- package/dist/session.js.map +1 -0
- package/dist/state.d.ts +74 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +250 -0
- package/dist/state.js.map +1 -0
- package/dist/terminal.d.ts +47 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +137 -0
- package/dist/terminal.js.map +1 -0
- package/dist/types.d.ts +64 -2
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -31
- package/dist/types.js.map +1 -1
- package/dist/ws-adapter.d.ts +39 -0
- package/dist/ws-adapter.d.ts.map +1 -0
- package/dist/ws-adapter.js +198 -0
- package/dist/ws-adapter.js.map +1 -0
- package/package.json +47 -24
- package/src/client.ts +162 -0
- package/src/index.ts +66 -0
- package/src/message-parser.test.ts +207 -0
- package/src/message-parser.ts +54 -0
- package/src/session-updates.test.ts +265 -0
- package/src/session-updates.ts +87 -0
- package/src/session.ts +737 -0
- package/src/state.ts +287 -0
- package/src/terminal.ts +164 -0
- package/src/types.ts +88 -0
- package/src/ws-adapter.ts +245 -0
- package/tsconfig.json +22 -0
- package/vitest.config.ts +7 -0
- package/dist/chunk-5IPYOXBE.js +0 -32
- package/dist/chunk-5IPYOXBE.js.map +0 -1
- package/dist/chunk-C73RKCTS.js +0 -36
- package/dist/chunk-C73RKCTS.js.map +0 -1
- package/dist/chunk-VVXT4HQM.js +0 -779
- package/dist/chunk-VVXT4HQM.js.map +0 -1
- package/dist/lib/logger.d.ts +0 -24
- package/dist/lib/logger.js +0 -17
- package/dist/lib/logger.js.map +0 -1
- package/dist/lib/mentions.js +0 -7
- package/dist/lib/mentions.js.map +0 -1
- package/dist/streams/backends/index.d.ts +0 -88
- package/dist/streams/backends/index.js +0 -13
- package/dist/streams/backends/index.js.map +0 -1
- package/dist/streams/manager.d.ts +0 -55
- package/dist/streams/manager.js +0 -248
- package/dist/streams/manager.js.map +0 -1
- package/dist/types-DCRtrjjj.d.ts +0 -192
- package/scripts/fix-pty.cjs +0 -21
package/dist/state.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
/**
|
|
5
|
+
* Default state directory
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_STATE_DIR = path.join(os.homedir(), '.local', 'state', 'amux');
|
|
8
|
+
/**
|
|
9
|
+
* State manager for amux sessions.
|
|
10
|
+
* Handles persistence of session state and history.
|
|
11
|
+
*/
|
|
12
|
+
export class StateManager {
|
|
13
|
+
stateDir;
|
|
14
|
+
constructor(stateDir) {
|
|
15
|
+
this.stateDir = stateDir ?? DEFAULT_STATE_DIR;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the state file path for a specific instance
|
|
19
|
+
*/
|
|
20
|
+
getStateFilePath(instanceId) {
|
|
21
|
+
return path.join(this.stateDir, `instance-${instanceId}.json`);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get history file path for a session
|
|
25
|
+
*/
|
|
26
|
+
getHistoryPath(sessionId) {
|
|
27
|
+
return path.join(this.stateDir, `session-${sessionId}-history.json`);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get sessions registry file path
|
|
31
|
+
*/
|
|
32
|
+
getSessionsRegistryPath() {
|
|
33
|
+
return path.join(this.stateDir, 'sessions.json');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load persisted session state
|
|
37
|
+
*/
|
|
38
|
+
loadState(instanceId) {
|
|
39
|
+
console.log('[amux] Loading state for instance:', instanceId);
|
|
40
|
+
try {
|
|
41
|
+
const stateFile = this.getStateFilePath(instanceId);
|
|
42
|
+
if (fs.existsSync(stateFile)) {
|
|
43
|
+
const data = JSON.parse(fs.readFileSync(stateFile, 'utf-8'));
|
|
44
|
+
console.log('[amux] Loaded persisted state:', JSON.stringify(data));
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.log('[amux] Failed to load persisted state:', err.message);
|
|
50
|
+
}
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Save session state to disk
|
|
55
|
+
*/
|
|
56
|
+
saveState(instanceId, state) {
|
|
57
|
+
try {
|
|
58
|
+
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
59
|
+
const stateFile = this.getStateFilePath(instanceId);
|
|
60
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
console.log('[amux] Failed to save state:', err.message);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Store event to history for replay
|
|
68
|
+
*/
|
|
69
|
+
storeEvent(sessionId, event) {
|
|
70
|
+
if (!sessionId)
|
|
71
|
+
return;
|
|
72
|
+
// Only store session updates and turn markers
|
|
73
|
+
const isSessionUpdate = event.type === 'session_update';
|
|
74
|
+
const isTurnMarker = event.type === 'turn_start' || event.type === 'turn_end';
|
|
75
|
+
if (!isSessionUpdate && !isTurnMarker) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
80
|
+
const historyFile = this.getHistoryPath(sessionId);
|
|
81
|
+
let events = [];
|
|
82
|
+
if (fs.existsSync(historyFile)) {
|
|
83
|
+
const data = fs.readFileSync(historyFile, 'utf-8');
|
|
84
|
+
events = JSON.parse(data);
|
|
85
|
+
}
|
|
86
|
+
events.push(event);
|
|
87
|
+
fs.writeFileSync(historyFile, JSON.stringify(events));
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.log('[amux] Failed to store event:', err.message);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Load history for replay
|
|
95
|
+
*/
|
|
96
|
+
loadHistory(sessionId) {
|
|
97
|
+
if (!sessionId)
|
|
98
|
+
return [];
|
|
99
|
+
try {
|
|
100
|
+
const historyFile = this.getHistoryPath(sessionId);
|
|
101
|
+
if (fs.existsSync(historyFile)) {
|
|
102
|
+
const data = fs.readFileSync(historyFile, 'utf-8');
|
|
103
|
+
return JSON.parse(data);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
console.log('[amux] Failed to load history:', err.message);
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Clear history for a session
|
|
113
|
+
*/
|
|
114
|
+
clearHistory(sessionId) {
|
|
115
|
+
if (!sessionId)
|
|
116
|
+
return;
|
|
117
|
+
try {
|
|
118
|
+
const historyFile = this.getHistoryPath(sessionId);
|
|
119
|
+
if (fs.existsSync(historyFile)) {
|
|
120
|
+
fs.unlinkSync(historyFile);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.log('[amux] Failed to clear history:', err.message);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Load sessions registry
|
|
129
|
+
*/
|
|
130
|
+
loadSessionsRegistry() {
|
|
131
|
+
try {
|
|
132
|
+
const registryPath = this.getSessionsRegistryPath();
|
|
133
|
+
if (fs.existsSync(registryPath)) {
|
|
134
|
+
const data = fs.readFileSync(registryPath, 'utf-8');
|
|
135
|
+
return JSON.parse(data);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
console.log('[amux] Failed to load sessions registry:', err.message);
|
|
140
|
+
}
|
|
141
|
+
return { sessions: [] };
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Save sessions registry
|
|
145
|
+
*/
|
|
146
|
+
saveSessionsRegistry(registry) {
|
|
147
|
+
try {
|
|
148
|
+
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
149
|
+
const registryPath = this.getSessionsRegistryPath();
|
|
150
|
+
fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2));
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
console.log('[amux] Failed to save sessions registry:', err.message);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Register a new session or update existing one
|
|
158
|
+
*/
|
|
159
|
+
registerSession(sessionId, cwd, agentType, displayName) {
|
|
160
|
+
const registry = this.loadSessionsRegistry();
|
|
161
|
+
const existingIndex = registry.sessions.findIndex(s => s.id === sessionId);
|
|
162
|
+
const session = {
|
|
163
|
+
id: sessionId,
|
|
164
|
+
name: displayName || `Session ${sessionId.slice(0, 8)}`,
|
|
165
|
+
cwd,
|
|
166
|
+
messageCount: 0,
|
|
167
|
+
lastModified: Date.now(),
|
|
168
|
+
agentType,
|
|
169
|
+
};
|
|
170
|
+
if (existingIndex >= 0) {
|
|
171
|
+
// Update existing session, preserve message count
|
|
172
|
+
const existing = registry.sessions[existingIndex];
|
|
173
|
+
session.messageCount = existing?.messageCount ?? 0;
|
|
174
|
+
registry.sessions[existingIndex] = session;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// Add new session at the beginning (most recent first)
|
|
178
|
+
registry.sessions.unshift(session);
|
|
179
|
+
}
|
|
180
|
+
this.saveSessionsRegistry(registry);
|
|
181
|
+
console.log(`[amux] Registered session: ${sessionId}`);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Update session metadata
|
|
185
|
+
*/
|
|
186
|
+
updateSessionMetadata(sessionId, updates) {
|
|
187
|
+
const registry = this.loadSessionsRegistry();
|
|
188
|
+
const session = registry.sessions.find(s => s.id === sessionId);
|
|
189
|
+
if (session) {
|
|
190
|
+
if (updates.messageCount !== undefined) {
|
|
191
|
+
session.messageCount = updates.messageCount;
|
|
192
|
+
}
|
|
193
|
+
if (updates.lastModified !== undefined) {
|
|
194
|
+
session.lastModified = updates.lastModified;
|
|
195
|
+
}
|
|
196
|
+
if (updates.name !== undefined) {
|
|
197
|
+
session.name = updates.name;
|
|
198
|
+
}
|
|
199
|
+
this.saveSessionsRegistry(registry);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Increment message count for a session
|
|
204
|
+
*/
|
|
205
|
+
incrementSessionMessageCount(sessionId) {
|
|
206
|
+
const registry = this.loadSessionsRegistry();
|
|
207
|
+
const session = registry.sessions.find(s => s.id === sessionId);
|
|
208
|
+
if (session) {
|
|
209
|
+
session.messageCount += 1;
|
|
210
|
+
session.lastModified = Date.now();
|
|
211
|
+
this.saveSessionsRegistry(registry);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* List all sessions, optionally filtered by cwd
|
|
216
|
+
*/
|
|
217
|
+
listSessions(cwd) {
|
|
218
|
+
const registry = this.loadSessionsRegistry();
|
|
219
|
+
let sessions = registry.sessions;
|
|
220
|
+
// Filter by cwd if provided
|
|
221
|
+
if (cwd) {
|
|
222
|
+
sessions = sessions.filter(s => s.cwd === cwd);
|
|
223
|
+
}
|
|
224
|
+
// Sort by lastModified (most recent first)
|
|
225
|
+
sessions.sort((a, b) => b.lastModified - a.lastModified);
|
|
226
|
+
return sessions;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get a specific session by ID
|
|
230
|
+
*/
|
|
231
|
+
getSession(sessionId) {
|
|
232
|
+
const registry = this.loadSessionsRegistry();
|
|
233
|
+
return registry.sessions.find(s => s.id === sessionId);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Delete a session from the registry and its history
|
|
237
|
+
*/
|
|
238
|
+
deleteSession(sessionId) {
|
|
239
|
+
const registry = this.loadSessionsRegistry();
|
|
240
|
+
const index = registry.sessions.findIndex(s => s.id === sessionId);
|
|
241
|
+
if (index >= 0) {
|
|
242
|
+
registry.sessions.splice(index, 1);
|
|
243
|
+
this.saveSessionsRegistry(registry);
|
|
244
|
+
}
|
|
245
|
+
// Also clear the history file
|
|
246
|
+
this.clearHistory(sessionId);
|
|
247
|
+
console.log(`[amux] Deleted session: ${sessionId}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type ChildProcess } from 'child_process';
|
|
2
|
+
import type * as acp from '@agentclientprotocol/sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Terminal state tracking
|
|
5
|
+
*/
|
|
6
|
+
export interface TerminalState {
|
|
7
|
+
process: ChildProcess;
|
|
8
|
+
output: string;
|
|
9
|
+
exitCode: number | null;
|
|
10
|
+
signal: string | null;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
outputByteLimit: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Manages terminal processes for ACP terminal capability.
|
|
16
|
+
* Handles spawning, output collection, and lifecycle management.
|
|
17
|
+
*/
|
|
18
|
+
export declare class TerminalManager {
|
|
19
|
+
private defaultCwd;
|
|
20
|
+
private terminals;
|
|
21
|
+
constructor(defaultCwd: () => string);
|
|
22
|
+
/**
|
|
23
|
+
* Create a new terminal process
|
|
24
|
+
*/
|
|
25
|
+
create(params: acp.CreateTerminalRequest): acp.CreateTerminalResponse;
|
|
26
|
+
/**
|
|
27
|
+
* Get terminal output
|
|
28
|
+
*/
|
|
29
|
+
getOutput(terminalId: string): acp.TerminalOutputResponse;
|
|
30
|
+
/**
|
|
31
|
+
* Wait for terminal to exit
|
|
32
|
+
*/
|
|
33
|
+
waitForExit(terminalId: string): Promise<acp.WaitForTerminalExitResponse>;
|
|
34
|
+
/**
|
|
35
|
+
* Kill a terminal process
|
|
36
|
+
*/
|
|
37
|
+
kill(terminalId: string): acp.KillTerminalCommandResponse;
|
|
38
|
+
/**
|
|
39
|
+
* Release a terminal (cleanup)
|
|
40
|
+
*/
|
|
41
|
+
release(terminalId: string): acp.ReleaseTerminalResponse;
|
|
42
|
+
/**
|
|
43
|
+
* Kill all terminals (for shutdown)
|
|
44
|
+
*/
|
|
45
|
+
killAll(): void;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAGd,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,SAAS,CAAoC;gBAEjC,UAAU,EAAE,MAAM,MAAM;IAE5C;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,qBAAqB,GAAG,GAAG,CAAC,sBAAsB;IAqDrE;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,sBAAsB;IAezD;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;IAyB/E;;OAEG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,2BAA2B;IASzD;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,uBAAuB;IAWxD;;OAEG;IACH,OAAO,IAAI,IAAI;CAOhB"}
|
package/dist/terminal.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
/**
|
|
4
|
+
* Manages terminal processes for ACP terminal capability.
|
|
5
|
+
* Handles spawning, output collection, and lifecycle management.
|
|
6
|
+
*/
|
|
7
|
+
export class TerminalManager {
|
|
8
|
+
defaultCwd;
|
|
9
|
+
terminals = new Map();
|
|
10
|
+
constructor(defaultCwd) {
|
|
11
|
+
this.defaultCwd = defaultCwd;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a new terminal process
|
|
15
|
+
*/
|
|
16
|
+
create(params) {
|
|
17
|
+
console.log('[amux] Create terminal:', params.command);
|
|
18
|
+
const terminalId = crypto.randomUUID();
|
|
19
|
+
const outputByteLimit = Number(params.outputByteLimit ?? 1024 * 1024); // Default 1MB
|
|
20
|
+
const termProc = spawn(params.command, params.args ?? [], {
|
|
21
|
+
cwd: params.cwd ?? this.defaultCwd(),
|
|
22
|
+
env: params.env
|
|
23
|
+
? { ...process.env, ...Object.fromEntries(params.env.map(e => [e.name, e.value])) }
|
|
24
|
+
: process.env,
|
|
25
|
+
shell: true,
|
|
26
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
27
|
+
});
|
|
28
|
+
const terminal = {
|
|
29
|
+
process: termProc,
|
|
30
|
+
output: '',
|
|
31
|
+
exitCode: null,
|
|
32
|
+
signal: null,
|
|
33
|
+
truncated: false,
|
|
34
|
+
outputByteLimit,
|
|
35
|
+
};
|
|
36
|
+
const appendOutput = (data) => {
|
|
37
|
+
terminal.output += data.toString();
|
|
38
|
+
// Truncate from beginning if over limit
|
|
39
|
+
if (terminal.output.length > terminal.outputByteLimit) {
|
|
40
|
+
terminal.output = terminal.output.slice(-terminal.outputByteLimit);
|
|
41
|
+
terminal.truncated = true;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
termProc.stdout?.on('data', appendOutput);
|
|
45
|
+
termProc.stderr?.on('data', appendOutput);
|
|
46
|
+
termProc.on('exit', (code, signal) => {
|
|
47
|
+
console.log(`[amux] Terminal ${terminalId} exited with code ${code}, signal ${signal}`);
|
|
48
|
+
terminal.exitCode = code ?? null;
|
|
49
|
+
terminal.signal = signal ?? null;
|
|
50
|
+
});
|
|
51
|
+
termProc.on('error', (err) => {
|
|
52
|
+
console.error(`[amux] Terminal ${terminalId} error:`, err.message);
|
|
53
|
+
terminal.output += `\nError: ${err.message}`;
|
|
54
|
+
terminal.exitCode = -1;
|
|
55
|
+
});
|
|
56
|
+
this.terminals.set(terminalId, terminal);
|
|
57
|
+
console.log(`[amux] Created terminal ${terminalId} for command: ${params.command}`);
|
|
58
|
+
return { terminalId };
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get terminal output
|
|
62
|
+
*/
|
|
63
|
+
getOutput(terminalId) {
|
|
64
|
+
const terminal = this.terminals.get(terminalId);
|
|
65
|
+
if (!terminal) {
|
|
66
|
+
throw new Error(`Terminal ${terminalId} not found`);
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
output: terminal.output,
|
|
70
|
+
truncated: terminal.truncated,
|
|
71
|
+
exitStatus: terminal.exitCode !== null || terminal.signal !== null ? {
|
|
72
|
+
exitCode: terminal.exitCode,
|
|
73
|
+
signal: terminal.signal,
|
|
74
|
+
} : undefined,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Wait for terminal to exit
|
|
79
|
+
*/
|
|
80
|
+
async waitForExit(terminalId) {
|
|
81
|
+
const terminal = this.terminals.get(terminalId);
|
|
82
|
+
if (!terminal) {
|
|
83
|
+
throw new Error(`Terminal ${terminalId} not found`);
|
|
84
|
+
}
|
|
85
|
+
// If already exited, return immediately
|
|
86
|
+
if (terminal.exitCode !== null || terminal.signal !== null) {
|
|
87
|
+
return {
|
|
88
|
+
exitCode: terminal.exitCode,
|
|
89
|
+
signal: terminal.signal,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Wait for exit
|
|
93
|
+
return new Promise((resolve) => {
|
|
94
|
+
terminal.process.on('exit', (code, signal) => {
|
|
95
|
+
resolve({
|
|
96
|
+
exitCode: code ?? null,
|
|
97
|
+
signal: signal ?? null,
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Kill a terminal process
|
|
104
|
+
*/
|
|
105
|
+
kill(terminalId) {
|
|
106
|
+
const terminal = this.terminals.get(terminalId);
|
|
107
|
+
if (!terminal) {
|
|
108
|
+
throw new Error(`Terminal ${terminalId} not found`);
|
|
109
|
+
}
|
|
110
|
+
terminal.process.kill('SIGTERM');
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Release a terminal (cleanup)
|
|
115
|
+
*/
|
|
116
|
+
release(terminalId) {
|
|
117
|
+
const terminal = this.terminals.get(terminalId);
|
|
118
|
+
if (terminal) {
|
|
119
|
+
if (terminal.exitCode === null) {
|
|
120
|
+
terminal.process.kill('SIGKILL');
|
|
121
|
+
}
|
|
122
|
+
this.terminals.delete(terminalId);
|
|
123
|
+
}
|
|
124
|
+
return {};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Kill all terminals (for shutdown)
|
|
128
|
+
*/
|
|
129
|
+
killAll() {
|
|
130
|
+
for (const [terminalId, terminal] of this.terminals) {
|
|
131
|
+
console.log(`[amux] Killing terminal ${terminalId}`);
|
|
132
|
+
terminal.process.kill('SIGKILL');
|
|
133
|
+
}
|
|
134
|
+
this.terminals.clear();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type * as acp from '@agentclientprotocol/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Agent configuration - maps agent type to binary name
|
|
4
|
+
*/
|
|
5
|
+
export interface AgentConfig {
|
|
6
|
+
name: string;
|
|
7
|
+
bin: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Built-in agent registry
|
|
11
|
+
*/
|
|
12
|
+
export declare const AGENTS: Record<string, AgentConfig>;
|
|
13
|
+
/**
|
|
14
|
+
* Session metadata for persistence
|
|
15
|
+
*/
|
|
16
|
+
export interface SessionMetadata {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
cwd: string;
|
|
20
|
+
messageCount: number;
|
|
21
|
+
lastModified: number;
|
|
22
|
+
agentType: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Persisted session state
|
|
26
|
+
*/
|
|
27
|
+
export interface SessionState {
|
|
28
|
+
cwd?: string;
|
|
29
|
+
sessionId?: string | null;
|
|
30
|
+
agentType?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Event stored in history for replay
|
|
34
|
+
*/
|
|
35
|
+
export interface StoredEvent {
|
|
36
|
+
type: string;
|
|
37
|
+
update?: acp.SessionUpdate;
|
|
38
|
+
[key: string]: unknown;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Session restore info sent to UI
|
|
42
|
+
*/
|
|
43
|
+
export interface SessionRestoreInfo {
|
|
44
|
+
restored: boolean;
|
|
45
|
+
reason?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Configuration for creating an agent session
|
|
49
|
+
*/
|
|
50
|
+
export interface AgentSessionConfig {
|
|
51
|
+
/** Unique identifier for this session instance */
|
|
52
|
+
instanceId: string;
|
|
53
|
+
/** Base path for resolving agent binaries (node_modules/.bin) */
|
|
54
|
+
basePath: string;
|
|
55
|
+
/** Optional system context to inject (e.g., from a markdown file) */
|
|
56
|
+
systemContext?: string;
|
|
57
|
+
/** Optional fixed working directory (overrides user selection) */
|
|
58
|
+
fixedCwd?: string;
|
|
59
|
+
/** Optional initial agent type (defaults to 'claude-code') */
|
|
60
|
+
agentType?: string;
|
|
61
|
+
/** Optional state directory override */
|
|
62
|
+
stateDir?: string;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAa9C,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,GAAG,CAAC,aAAa,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IAEnB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IAEjB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
package/dist/types.js
CHANGED
|
@@ -1,33 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
function isAcpEvent(payload) {
|
|
18
|
-
return payload.eventType === "acp";
|
|
19
|
-
}
|
|
20
|
-
function isAcpLifecycleEvent(payload) {
|
|
21
|
-
return typeof payload.eventType === "string" && payload.eventType.startsWith("acp:");
|
|
22
|
-
}
|
|
23
|
-
function isTerminalEvent(payload) {
|
|
24
|
-
return typeof payload.eventType === "string" && payload.eventType.startsWith("terminal:");
|
|
25
|
-
}
|
|
26
|
-
export {
|
|
27
|
-
isAcpEvent,
|
|
28
|
-
isAcpLifecycleEvent,
|
|
29
|
-
isLifecycleEvent,
|
|
30
|
-
isTerminalEvent,
|
|
31
|
-
normalizePlanEntry
|
|
1
|
+
/**
|
|
2
|
+
* Built-in agent registry
|
|
3
|
+
*/
|
|
4
|
+
export const AGENTS = {
|
|
5
|
+
'claude-code': {
|
|
6
|
+
name: 'Claude Code',
|
|
7
|
+
bin: 'claude-code-acp',
|
|
8
|
+
},
|
|
9
|
+
'codex': {
|
|
10
|
+
name: 'Codex',
|
|
11
|
+
bin: 'codex-acp',
|
|
12
|
+
},
|
|
13
|
+
'pi': {
|
|
14
|
+
name: 'Pi',
|
|
15
|
+
bin: 'pi-acp',
|
|
16
|
+
},
|
|
32
17
|
};
|
|
33
18
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAgC;IACjD,aAAa,EAAE;QACb,IAAI,EAAE,aAAa;QACnB,GAAG,EAAE,iBAAiB;KACvB;IACD,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,GAAG,EAAE,WAAW;KACjB;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,QAAQ;KACd;CACF,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { WebSocketServer } from 'ws';
|
|
2
|
+
import type { AgentSession } from './session.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for the WebSocket adapter
|
|
5
|
+
*/
|
|
6
|
+
export interface WsAdapterOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Send history on connect (default: true)
|
|
9
|
+
*/
|
|
10
|
+
sendHistoryOnConnect?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create a WebSocket adapter for an AgentSession.
|
|
14
|
+
*
|
|
15
|
+
* Bridges session events to WebSocket clients and handles incoming messages.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { AgentSession } from 'amux';
|
|
20
|
+
* import { createWsAdapter } from 'amux/ws';
|
|
21
|
+
* import { WebSocketServer } from 'ws';
|
|
22
|
+
*
|
|
23
|
+
* const session = new AgentSession({ ... });
|
|
24
|
+
* const wss = new WebSocketServer({ server, path: '/ws' });
|
|
25
|
+
*
|
|
26
|
+
* createWsAdapter(session, wss);
|
|
27
|
+
*
|
|
28
|
+
* await session.spawnAgent();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createWsAdapter(session: AgentSession, wss: WebSocketServer, options?: WsAdapterOptions): {
|
|
32
|
+
/** Get connected client count */
|
|
33
|
+
clientCount: () => number;
|
|
34
|
+
/** Broadcast a custom message to all clients */
|
|
35
|
+
broadcast: (message: unknown) => void;
|
|
36
|
+
/** Close all connections */
|
|
37
|
+
close: () => void;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=ws-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-adapter.d.ts","sourceRoot":"","sources":["../src/ws-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,eAAe,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAUrE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,gBAAqB,GAC7B;IACD,iCAAiC;IACjC,WAAW,EAAE,MAAM,MAAM,CAAC;IAC1B,gDAAgD;IAChD,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,4BAA4B;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAmGA"}
|