@kdonev/termscape 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/LICENSE +21 -0
- package/README.md +288 -0
- package/dist/agents/env.d.ts +36 -0
- package/dist/agents/env.d.ts.map +1 -0
- package/dist/agents/env.js +61 -0
- package/dist/agents/env.js.map +1 -0
- package/dist/agents/profiles.d.ts +45 -0
- package/dist/agents/profiles.d.ts.map +1 -0
- package/dist/agents/profiles.js +123 -0
- package/dist/agents/profiles.js.map +1 -0
- package/dist/agents/resolve.d.ts +16 -0
- package/dist/agents/resolve.d.ts.map +1 -0
- package/dist/agents/resolve.js +71 -0
- package/dist/agents/resolve.js.map +1 -0
- package/dist/agents/router.d.ts +29 -0
- package/dist/agents/router.d.ts.map +1 -0
- package/dist/agents/router.js +83 -0
- package/dist/agents/router.js.map +1 -0
- package/dist/agents/tokens.d.ts +21 -0
- package/dist/agents/tokens.d.ts.map +1 -0
- package/dist/agents/tokens.js +39 -0
- package/dist/agents/tokens.js.map +1 -0
- package/dist/agents/wiring.d.ts +30 -0
- package/dist/agents/wiring.d.ts.map +1 -0
- package/dist/agents/wiring.js +110 -0
- package/dist/agents/wiring.js.map +1 -0
- package/dist/browser.d.ts +13 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +34 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +200 -0
- package/dist/cli.js.map +1 -0
- package/dist/db/index.d.ts +14 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +24 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +15 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +176 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/store.d.ts +71 -0
- package/dist/db/store.d.ts.map +1 -0
- package/dist/db/store.js +341 -0
- package/dist/db/store.js.map +1 -0
- package/dist/hub.d.ts +188 -0
- package/dist/hub.d.ts.map +1 -0
- package/dist/hub.js +636 -0
- package/dist/hub.js.map +1 -0
- package/dist/hub.tgz +0 -0
- package/dist/mcp/server.d.ts +31 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +66 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/paths.d.ts +27 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -0
- package/dist/protocol/address.d.ts +15 -0
- package/dist/protocol/address.d.ts.map +1 -0
- package/dist/protocol/address.js +39 -0
- package/dist/protocol/address.js.map +1 -0
- package/dist/protocol/domain.d.ts +151 -0
- package/dist/protocol/domain.d.ts.map +1 -0
- package/dist/protocol/domain.js +104 -0
- package/dist/protocol/domain.js.map +1 -0
- package/dist/protocol/index.d.ts +7 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +7 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/inject.d.ts +29 -0
- package/dist/protocol/inject.d.ts.map +1 -0
- package/dist/protocol/inject.js +40 -0
- package/dist/protocol/inject.js.map +1 -0
- package/dist/protocol/mcp-tools.d.ts +45 -0
- package/dist/protocol/mcp-tools.d.ts.map +1 -0
- package/dist/protocol/mcp-tools.js +46 -0
- package/dist/protocol/mcp-tools.js.map +1 -0
- package/dist/protocol/peer.d.ts +304 -0
- package/dist/protocol/peer.d.ts.map +1 -0
- package/dist/protocol/peer.js +183 -0
- package/dist/protocol/peer.js.map +1 -0
- package/dist/protocol/ws.d.ts +416 -0
- package/dist/protocol/ws.d.ts.map +1 -0
- package/dist/protocol/ws.js +119 -0
- package/dist/protocol/ws.js.map +1 -0
- package/dist/remote/deployer.d.ts +78 -0
- package/dist/remote/deployer.d.ts.map +1 -0
- package/dist/remote/deployer.js +216 -0
- package/dist/remote/deployer.js.map +1 -0
- package/dist/remote/enroll.d.ts +14 -0
- package/dist/remote/enroll.d.ts.map +1 -0
- package/dist/remote/enroll.js +244 -0
- package/dist/remote/enroll.js.map +1 -0
- package/dist/remote/join-script.d.ts +29 -0
- package/dist/remote/join-script.d.ts.map +1 -0
- package/dist/remote/join-script.js +709 -0
- package/dist/remote/join-script.js.map +1 -0
- package/dist/remote/join.d.ts +19 -0
- package/dist/remote/join.d.ts.map +1 -0
- package/dist/remote/join.js +195 -0
- package/dist/remote/join.js.map +1 -0
- package/dist/remote/lan.d.ts +45 -0
- package/dist/remote/lan.d.ts.map +1 -0
- package/dist/remote/lan.js +105 -0
- package/dist/remote/lan.js.map +1 -0
- package/dist/remote/peer-serve.d.ts +27 -0
- package/dist/remote/peer-serve.d.ts.map +1 -0
- package/dist/remote/peer-serve.js +274 -0
- package/dist/remote/peer-serve.js.map +1 -0
- package/dist/remote/peer.d.ts +62 -0
- package/dist/remote/peer.d.ts.map +1 -0
- package/dist/remote/peer.js +250 -0
- package/dist/remote/peer.js.map +1 -0
- package/dist/remote/registry.d.ts +104 -0
- package/dist/remote/registry.d.ts.map +1 -0
- package/dist/remote/registry.js +359 -0
- package/dist/remote/registry.js.map +1 -0
- package/dist/remote/tarball.d.ts +9 -0
- package/dist/remote/tarball.d.ts.map +1 -0
- package/dist/remote/tarball.js +22 -0
- package/dist/remote/tarball.js.map +1 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +438 -0
- package/dist/server.js.map +1 -0
- package/dist/session/manager.d.ts +104 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +421 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/pty.d.ts +114 -0
- package/dist/session/pty.d.ts.map +1 -0
- package/dist/session/pty.js +300 -0
- package/dist/session/pty.js.map +1 -0
- package/package.json +49 -0
- package/web/assets/index-B2JtCtHa.css +1 -0
- package/web/assets/index-BOqZOoep.js +107 -0
- package/web/index.html +13 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { makeAddress, uniqueName, } from '../protocol/index.js';
|
|
5
|
+
import { DEFAULT_WINDOW } from '../db/store.js';
|
|
6
|
+
import { template, templateAll } from '../agents/profiles.js';
|
|
7
|
+
import { resolveCommand } from '../agents/resolve.js';
|
|
8
|
+
import { writeWiring } from '../agents/wiring.js';
|
|
9
|
+
import { PtySession } from './pty.js';
|
|
10
|
+
/** Debounce for persisting the serialized screen of an active session. */
|
|
11
|
+
const SNAPSHOT_DEBOUNCE_MS = 5_000;
|
|
12
|
+
/**
|
|
13
|
+
* How long titles are pooled before one write and one broadcast. An agent
|
|
14
|
+
* rewrites its terminal title as it works, and every change would otherwise be
|
|
15
|
+
* a row update and a frame to every browser.
|
|
16
|
+
*/
|
|
17
|
+
const TITLE_COALESCE_MS = 250;
|
|
18
|
+
/** Debounce for persisting window geometry while a window is being dragged. */
|
|
19
|
+
export const LAYOUT_DEBOUNCE_MS = 250;
|
|
20
|
+
/**
|
|
21
|
+
* Owns every PTY on this hub, plus the persistence of their state.
|
|
22
|
+
*
|
|
23
|
+
* The invariant worth stating: SQLite always holds enough to redraw the canvas
|
|
24
|
+
* and relaunch each agent. Live objects here are a cache over that, never the
|
|
25
|
+
* other way round.
|
|
26
|
+
*/
|
|
27
|
+
export class SessionManager extends EventEmitter {
|
|
28
|
+
store;
|
|
29
|
+
profiles;
|
|
30
|
+
tokens;
|
|
31
|
+
hubOrigin;
|
|
32
|
+
live = new Map();
|
|
33
|
+
snapshotTimers = new Map();
|
|
34
|
+
layoutTimers = new Map();
|
|
35
|
+
/** Latest title per session, waiting for the coalescing window to close. */
|
|
36
|
+
pendingTitles = new Map();
|
|
37
|
+
titleTimer = null;
|
|
38
|
+
constructor(store, profiles, tokens, hubOrigin) {
|
|
39
|
+
super();
|
|
40
|
+
this.store = store;
|
|
41
|
+
this.profiles = profiles;
|
|
42
|
+
this.tokens = tokens;
|
|
43
|
+
this.hubOrigin = hubOrigin;
|
|
44
|
+
}
|
|
45
|
+
setHubOrigin(origin) {
|
|
46
|
+
this.hubOrigin = origin;
|
|
47
|
+
}
|
|
48
|
+
/* ----------------------------------------------------------- accessors */
|
|
49
|
+
isResumable = (profile) => this.profiles.isResumable(profile);
|
|
50
|
+
list() {
|
|
51
|
+
return this.store.listSessions(this.isResumable).map((s) => this.decorate(s));
|
|
52
|
+
}
|
|
53
|
+
get(id) {
|
|
54
|
+
const s = this.store.getSession(id, this.isResumable);
|
|
55
|
+
return s ? this.decorate(s) : null;
|
|
56
|
+
}
|
|
57
|
+
getByAddress(address) {
|
|
58
|
+
return this.list().find((s) => s.address === address) ?? null;
|
|
59
|
+
}
|
|
60
|
+
/** Overlay live runtime status onto the persisted row. */
|
|
61
|
+
decorate(s) {
|
|
62
|
+
const p = this.live.get(s.id);
|
|
63
|
+
if (!p)
|
|
64
|
+
return s;
|
|
65
|
+
return { ...s, status: p.status, pid: p.pid, cols: p.cols, rows: p.rows };
|
|
66
|
+
}
|
|
67
|
+
pty(id) {
|
|
68
|
+
return this.live.get(id) ?? null;
|
|
69
|
+
}
|
|
70
|
+
/* -------------------------------------------------------------- launch */
|
|
71
|
+
/** Build the resolved argv/env for a launch. `resume` swaps in --resume. */
|
|
72
|
+
buildSpec(session, workspaceName, profile, peers, resume) {
|
|
73
|
+
const token = this.tokens.mint(session.id);
|
|
74
|
+
let vars = {
|
|
75
|
+
address: session.address,
|
|
76
|
+
workspace: workspaceName,
|
|
77
|
+
cwd: session.cwd,
|
|
78
|
+
session_uuid: session.agentSessionUuid ?? '',
|
|
79
|
+
default_shell: profile.command,
|
|
80
|
+
};
|
|
81
|
+
if (profile.mcp) {
|
|
82
|
+
const w = writeWiring({
|
|
83
|
+
sessionId: session.id,
|
|
84
|
+
address: session.address,
|
|
85
|
+
workspace: workspaceName,
|
|
86
|
+
cwd: session.cwd,
|
|
87
|
+
profile,
|
|
88
|
+
token,
|
|
89
|
+
hubOrigin: this.hubOrigin,
|
|
90
|
+
peers,
|
|
91
|
+
});
|
|
92
|
+
vars = {
|
|
93
|
+
...vars,
|
|
94
|
+
mcp_config_path: w.mcpConfigPath,
|
|
95
|
+
settings_path: w.settingsPath,
|
|
96
|
+
brief_path: w.briefPath,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const argTemplate = resume && profile.resumeArgs ? profile.resumeArgs : profile.args;
|
|
100
|
+
// Resolve to an absolute path here rather than at spawn time, so the
|
|
101
|
+
// stored argv is exactly what will be run and a missing CLI is reported
|
|
102
|
+
// as a clear error instead of node-pty's bare "File not found:".
|
|
103
|
+
const { argv } = resolveCommand(template(profile.command, vars), templateAll(argTemplate, vars));
|
|
104
|
+
return {
|
|
105
|
+
argv,
|
|
106
|
+
env: Object.fromEntries(Object.entries(profile.env).map(([k, v]) => [k, templateAll([v], vars)[0]])),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
peersOf(workspaceId, exceptId) {
|
|
110
|
+
return this.list()
|
|
111
|
+
.filter((s) => s.workspaceId === workspaceId && s.id !== exceptId)
|
|
112
|
+
.map((s) => s.address);
|
|
113
|
+
}
|
|
114
|
+
async start(opts) {
|
|
115
|
+
const ws = this.store.getWorkspace(opts.workspaceId);
|
|
116
|
+
if (!ws)
|
|
117
|
+
throw new Error(`unknown workspace ${opts.workspaceId}`);
|
|
118
|
+
const profile = this.profiles.require(opts.profileId);
|
|
119
|
+
const name = uniqueName(opts.name ?? opts.profileId, this.store.namesInWorkspace(ws.id));
|
|
120
|
+
const id = randomUUID();
|
|
121
|
+
const cwd = opts.cwd ?? ws.rootPath;
|
|
122
|
+
if (!existsSync(cwd))
|
|
123
|
+
throw new Error(`working directory does not exist: ${cwd}`);
|
|
124
|
+
const now = Date.now();
|
|
125
|
+
const session = {
|
|
126
|
+
id,
|
|
127
|
+
workspaceId: ws.id,
|
|
128
|
+
name,
|
|
129
|
+
address: makeAddress(ws.name, name),
|
|
130
|
+
profile: profile.id,
|
|
131
|
+
cwd,
|
|
132
|
+
// Claude Code keys its conversation store by cwd + this uuid; holding on
|
|
133
|
+
// to it is what makes --resume possible after a restart.
|
|
134
|
+
agentSessionUuid: profile.resumeArgs ? randomUUID() : null,
|
|
135
|
+
spawnedBy: opts.spawnedBy ?? null,
|
|
136
|
+
state: 'starting',
|
|
137
|
+
status: 'unknown',
|
|
138
|
+
statusText: null,
|
|
139
|
+
title: null,
|
|
140
|
+
pid: null,
|
|
141
|
+
exitCode: null,
|
|
142
|
+
cols: opts.cols ?? 100,
|
|
143
|
+
rows: opts.rows ?? 30,
|
|
144
|
+
resumable: !!profile.resumeArgs,
|
|
145
|
+
createdAt: now,
|
|
146
|
+
exitedAt: null,
|
|
147
|
+
lastActiveAt: now,
|
|
148
|
+
window: opts.window ?? this.placeWindow(ws.id, opts.spawnedBy ?? null),
|
|
149
|
+
};
|
|
150
|
+
const spec = this.buildSpec(session, ws.name, profile, this.peersOf(ws.id), false);
|
|
151
|
+
this.store.insertSession(session, spec);
|
|
152
|
+
this.spawn(session, spec, profile);
|
|
153
|
+
return this.get(id);
|
|
154
|
+
}
|
|
155
|
+
/** Bring a stopped session back, reusing its recorded argv and cwd. */
|
|
156
|
+
async resume(sessionId) {
|
|
157
|
+
const s = this.store.getSession(sessionId, this.isResumable);
|
|
158
|
+
if (!s)
|
|
159
|
+
throw new Error(`unknown session ${sessionId}`);
|
|
160
|
+
if (this.live.get(sessionId)?.running)
|
|
161
|
+
return this.get(sessionId);
|
|
162
|
+
const ws = this.store.getWorkspace(s.workspaceId);
|
|
163
|
+
if (!ws)
|
|
164
|
+
throw new Error(`unknown workspace ${s.workspaceId}`);
|
|
165
|
+
const profile = this.profiles.require(s.profile);
|
|
166
|
+
// Rebuild rather than replay the stored argv verbatim: the token must be
|
|
167
|
+
// fresh and the wiring files must be rewritten for this run.
|
|
168
|
+
const spec = this.buildSpec(s, ws.name, profile, this.peersOf(ws.id, s.id), !!profile.resumeArgs && !!s.agentSessionUuid);
|
|
169
|
+
this.store.setLaunchSpec(s.id, spec);
|
|
170
|
+
this.spawn(s, spec, profile);
|
|
171
|
+
return this.get(sessionId);
|
|
172
|
+
}
|
|
173
|
+
spawn(session, spec, profile) {
|
|
174
|
+
const existing = this.live.get(session.id);
|
|
175
|
+
if (existing)
|
|
176
|
+
existing.dispose();
|
|
177
|
+
const p = new PtySession(session.id, session.cols, session.rows, profile.readyHint ? new RegExp(profile.readyHint) : null, profile.status);
|
|
178
|
+
this.live.set(session.id, p);
|
|
179
|
+
// Restoring the persisted screen first means a resumed window shows its
|
|
180
|
+
// prior content immediately rather than flashing empty.
|
|
181
|
+
const snap = this.store.getSnapshot(session.id);
|
|
182
|
+
if (snap)
|
|
183
|
+
p.restore(snap.serialized);
|
|
184
|
+
p.on('data', (chunk) => {
|
|
185
|
+
this.emit('data', session.id, chunk);
|
|
186
|
+
this.scheduleSnapshot(session.id);
|
|
187
|
+
});
|
|
188
|
+
p.on('status', () => this.emitSession(session.id));
|
|
189
|
+
p.on('title', (title) => this.noteTitle(session.id, title));
|
|
190
|
+
p.on('exit', ({ exitCode }) => {
|
|
191
|
+
this.persistSnapshot(session.id);
|
|
192
|
+
this.tokens.revoke(session.id);
|
|
193
|
+
this.store.updateSession(session.id, {
|
|
194
|
+
state: 'exited',
|
|
195
|
+
pid: null,
|
|
196
|
+
exitCode,
|
|
197
|
+
exitedAt: Date.now(),
|
|
198
|
+
});
|
|
199
|
+
this.emit('exit', session.id, exitCode);
|
|
200
|
+
this.emitSession(session.id);
|
|
201
|
+
});
|
|
202
|
+
try {
|
|
203
|
+
p.start({
|
|
204
|
+
argv: spec.argv,
|
|
205
|
+
env: spec.env,
|
|
206
|
+
cwd: session.cwd,
|
|
207
|
+
cols: session.cols,
|
|
208
|
+
rows: session.rows,
|
|
209
|
+
});
|
|
210
|
+
this.store.updateSession(session.id, {
|
|
211
|
+
state: 'running',
|
|
212
|
+
pid: p.pid,
|
|
213
|
+
exitCode: null,
|
|
214
|
+
exitedAt: null,
|
|
215
|
+
lastActiveAt: Date.now(),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
this.store.updateSession(session.id, {
|
|
220
|
+
state: 'failed',
|
|
221
|
+
pid: null,
|
|
222
|
+
exitedAt: Date.now(),
|
|
223
|
+
});
|
|
224
|
+
this.emitSession(session.id);
|
|
225
|
+
throw err;
|
|
226
|
+
}
|
|
227
|
+
this.emitSession(session.id);
|
|
228
|
+
}
|
|
229
|
+
/* --------------------------------------------------------------- input */
|
|
230
|
+
write(sessionId, data) {
|
|
231
|
+
const p = this.live.get(sessionId);
|
|
232
|
+
if (!p?.running)
|
|
233
|
+
throw new Error(`session ${sessionId} is not running`);
|
|
234
|
+
p.write(data);
|
|
235
|
+
this.store.updateSession(sessionId, { lastActiveAt: Date.now() });
|
|
236
|
+
}
|
|
237
|
+
resize(sessionId, cols, rows) {
|
|
238
|
+
const p = this.live.get(sessionId);
|
|
239
|
+
p?.resize(cols, rows);
|
|
240
|
+
this.store.updateSession(sessionId, { cols, rows });
|
|
241
|
+
}
|
|
242
|
+
setStatusText(sessionId, text) {
|
|
243
|
+
this.store.updateSession(sessionId, { statusText: text });
|
|
244
|
+
this.emitSession(sessionId);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* A title the program in the PTY set for itself.
|
|
248
|
+
*
|
|
249
|
+
* An agent rewrites this as it works, several times a second, so the write
|
|
250
|
+
* and the broadcast are held to the last value in a window rather than one
|
|
251
|
+
* apiece. Unrefed: a pending title is never a reason to keep the process up.
|
|
252
|
+
*/
|
|
253
|
+
noteTitle(sessionId, title) {
|
|
254
|
+
this.pendingTitles.set(sessionId, title);
|
|
255
|
+
if (this.titleTimer)
|
|
256
|
+
return;
|
|
257
|
+
this.titleTimer = setTimeout(() => {
|
|
258
|
+
this.titleTimer = null;
|
|
259
|
+
const batch = [...this.pendingTitles];
|
|
260
|
+
this.pendingTitles.clear();
|
|
261
|
+
for (const [id, t] of batch) {
|
|
262
|
+
this.store.updateSession(id, { title: t });
|
|
263
|
+
this.emitSession(id);
|
|
264
|
+
}
|
|
265
|
+
}, TITLE_COALESCE_MS);
|
|
266
|
+
this.titleTimer.unref?.();
|
|
267
|
+
}
|
|
268
|
+
/** Called by the hooks endpoint: exact turn boundaries from the agent CLI. */
|
|
269
|
+
setStatusFromHook(sessionId, status) {
|
|
270
|
+
this.live.get(sessionId)?.noteHook(status);
|
|
271
|
+
this.emitSession(sessionId);
|
|
272
|
+
}
|
|
273
|
+
stop(sessionId) {
|
|
274
|
+
const p = this.live.get(sessionId);
|
|
275
|
+
if (!p)
|
|
276
|
+
return;
|
|
277
|
+
this.persistSnapshot(sessionId);
|
|
278
|
+
p.kill();
|
|
279
|
+
this.tokens.revoke(sessionId);
|
|
280
|
+
this.store.updateSession(sessionId, { state: 'stopped', pid: null });
|
|
281
|
+
this.emitSession(sessionId);
|
|
282
|
+
}
|
|
283
|
+
remove(sessionId) {
|
|
284
|
+
// Capture the address before the row goes: peers address sessions by
|
|
285
|
+
// name, and after the delete there is nothing left to look it up from.
|
|
286
|
+
const address = this.get(sessionId)?.address ?? null;
|
|
287
|
+
this.live.get(sessionId)?.dispose();
|
|
288
|
+
this.live.delete(sessionId);
|
|
289
|
+
this.clearTimer(this.snapshotTimers, sessionId);
|
|
290
|
+
this.clearTimer(this.layoutTimers, sessionId);
|
|
291
|
+
this.tokens.revoke(sessionId);
|
|
292
|
+
this.store.removeSession(sessionId);
|
|
293
|
+
this.emit('removed', sessionId, address);
|
|
294
|
+
}
|
|
295
|
+
/* ------------------------------------------------------------ snapshots */
|
|
296
|
+
scheduleSnapshot(sessionId) {
|
|
297
|
+
if (this.snapshotTimers.has(sessionId))
|
|
298
|
+
return;
|
|
299
|
+
const t = setTimeout(() => {
|
|
300
|
+
this.snapshotTimers.delete(sessionId);
|
|
301
|
+
this.persistSnapshot(sessionId);
|
|
302
|
+
}, SNAPSHOT_DEBOUNCE_MS);
|
|
303
|
+
// Never let a pending snapshot hold the process open at shutdown.
|
|
304
|
+
t.unref?.();
|
|
305
|
+
this.snapshotTimers.set(sessionId, t);
|
|
306
|
+
}
|
|
307
|
+
/** Screen only — the deliberate cost of the snapshot-only design. */
|
|
308
|
+
persistSnapshot(sessionId) {
|
|
309
|
+
const p = this.live.get(sessionId);
|
|
310
|
+
if (!p)
|
|
311
|
+
return;
|
|
312
|
+
try {
|
|
313
|
+
this.store.saveSnapshot(sessionId, p.serializeForPersist(), p.cols, p.rows);
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
console.error(`[snapshot] ${sessionId}: ${err.message}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
persistAllSnapshots() {
|
|
320
|
+
for (const id of this.live.keys())
|
|
321
|
+
this.persistSnapshot(id);
|
|
322
|
+
}
|
|
323
|
+
snapshotForAttach(sessionId) {
|
|
324
|
+
const p = this.live.get(sessionId);
|
|
325
|
+
if (p)
|
|
326
|
+
return { serialized: p.serializeForAttach(), cols: p.cols, rows: p.rows };
|
|
327
|
+
// Not running: fall back to whatever the last persisted screen was.
|
|
328
|
+
return this.store.getSnapshot(sessionId);
|
|
329
|
+
}
|
|
330
|
+
/* --------------------------------------------------------------- layout */
|
|
331
|
+
moveWindow(sessionId, rect) {
|
|
332
|
+
this.clearTimer(this.layoutTimers, sessionId);
|
|
333
|
+
const t = setTimeout(() => {
|
|
334
|
+
this.layoutTimers.delete(sessionId);
|
|
335
|
+
this.store.saveWindow(sessionId, rect);
|
|
336
|
+
}, LAYOUT_DEBOUNCE_MS);
|
|
337
|
+
t.unref?.();
|
|
338
|
+
this.layoutTimers.set(sessionId, t);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Place a new window: tucked below-right of its parent when spawned by
|
|
342
|
+
* another agent, otherwise in the next free slot of a simple grid.
|
|
343
|
+
*/
|
|
344
|
+
placeWindow(workspaceId, parentId) {
|
|
345
|
+
const siblings = this.list().filter((s) => s.workspaceId === workspaceId);
|
|
346
|
+
if (parentId) {
|
|
347
|
+
const parent = this.get(parentId);
|
|
348
|
+
if (parent) {
|
|
349
|
+
return {
|
|
350
|
+
...DEFAULT_WINDOW,
|
|
351
|
+
x: parent.window.x + 60,
|
|
352
|
+
y: parent.window.y + parent.window.h + 40,
|
|
353
|
+
z: parent.window.z + 1,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const all = this.list();
|
|
358
|
+
const col = siblings.length % 3;
|
|
359
|
+
const row = Math.floor(siblings.length / 3);
|
|
360
|
+
const originX = all.length === siblings.length ? 0 : this.workspaceOriginX(workspaceId);
|
|
361
|
+
return {
|
|
362
|
+
...DEFAULT_WINDOW,
|
|
363
|
+
x: originX + col * (DEFAULT_WINDOW.w + 40),
|
|
364
|
+
y: row * (DEFAULT_WINDOW.h + 40),
|
|
365
|
+
z: siblings.length,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
/** Workspaces are laid out left to right so their groups do not overlap. */
|
|
369
|
+
workspaceOriginX(workspaceId) {
|
|
370
|
+
const order = this.store.listWorkspaces().findIndex((w) => w.id === workspaceId);
|
|
371
|
+
return Math.max(0, order) * (DEFAULT_WINDOW.w + 40) * 3.5;
|
|
372
|
+
}
|
|
373
|
+
/* -------------------------------------------------------------- helpers */
|
|
374
|
+
clearTimer(map, key) {
|
|
375
|
+
const t = map.get(key);
|
|
376
|
+
if (t) {
|
|
377
|
+
clearTimeout(t);
|
|
378
|
+
map.delete(key);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
emitSession(sessionId) {
|
|
382
|
+
const s = this.get(sessionId);
|
|
383
|
+
if (s)
|
|
384
|
+
this.emit('session', s);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Startup reconciliation. Sessions cannot outlive the hub, so anything the
|
|
388
|
+
* DB still calls running is stale and is marked stopped, ready to resume.
|
|
389
|
+
*/
|
|
390
|
+
reconcileOnBoot() {
|
|
391
|
+
for (const s of this.store.listSessions(this.isResumable)) {
|
|
392
|
+
if (s.state === 'running' || s.state === 'starting') {
|
|
393
|
+
this.store.updateSession(s.id, { state: 'stopped', pid: null });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
shutdown() {
|
|
398
|
+
this.persistAllSnapshots();
|
|
399
|
+
for (const [id, p] of this.live) {
|
|
400
|
+
p.dispose();
|
|
401
|
+
this.store.updateSession(id, { state: 'stopped', pid: null });
|
|
402
|
+
}
|
|
403
|
+
this.live.clear();
|
|
404
|
+
for (const t of this.snapshotTimers.values())
|
|
405
|
+
clearTimeout(t);
|
|
406
|
+
for (const t of this.layoutTimers.values())
|
|
407
|
+
clearTimeout(t);
|
|
408
|
+
this.snapshotTimers.clear();
|
|
409
|
+
this.layoutTimers.clear();
|
|
410
|
+
// The title timer is a single shared timeout rather than one per session,
|
|
411
|
+
// which is exactly why it was missed here: it holds a write that would
|
|
412
|
+
// land after the caller closes the database, and better-sqlite3 throws
|
|
413
|
+
// rather than ignoring it. Unref keeps it from holding the process open;
|
|
414
|
+
// it does not stop it firing while the process is still coming down.
|
|
415
|
+
if (this.titleTimer)
|
|
416
|
+
clearTimeout(this.titleTimer);
|
|
417
|
+
this.titleTimer = null;
|
|
418
|
+
this.pendingTitles.clear();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { AgentStatus } from '../protocol/index.js';
|
|
3
|
+
export interface PtyStartOptions {
|
|
4
|
+
argv: string[];
|
|
5
|
+
env: Record<string, string>;
|
|
6
|
+
cwd: string;
|
|
7
|
+
cols: number;
|
|
8
|
+
rows: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PtyExit {
|
|
11
|
+
exitCode: number;
|
|
12
|
+
signal?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* One PTY plus a headless xterm that mirrors it.
|
|
16
|
+
*
|
|
17
|
+
* The headless terminal earns its keep twice: it produces the serialized
|
|
18
|
+
* screen we persist to SQLite, and it is the in-memory scrollback that backs
|
|
19
|
+
* LOD detach/reattach. Feeding one parser instead of keeping a separate raw
|
|
20
|
+
* ring buffer means the replayed screen is always consistent with what the
|
|
21
|
+
* program actually drew, escape sequences and all.
|
|
22
|
+
*/
|
|
23
|
+
export declare class PtySession extends EventEmitter {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
cols: number;
|
|
26
|
+
rows: number;
|
|
27
|
+
private readonly readyHint;
|
|
28
|
+
private readonly statusMode;
|
|
29
|
+
private proc;
|
|
30
|
+
private readonly term;
|
|
31
|
+
private readonly serializer;
|
|
32
|
+
private lastOutputAt;
|
|
33
|
+
private idleTimer;
|
|
34
|
+
private _status;
|
|
35
|
+
/**
|
|
36
|
+
* Whether this session has ever reported a turn boundary itself. Until it
|
|
37
|
+
* has, a `hooks` profile is indistinguishable from one whose hooks cannot
|
|
38
|
+
* run at all, and the dot has to come from somewhere.
|
|
39
|
+
*/
|
|
40
|
+
private hooksSeen;
|
|
41
|
+
/** Last title this program set, to keep repeats off the wire. */
|
|
42
|
+
private lastTitle;
|
|
43
|
+
/** argv[0], to recognise the one title the program did not choose. */
|
|
44
|
+
private launchedFile;
|
|
45
|
+
private disposed;
|
|
46
|
+
constructor(id: string, cols: number, rows: number, readyHint: RegExp | null, statusMode: 'hooks' | 'heuristic');
|
|
47
|
+
/**
|
|
48
|
+
* ConPTY announces the child's image path as the terminal title the moment
|
|
49
|
+
* it starts, before the program has said anything at all. That is Windows
|
|
50
|
+
* talking, not the agent, and `C:...node.exe` in a window header is worse
|
|
51
|
+
* than the canvas address it would replace.
|
|
52
|
+
*/
|
|
53
|
+
private isLaunchNoise;
|
|
54
|
+
get status(): AgentStatus;
|
|
55
|
+
get running(): boolean;
|
|
56
|
+
get pid(): number | null;
|
|
57
|
+
start(opts: PtyStartOptions): void;
|
|
58
|
+
/** Feed output to subscribers and to the mirror terminal. */
|
|
59
|
+
private ingest;
|
|
60
|
+
/**
|
|
61
|
+
* Idle detection from output alone. Drives the status chip only — never
|
|
62
|
+
* gates delivery, because delivery is immediate by design.
|
|
63
|
+
*
|
|
64
|
+
* Two callers, with different standards of proof. A `heuristic` profile has
|
|
65
|
+
* a prompt pattern, so a short quiet spell plus a matching last line is
|
|
66
|
+
* enough. A `hooks` profile only reaches here while its hooks have never
|
|
67
|
+
* arrived, and has nothing to match against, so it waits out a longer
|
|
68
|
+
* silence and takes that as the answer.
|
|
69
|
+
*/
|
|
70
|
+
private scheduleIdleCheck;
|
|
71
|
+
private clearIdleTimer;
|
|
72
|
+
markBusy(): void;
|
|
73
|
+
/**
|
|
74
|
+
* A turn boundary the agent reported itself. Exact, where reading the output
|
|
75
|
+
* is a guess — so the first one to arrive retires the fallback for good and
|
|
76
|
+
* this session's status is whatever its hooks say from then on.
|
|
77
|
+
*/
|
|
78
|
+
noteHook(s: AgentStatus): void;
|
|
79
|
+
setStatus(s: AgentStatus): void;
|
|
80
|
+
write(data: string): void;
|
|
81
|
+
resize(cols: number, rows: number): void;
|
|
82
|
+
/** Full-ish history, for a browser that just attached to this window. */
|
|
83
|
+
serializeForAttach(): string;
|
|
84
|
+
/**
|
|
85
|
+
* Screen only. This is what goes in SQLite: a restart preserves the last
|
|
86
|
+
* screenful, deliberately not the scrollback above it.
|
|
87
|
+
*/
|
|
88
|
+
serializeForPersist(): string;
|
|
89
|
+
/**
|
|
90
|
+
* The last line the program actually drew, wherever it is on the screen.
|
|
91
|
+
*
|
|
92
|
+
* Not the bottom row: a CLI sitting at its prompt after printing one banner
|
|
93
|
+
* has its prompt at the top and twenty-three blank rows under it, and
|
|
94
|
+
* testing the bottom row against a prompt pattern matched nothing, ever.
|
|
95
|
+
* That is what kept a freshly started window amber for the life of the
|
|
96
|
+
* process.
|
|
97
|
+
*/
|
|
98
|
+
private lastNonEmptyLine;
|
|
99
|
+
/**
|
|
100
|
+
* Trailing rendered lines, for the read_screen MCP tool.
|
|
101
|
+
*
|
|
102
|
+
* Rows the terminal wrapped are rejoined. A wrap is a property of how
|
|
103
|
+
* wide the window happens to be, not of the text, so breaking a line
|
|
104
|
+
* there hands the reader a word split down the middle at a column that
|
|
105
|
+
* depends on someone else's terminal size - and the reader here is an
|
|
106
|
+
* agent trying to make sense of what another agent is doing.
|
|
107
|
+
*/
|
|
108
|
+
tailLines(n: number): string;
|
|
109
|
+
/** Restore a persisted screen into the mirror so reattach shows it. */
|
|
110
|
+
restore(serialized: string): void;
|
|
111
|
+
kill(): void;
|
|
112
|
+
dispose(): void;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=pty.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty.d.ts","sourceRoot":"","sources":["../../src/session/pty.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAqBvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAqBD;;;;;;;;GAQG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAoBxC,QAAQ,CAAC,EAAE,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAvB7B,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAA0B;IACzC;;;;OAIG;IACH,OAAO,CAAC,SAAS,CAAS;IAC1B,iEAAiE;IACjE,OAAO,CAAC,SAAS,CAAuB;IACxC,sEAAsE;IACtE,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAS;gBAGd,EAAE,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACF,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,UAAU,EAAE,OAAO,GAAG,WAAW;IAwBpD;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IASrB,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,GAAG,IAAI,MAAM,GAAG,IAAI,CAEvB;IAED,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAkClC,6DAA6D;IAC7D,OAAO,CAAC,MAAM;IAWd;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,cAAc;IAOtB,QAAQ,IAAI,IAAI;IAIhB;;;;OAIG;IACH,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;IAM9B,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;IAM/B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IASxC,yEAAyE;IACzE,kBAAkB,IAAI,MAAM;IAI5B;;;OAGG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;;;;;OAQG;IACH,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAe5B,uEAAuE;IACvE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIjC,IAAI,IAAI,IAAI;IAWZ,OAAO,IAAI,IAAI;CAMhB"}
|