@getpaseo/server 0.1.95 → 0.1.97-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/{utils/executable.d.ts → executable-resolution/executable-resolution.d.ts} +2 -2
- package/dist/server/{utils/executable.js → executable-resolution/executable-resolution.js} +16 -14
- package/dist/server/executable-resolution/windows.d.ts +18 -0
- package/dist/server/executable-resolution/windows.js +62 -0
- package/dist/server/server/agent/agent-loading.js +4 -1
- package/dist/server/server/agent/agent-manager.d.ts +10 -2
- package/dist/server/server/agent/agent-manager.js +34 -46
- package/dist/server/server/agent/agent-projections.js +3 -0
- package/dist/server/server/agent/agent-prompt.js +19 -1
- package/dist/server/server/agent/agent-response-loop.js +2 -4
- package/dist/server/server/agent/agent-storage.d.ts +18 -19
- package/dist/server/server/agent/agent-storage.js +6 -23
- package/dist/server/server/agent/create-agent/create.d.ts +2 -12
- package/dist/server/server/agent/create-agent/create.js +28 -30
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +4 -2
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +31 -22
- package/dist/server/server/agent/import-sessions.d.ts +1 -10
- package/dist/server/server/agent/import-sessions.js +1 -53
- package/dist/server/server/agent/lifecycle-command.js +5 -4
- package/dist/server/server/agent/mcp-server.d.ts +8 -5
- package/dist/server/server/agent/mcp-server.js +41 -14
- package/dist/server/server/agent/mcp-shared.d.ts +6 -3
- package/dist/server/server/agent/mcp-shared.js +3 -0
- package/dist/server/server/agent/provider-launch-config.js +1 -1
- package/dist/server/server/agent/providers/acp-agent.d.ts +5 -0
- package/dist/server/server/agent/providers/acp-agent.js +31 -26
- package/dist/server/server/agent/providers/claude/agent.js +45 -6
- package/dist/server/server/agent/providers/codex-app-server-agent.js +1 -1
- package/dist/server/server/agent/providers/copilot-acp-agent.js +1 -0
- package/dist/server/server/agent/providers/cursor-acp-agent.d.ts +0 -7
- package/dist/server/server/agent/providers/cursor-acp-agent.js +0 -78
- package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -0
- package/dist/server/server/agent/providers/mock-load-test-agent.js +73 -1
- package/dist/server/server/agent/providers/opencode/server-manager.js +1 -1
- package/dist/server/server/agent/structured-generation-providers.js +45 -1
- package/dist/server/server/agent-attention-policy.d.ts +12 -3
- package/dist/server/server/agent-attention-policy.js +15 -3
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +7 -6
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +21 -16
- package/dist/server/server/bootstrap.d.ts +3 -0
- package/dist/server/server/bootstrap.js +91 -12
- package/dist/server/server/config.js +1 -0
- package/dist/server/server/daemon-config-store.js +1 -0
- package/dist/server/server/exports.d.ts +1 -1
- package/dist/server/server/exports.js +1 -1
- package/dist/server/server/loop-service.d.ts +24 -24
- package/dist/server/server/migrations/backfill-workspace-id.migration.d.ts +9 -0
- package/dist/server/server/migrations/backfill-workspace-id.migration.js +60 -0
- package/dist/server/server/paseo-worktree-service.d.ts +9 -0
- package/dist/server/server/paseo-worktree-service.js +71 -12
- package/dist/server/server/path-utils.d.ts +1 -0
- package/dist/server/server/path-utils.js +6 -1
- package/dist/server/server/persisted-config.d.ts +7 -0
- package/dist/server/server/persisted-config.js +1 -0
- package/dist/server/server/persistence-hooks.d.ts +1 -0
- package/dist/server/server/persistence-hooks.js +13 -5
- package/dist/server/server/resolve-workspace-id-for-path.d.ts +3 -0
- package/dist/server/server/resolve-workspace-id-for-path.js +41 -0
- package/dist/server/server/script-proxy.d.ts +1 -1
- package/dist/server/server/script-proxy.js +1 -1
- package/dist/server/server/service-proxy.js +1 -1
- package/dist/server/server/session.d.ts +31 -6
- package/dist/server/server/session.js +640 -196
- package/dist/server/server/websocket-server.d.ts +5 -0
- package/dist/server/server/websocket-server.js +137 -3
- package/dist/server/server/workspace-archive-service.d.ts +60 -3
- package/dist/server/server/workspace-archive-service.js +217 -4
- package/dist/server/server/workspace-directory.d.ts +20 -2
- package/dist/server/server/workspace-directory.js +148 -70
- package/dist/server/server/workspace-git-service.js +21 -21
- package/dist/server/server/workspace-reconciliation-service.d.ts +1 -1
- package/dist/server/server/workspace-reconciliation-service.js +21 -22
- package/dist/server/server/workspace-registry-bootstrap.js +23 -10
- package/dist/server/server/workspace-registry-model.d.ts +3 -3
- package/dist/server/server/workspace-registry-model.js +9 -10
- package/dist/server/server/workspace-registry.d.ts +17 -4
- package/dist/server/server/workspace-registry.js +27 -0
- package/dist/server/server/worktree/commands.d.ts +7 -5
- package/dist/server/server/worktree/commands.js +38 -18
- package/dist/server/server/worktree-bootstrap.d.ts +1 -0
- package/dist/server/server/worktree-bootstrap.js +4 -1
- package/dist/server/server/worktree-branch-name-generator.d.ts +5 -1
- package/dist/server/server/worktree-branch-name-generator.js +8 -2
- package/dist/server/server/worktree-session.d.ts +4 -5
- package/dist/server/server/worktree-session.js +9 -3
- package/dist/server/services/github-service.js +1 -1
- package/dist/server/terminal/activity/terminal-activity-tracker.d.ts +20 -0
- package/dist/server/terminal/activity/terminal-activity-tracker.js +59 -0
- package/dist/server/terminal/agent-hooks/agent-hook-installer.d.ts +62 -0
- package/dist/server/terminal/agent-hooks/agent-hook-installer.js +117 -0
- package/dist/server/terminal/agent-hooks/claude/claude-settings.d.ts +7 -0
- package/dist/server/terminal/agent-hooks/claude/claude-settings.js +88 -0
- package/dist/server/terminal/agent-hooks/claude/claude.d.ts +4 -0
- package/dist/server/terminal/agent-hooks/claude/claude.js +47 -0
- package/dist/server/terminal/agent-hooks/codex/codex-settings.d.ts +7 -0
- package/dist/server/terminal/agent-hooks/codex/codex-settings.js +99 -0
- package/dist/server/terminal/agent-hooks/codex/codex.d.ts +4 -0
- package/dist/server/terminal/agent-hooks/codex/codex.js +30 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.d.ts +4 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.js +46 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode.d.ts +3 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode.js +23 -0
- package/dist/server/terminal/agent-hooks/provider-registry.d.ts +24 -0
- package/dist/server/terminal/agent-hooks/provider-registry.js +36 -0
- package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.d.ts +10 -0
- package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.js +26 -0
- package/dist/server/terminal/terminal-manager-factory.d.ts +4 -1
- package/dist/server/terminal/terminal-manager-factory.js +2 -2
- package/dist/server/terminal/terminal-manager.d.ts +33 -2
- package/dist/server/terminal/terminal-manager.js +144 -18
- package/dist/server/terminal/terminal-output-coalescer.d.ts +4 -0
- package/dist/server/terminal/terminal-output-coalescer.js +18 -0
- package/dist/server/terminal/terminal-restore.d.ts +1 -0
- package/dist/server/terminal/terminal-restore.js +6 -0
- package/dist/server/terminal/terminal-session-controller.d.ts +4 -2
- package/dist/server/terminal/terminal-session-controller.js +65 -24
- package/dist/server/terminal/terminal-worker-process.js +146 -63
- package/dist/server/terminal/terminal-worker-protocol.d.ts +19 -14
- package/dist/server/terminal/terminal.d.ts +42 -0
- package/dist/server/terminal/terminal.js +235 -16
- package/dist/server/terminal/worker-terminal-manager.d.ts +1 -0
- package/dist/server/terminal/worker-terminal-manager.js +220 -36
- package/dist/server/utils/build-metadata-prompt.d.ts +1 -1
- package/dist/server/utils/github-remote.js +1 -1
- package/dist/server/utils/tree-kill.d.ts +2 -2
- package/dist/src/{utils/executable.js → executable-resolution/executable-resolution.js} +16 -14
- package/dist/src/executable-resolution/windows.js +62 -0
- package/dist/src/server/agent/provider-launch-config.js +1 -1
- package/dist/src/server/persisted-config.js +1 -0
- package/package.json +10 -5
- package/dist/server/server/agent/agent-metadata-generator.d.ts +0 -36
- package/dist/server/server/agent/agent-metadata-generator.js +0 -112
- package/dist/server/server/paseo-worktree-archive-service.d.ts +0 -41
- package/dist/server/server/paseo-worktree-archive-service.js +0 -144
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import { createTerminalManager } from "./terminal-manager.js";
|
|
2
2
|
import { captureTerminalLines } from "./terminal-capture.js";
|
|
3
|
+
import { TerminalOutputCoalescer } from "./terminal-output-coalescer.js";
|
|
3
4
|
const manager = createTerminalManager();
|
|
4
5
|
const unsubscribeByTerminalId = new Map();
|
|
6
|
+
const outputCoalescerByTerminalId = new Map();
|
|
5
7
|
let ipcClosing = false;
|
|
8
|
+
let inFlightTerminalCreateRequest = null;
|
|
9
|
+
// The conpty failure signal is process-scoped, not request-scoped. Serializing
|
|
10
|
+
// creates keeps an async spawn failure attributable to exactly one request.
|
|
11
|
+
let createTerminalQueue = Promise.resolve();
|
|
12
|
+
// node-pty completes its Windows conpty spawn asynchronously on a separate
|
|
13
|
+
// conout worker thread. When that spawn fails (bad cwd, missing command, etc.)
|
|
14
|
+
// it throws an exception there that cannot be caught at the call site and would
|
|
15
|
+
// otherwise crash this worker process and sever every existing terminal.
|
|
16
|
+
process.on("uncaughtException", (error) => {
|
|
17
|
+
console.error("Terminal worker uncaught exception (kept alive):", error);
|
|
18
|
+
reportInFlightTerminalCreateFailure(error);
|
|
19
|
+
});
|
|
6
20
|
function sendToParent(message) {
|
|
7
21
|
if (ipcClosing || !process.connected || !process.send) {
|
|
8
22
|
return;
|
|
@@ -18,14 +32,37 @@ function sendToParent(message) {
|
|
|
18
32
|
ipcClosing = true;
|
|
19
33
|
}
|
|
20
34
|
}
|
|
35
|
+
function buildTerminalStateResult(session, options) {
|
|
36
|
+
if (!session) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return { ...session.getStateSnapshot(options), replayPreamble: session.getReplayPreamble() };
|
|
40
|
+
}
|
|
21
41
|
function toTerminalInfo(session) {
|
|
22
42
|
return {
|
|
23
43
|
id: session.id,
|
|
24
44
|
name: session.name,
|
|
25
45
|
cwd: session.cwd,
|
|
46
|
+
workspaceId: session.workspaceId,
|
|
26
47
|
...(session.getTitle() ? { title: session.getTitle() } : {}),
|
|
48
|
+
activity: session.getActivity(),
|
|
27
49
|
};
|
|
28
50
|
}
|
|
51
|
+
function terminalWorkerErrorMessage(error) {
|
|
52
|
+
return error instanceof Error ? error.message : "Terminal worker request failed";
|
|
53
|
+
}
|
|
54
|
+
function reportInFlightTerminalCreateFailure(error) {
|
|
55
|
+
if (!inFlightTerminalCreateRequest || inFlightTerminalCreateRequest.errorReported) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
inFlightTerminalCreateRequest.errorReported = true;
|
|
59
|
+
sendToParent({
|
|
60
|
+
type: "response",
|
|
61
|
+
requestId: inFlightTerminalCreateRequest.requestId,
|
|
62
|
+
ok: false,
|
|
63
|
+
error: terminalWorkerErrorMessage(error),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
29
66
|
function clearTerminalSubscriptions(terminalId) {
|
|
30
67
|
const subscriptions = unsubscribeByTerminalId.get(terminalId);
|
|
31
68
|
if (subscriptions) {
|
|
@@ -39,10 +76,41 @@ function clearTerminalSubscriptions(terminalId) {
|
|
|
39
76
|
}
|
|
40
77
|
}
|
|
41
78
|
unsubscribeByTerminalId.delete(terminalId);
|
|
79
|
+
const coalescer = outputCoalescerByTerminalId.get(terminalId);
|
|
80
|
+
if (coalescer) {
|
|
81
|
+
coalescer.dispose();
|
|
82
|
+
outputCoalescerByTerminalId.delete(terminalId);
|
|
83
|
+
}
|
|
42
84
|
}
|
|
43
85
|
function watchTerminal(session) {
|
|
44
86
|
clearTerminalSubscriptions(session.id);
|
|
87
|
+
// Coalesce pty output chunks into a single IPC message per ~5ms window so a
|
|
88
|
+
// burst of small chunks no longer costs one process.send each. The batch
|
|
89
|
+
// carries the LAST chunk's revision (the highest) so downstream snapshot
|
|
90
|
+
// replay dedup stays correct.
|
|
91
|
+
let pendingOutputRevision;
|
|
92
|
+
const outputCoalescer = new TerminalOutputCoalescer({
|
|
93
|
+
timers: { setTimeout, clearTimeout },
|
|
94
|
+
onFlush: ({ payload }) => {
|
|
95
|
+
const revision = pendingOutputRevision;
|
|
96
|
+
pendingOutputRevision = undefined;
|
|
97
|
+
sendToParent({
|
|
98
|
+
type: "terminalMessage",
|
|
99
|
+
terminalId: session.id,
|
|
100
|
+
message: { type: "output", data: payload.toString("utf8"), revision },
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
outputCoalescerByTerminalId.set(session.id, outputCoalescer);
|
|
45
105
|
const unsubscribeMessage = session.subscribe((message) => {
|
|
106
|
+
if (message.type === "output") {
|
|
107
|
+
pendingOutputRevision = message.revision;
|
|
108
|
+
outputCoalescer.handle(message.data);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Non-output messages (snapshot/snapshotReady/titleChange) must not jump
|
|
112
|
+
// ahead of buffered output: flush the coalescer first, then forward.
|
|
113
|
+
outputCoalescer.flush();
|
|
46
114
|
sendToParent({
|
|
47
115
|
type: "terminalMessage",
|
|
48
116
|
terminalId: session.id,
|
|
@@ -50,6 +118,7 @@ function watchTerminal(session) {
|
|
|
50
118
|
});
|
|
51
119
|
});
|
|
52
120
|
const unsubscribeExit = session.onExit((info) => {
|
|
121
|
+
outputCoalescer.flush();
|
|
53
122
|
clearTerminalSubscriptions(session.id);
|
|
54
123
|
sendToParent({
|
|
55
124
|
type: "terminalExit",
|
|
@@ -58,6 +127,7 @@ function watchTerminal(session) {
|
|
|
58
127
|
});
|
|
59
128
|
});
|
|
60
129
|
const unsubscribeTitle = session.onTitleChange((title) => {
|
|
130
|
+
outputCoalescer.flush();
|
|
61
131
|
sendToParent({
|
|
62
132
|
type: "terminalTitleChange",
|
|
63
133
|
terminalId: session.id,
|
|
@@ -65,56 +135,80 @@ function watchTerminal(session) {
|
|
|
65
135
|
});
|
|
66
136
|
});
|
|
67
137
|
const unsubscribeCommandFinished = session.onCommandFinished((info) => {
|
|
138
|
+
outputCoalescer.flush();
|
|
68
139
|
sendToParent({
|
|
69
140
|
type: "terminalCommandFinished",
|
|
70
141
|
terminalId: session.id,
|
|
71
142
|
info,
|
|
72
143
|
});
|
|
73
144
|
});
|
|
145
|
+
const unsubscribeActivity = session.onActivityChange((transition) => {
|
|
146
|
+
sendToParent({
|
|
147
|
+
type: "terminalActivityChange",
|
|
148
|
+
terminalId: session.id,
|
|
149
|
+
activity: transition.activity,
|
|
150
|
+
previous: transition.previous,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
74
153
|
unsubscribeByTerminalId.set(session.id, [
|
|
75
154
|
unsubscribeMessage,
|
|
76
155
|
unsubscribeExit,
|
|
77
156
|
unsubscribeTitle,
|
|
78
157
|
unsubscribeCommandFinished,
|
|
158
|
+
unsubscribeActivity,
|
|
79
159
|
]);
|
|
80
160
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
161
|
+
function enqueueCreateTerminalRequest(message) {
|
|
162
|
+
const nextRequest = createTerminalQueue.then(() => handleCreateTerminalRequest(message));
|
|
163
|
+
createTerminalQueue = nextRequest.catch(() => { });
|
|
164
|
+
return nextRequest;
|
|
165
|
+
}
|
|
166
|
+
async function handleCreateTerminalRequest(message) {
|
|
167
|
+
const request = {
|
|
168
|
+
requestId: message.requestId,
|
|
169
|
+
errorReported: false,
|
|
170
|
+
};
|
|
171
|
+
inFlightTerminalCreateRequest = request;
|
|
172
|
+
try {
|
|
173
|
+
const { workspaceId } = message.options;
|
|
174
|
+
if (!workspaceId) {
|
|
175
|
+
throw new Error("workspaceId is required");
|
|
176
|
+
}
|
|
177
|
+
const session = await manager.createTerminal({ ...message.options, workspaceId });
|
|
178
|
+
if (request.errorReported) {
|
|
179
|
+
session.kill();
|
|
98
180
|
return;
|
|
99
181
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
182
|
+
watchTerminal(session);
|
|
183
|
+
const initialSnapshot = session.getStateSnapshot();
|
|
184
|
+
sendToParent({
|
|
185
|
+
type: "terminalCreated",
|
|
186
|
+
terminal: toTerminalInfo(session),
|
|
187
|
+
state: initialSnapshot.state,
|
|
188
|
+
});
|
|
189
|
+
sendToParent({
|
|
190
|
+
type: "response",
|
|
191
|
+
requestId: message.requestId,
|
|
192
|
+
ok: true,
|
|
193
|
+
result: {
|
|
106
194
|
terminal: toTerminalInfo(session),
|
|
107
195
|
state: initialSnapshot.state,
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
reportInFlightTerminalCreateFailure(error);
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
if (inFlightTerminalCreateRequest === request) {
|
|
204
|
+
inFlightTerminalCreateRequest = null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async function handleRequest(message) {
|
|
209
|
+
switch (message.type) {
|
|
210
|
+
case "createTerminal": {
|
|
211
|
+
await enqueueCreateTerminalRequest(message);
|
|
118
212
|
return;
|
|
119
213
|
}
|
|
120
214
|
case "registerCwdEnv": {
|
|
@@ -122,52 +216,41 @@ async function handleRequest(message) {
|
|
|
122
216
|
sendToParent({ type: "response", requestId: message.requestId, ok: true });
|
|
123
217
|
return;
|
|
124
218
|
}
|
|
219
|
+
case "setActivity": {
|
|
220
|
+
await manager.setTerminalActivity(message.terminalId, message.state);
|
|
221
|
+
sendToParent({ type: "response", requestId: message.requestId, ok: true });
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
case "clearAttention": {
|
|
225
|
+
await manager.clearTerminalAttention(message.terminalId);
|
|
226
|
+
sendToParent({ type: "response", requestId: message.requestId, ok: true });
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
125
229
|
case "killTerminal": {
|
|
126
|
-
const session = manager.getTerminal(message.terminalId);
|
|
127
|
-
const cwd = session?.cwd;
|
|
128
230
|
manager.killTerminal(message.terminalId);
|
|
231
|
+
// Removal is owned by session.onExit -> terminalExit; the parent mirror
|
|
232
|
+
// clears contribution and emits terminalsChanged from that single path.
|
|
129
233
|
clearTerminalSubscriptions(message.terminalId);
|
|
130
|
-
if (cwd) {
|
|
131
|
-
sendToParent({
|
|
132
|
-
type: "terminalRemoved",
|
|
133
|
-
terminalId: message.terminalId,
|
|
134
|
-
cwd,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
234
|
sendToParent({ type: "response", requestId: message.requestId, ok: true });
|
|
138
235
|
return;
|
|
139
236
|
}
|
|
140
237
|
case "killTerminalAndWait": {
|
|
141
|
-
const session = manager.getTerminal(message.terminalId);
|
|
142
|
-
const cwd = session?.cwd;
|
|
143
238
|
await manager.killTerminalAndWait(message.terminalId, message.options);
|
|
144
239
|
clearTerminalSubscriptions(message.terminalId);
|
|
145
|
-
if (cwd) {
|
|
146
|
-
sendToParent({
|
|
147
|
-
type: "terminalRemoved",
|
|
148
|
-
terminalId: message.terminalId,
|
|
149
|
-
cwd,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
240
|
sendToParent({ type: "response", requestId: message.requestId, ok: true });
|
|
153
241
|
return;
|
|
154
242
|
}
|
|
155
243
|
case "getTerminalState": {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
result: session?.getStateSnapshot(message.options) ?? null,
|
|
162
|
-
});
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
case "listDirectories": {
|
|
244
|
+
// Flush buffered output before snapshotting: the headless state already includes it,
|
|
245
|
+
// so if the coalescer emitted it afterward (in a batch carrying a revision past the
|
|
246
|
+
// snapshot's) the controller's revision dedup wouldn't drop it and the client would
|
|
247
|
+
// see the bytes twice. Flushing first sends them with a revision <= the snapshot's.
|
|
248
|
+
outputCoalescerByTerminalId.get(message.terminalId)?.flush();
|
|
166
249
|
sendToParent({
|
|
167
250
|
type: "response",
|
|
168
251
|
requestId: message.requestId,
|
|
169
252
|
ok: true,
|
|
170
|
-
result: manager.
|
|
253
|
+
result: buildTerminalStateResult(manager.getTerminal(message.terminalId), message.options),
|
|
171
254
|
});
|
|
172
255
|
return;
|
|
173
256
|
}
|
|
@@ -210,7 +293,7 @@ process.on("message", (message) => {
|
|
|
210
293
|
type: "response",
|
|
211
294
|
requestId: message.requestId,
|
|
212
295
|
ok: false,
|
|
213
|
-
error: error
|
|
296
|
+
error: terminalWorkerErrorMessage(error),
|
|
214
297
|
});
|
|
215
298
|
});
|
|
216
299
|
});
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
import type { TerminalExitInfo, ServerMessage, ClientMessage, TerminalStateSnapshot, TerminalStateSnapshotOptions } from "./terminal.js";
|
|
2
2
|
import type { TerminalState } from "@getpaseo/protocol/messages";
|
|
3
|
+
import type { TerminalActivity, TerminalActivityState } from "@getpaseo/protocol/terminal-activity";
|
|
3
4
|
import type { CaptureTerminalLinesResult } from "./terminal-capture.js";
|
|
4
5
|
export interface WorkerTerminalInfo {
|
|
5
6
|
id: string;
|
|
6
7
|
name: string;
|
|
7
8
|
cwd: string;
|
|
9
|
+
workspaceId?: string;
|
|
8
10
|
title?: string;
|
|
11
|
+
activity: TerminalActivity | null;
|
|
9
12
|
}
|
|
10
13
|
export interface WorkerCreateTerminalOptions {
|
|
11
14
|
id?: string;
|
|
12
15
|
cwd: string;
|
|
16
|
+
workspaceId?: string;
|
|
13
17
|
name?: string;
|
|
14
18
|
title?: string;
|
|
15
19
|
env?: Record<string, string>;
|
|
16
20
|
command?: string;
|
|
17
21
|
args?: string[];
|
|
22
|
+
activityToken?: string;
|
|
23
|
+
activityUrl?: string | null;
|
|
18
24
|
}
|
|
19
25
|
export interface WorkerKillAndWaitOptions {
|
|
20
26
|
gracefulTimeoutMs?: number;
|
|
21
27
|
forceTimeoutMs?: number;
|
|
22
28
|
}
|
|
23
29
|
export type TerminalWorkerRequest = {
|
|
24
|
-
type: "getTerminals";
|
|
25
|
-
requestId: string;
|
|
26
|
-
cwd: string;
|
|
27
|
-
} | {
|
|
28
30
|
type: "createTerminal";
|
|
29
31
|
requestId: string;
|
|
30
32
|
options: WorkerCreateTerminalOptions;
|
|
@@ -33,6 +35,15 @@ export type TerminalWorkerRequest = {
|
|
|
33
35
|
requestId: string;
|
|
34
36
|
cwd: string;
|
|
35
37
|
env: Record<string, string>;
|
|
38
|
+
} | {
|
|
39
|
+
type: "setActivity";
|
|
40
|
+
requestId: string;
|
|
41
|
+
terminalId: string;
|
|
42
|
+
state: TerminalActivityState;
|
|
43
|
+
} | {
|
|
44
|
+
type: "clearAttention";
|
|
45
|
+
requestId: string;
|
|
46
|
+
terminalId: string;
|
|
36
47
|
} | {
|
|
37
48
|
type: "killTerminal";
|
|
38
49
|
requestId: string;
|
|
@@ -54,9 +65,6 @@ export type TerminalWorkerRequest = {
|
|
|
54
65
|
start?: number;
|
|
55
66
|
end?: number;
|
|
56
67
|
stripAnsi?: boolean;
|
|
57
|
-
} | {
|
|
58
|
-
type: "listDirectories";
|
|
59
|
-
requestId: string;
|
|
60
68
|
} | {
|
|
61
69
|
type: "killAll";
|
|
62
70
|
requestId: string;
|
|
@@ -81,10 +89,6 @@ export type TerminalWorkerEvent = {
|
|
|
81
89
|
type: "terminalCreated";
|
|
82
90
|
terminal: WorkerTerminalInfo;
|
|
83
91
|
state: TerminalState;
|
|
84
|
-
} | {
|
|
85
|
-
type: "terminalRemoved";
|
|
86
|
-
terminalId: string;
|
|
87
|
-
cwd: string;
|
|
88
92
|
} | {
|
|
89
93
|
type: "terminalMessage";
|
|
90
94
|
terminalId: string;
|
|
@@ -104,9 +108,10 @@ export type TerminalWorkerEvent = {
|
|
|
104
108
|
exitCode: number | null;
|
|
105
109
|
};
|
|
106
110
|
} | {
|
|
107
|
-
type: "
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
type: "terminalActivityChange";
|
|
112
|
+
terminalId: string;
|
|
113
|
+
activity: TerminalActivity | null;
|
|
114
|
+
previous: TerminalActivity | null;
|
|
110
115
|
};
|
|
111
116
|
export type TerminalWorkerToParentMessage = TerminalWorkerResponse | TerminalWorkerEvent;
|
|
112
117
|
export type TerminalWorkerCaptureResult = CaptureTerminalLinesResult;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TerminalState } from "@getpaseo/protocol/messages";
|
|
2
|
+
import type { TerminalActivity, TerminalActivityState } from "@getpaseo/protocol/terminal-activity";
|
|
2
3
|
export interface TerminalExitInfo {
|
|
3
4
|
exitCode: number | null;
|
|
4
5
|
signal: number | null;
|
|
@@ -10,6 +11,7 @@ export interface TerminalCommandFinishedInfo {
|
|
|
10
11
|
export interface TerminalStateSnapshot {
|
|
11
12
|
state: TerminalState;
|
|
12
13
|
revision: number;
|
|
14
|
+
replayPreamble?: string;
|
|
13
15
|
}
|
|
14
16
|
export interface TerminalStateSnapshotOptions {
|
|
15
17
|
scrollbackLines?: number;
|
|
@@ -43,19 +45,26 @@ export type ServerMessage = {
|
|
|
43
45
|
} | {
|
|
44
46
|
type: "snapshotReady";
|
|
45
47
|
revision?: number;
|
|
48
|
+
replayPreamble?: string;
|
|
46
49
|
} | {
|
|
47
50
|
type: "titleChange";
|
|
48
51
|
title?: string;
|
|
49
52
|
};
|
|
53
|
+
export interface TerminalActivityTransition {
|
|
54
|
+
activity: TerminalActivity | null;
|
|
55
|
+
previous: TerminalActivity | null;
|
|
56
|
+
}
|
|
50
57
|
export interface TerminalSession {
|
|
51
58
|
id: string;
|
|
52
59
|
name: string;
|
|
53
60
|
cwd: string;
|
|
61
|
+
workspaceId: string;
|
|
54
62
|
send(msg: ClientMessage): void;
|
|
55
63
|
subscribe(listener: (msg: ServerMessage) => void, options?: TerminalSubscribeOptions): () => void;
|
|
56
64
|
onExit(listener: (info: TerminalExitInfo) => void): () => void;
|
|
57
65
|
onCommandFinished(listener: (info: TerminalCommandFinishedInfo) => void): () => void;
|
|
58
66
|
onTitleChange(listener: (title?: string) => void): () => void;
|
|
67
|
+
onActivityChange(listener: (transition: TerminalActivityTransition) => void): () => void;
|
|
59
68
|
getSize(): {
|
|
60
69
|
rows: number;
|
|
61
70
|
cols: number;
|
|
@@ -64,6 +73,9 @@ export interface TerminalSession {
|
|
|
64
73
|
getStateSnapshot(options?: TerminalStateSnapshotOptions): TerminalStateSnapshot;
|
|
65
74
|
getReplayPreamble(): string;
|
|
66
75
|
getTitle(): string | undefined;
|
|
76
|
+
getActivity(): TerminalActivity | null;
|
|
77
|
+
setActivity(state: TerminalActivityState): void;
|
|
78
|
+
clearActivityAttention(): boolean;
|
|
67
79
|
setTitle(title: string): void;
|
|
68
80
|
getExitInfo(): TerminalExitInfo | null;
|
|
69
81
|
kill(): void;
|
|
@@ -75,8 +87,10 @@ export interface TerminalSession {
|
|
|
75
87
|
export interface CreateTerminalOptions {
|
|
76
88
|
id?: string;
|
|
77
89
|
cwd: string;
|
|
90
|
+
workspaceId: string;
|
|
78
91
|
shell?: string;
|
|
79
92
|
env?: Record<string, string>;
|
|
93
|
+
activityEnv?: Record<string, string>;
|
|
80
94
|
rows?: number;
|
|
81
95
|
cols?: number;
|
|
82
96
|
name?: string;
|
|
@@ -88,6 +102,8 @@ interface BuildTerminalEnvironmentInput {
|
|
|
88
102
|
shell: string;
|
|
89
103
|
env: Record<string, string>;
|
|
90
104
|
zshShellIntegrationDir?: string;
|
|
105
|
+
paseoCliBinDir?: string | null;
|
|
106
|
+
paseoHookCliPath?: string | null;
|
|
91
107
|
}
|
|
92
108
|
interface EnsureNodePtySpawnHelperExecutableOptions {
|
|
93
109
|
packageRoot?: string;
|
|
@@ -100,7 +116,33 @@ export declare function resolveDefaultTerminalShell(options?: {
|
|
|
100
116
|
platform?: NodeJS.Platform;
|
|
101
117
|
env?: NodeJS.ProcessEnv;
|
|
102
118
|
}): string;
|
|
119
|
+
export interface ResolvedTerminalCommand {
|
|
120
|
+
command: string;
|
|
121
|
+
args: string[];
|
|
122
|
+
}
|
|
123
|
+
export interface ResolveTerminalSpawnCommandOptions {
|
|
124
|
+
platform?: NodeJS.Platform;
|
|
125
|
+
env?: Record<string, string | undefined>;
|
|
126
|
+
resolveExecutable?: (name: string) => Promise<string | null>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Resolve a terminal profile command (e.g. `claude`) into something node-pty's
|
|
130
|
+
* conpty backend can actually launch on Windows.
|
|
131
|
+
*
|
|
132
|
+
* On Windows, conpty's underlying `CreateProcess` does not apply `PATHEXT`, so a
|
|
133
|
+
* bare `claude` (installed by npm as `claude.cmd`) fails with `error code: 2`
|
|
134
|
+
* (`ERROR_FILE_NOT_FOUND`). Worse, conpty completes the spawn asynchronously on
|
|
135
|
+
* its own conout worker thread, so that failure surfaces as an uncaught
|
|
136
|
+
* exception that takes down the whole terminal worker process. Resolving the
|
|
137
|
+
* real path up front — and routing `.cmd`/`.bat` shims through `cmd.exe /c`
|
|
138
|
+
* (node-pty has no `shell` option) — keeps the profile launchable.
|
|
139
|
+
*
|
|
140
|
+
* Non-Windows and the default-shell path (no explicit command) are unchanged.
|
|
141
|
+
*/
|
|
142
|
+
export declare function resolveTerminalSpawnCommand(command: string, args: string[], options?: ResolveTerminalSpawnCommandOptions): Promise<ResolvedTerminalCommand>;
|
|
103
143
|
export declare function resolveZshShellIntegrationDir(): string;
|
|
144
|
+
export declare function resolvePaseoCliBinDir(): string | null;
|
|
145
|
+
export declare function resolvePaseoCliExecutablePath(): string | null;
|
|
104
146
|
export declare function buildTerminalEnvironment(input: BuildTerminalEnvironmentInput): Record<string, string>;
|
|
105
147
|
export declare function normalizeProcessTitle(processTitle: string): string | undefined;
|
|
106
148
|
export declare function humanizeProcessTitle(processTitle: string): string | undefined;
|