@av-pi-studio/server 0.0.93 → 0.0.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent-manager.d.ts +8 -0
- package/dist/agent/agent-manager.js +11 -2
- package/dist/agent/agent-ui/agent-ui-rpc.d.ts +20 -0
- package/dist/agent/agent-ui/agent-ui-rpc.js +24 -0
- package/dist/agent/agent-ui/agent-ui-service.d.ts +55 -0
- package/dist/agent/agent-ui/agent-ui-service.js +237 -0
- package/dist/agent/mcp-server.d.ts +37 -6
- package/dist/agent/mcp-server.js +43 -6
- package/dist/agent/provider-contract.d.ts +29 -0
- package/dist/agent/providers/mock/mock-provider.d.ts +121 -2
- package/dist/agent/providers/mock/mock-provider.js +130 -1
- package/dist/agent/providers/mock/ui-script.d.ts +52 -0
- package/dist/agent/providers/mock/ui-script.js +224 -0
- package/dist/agent/providers/pi/agent.d.ts +1 -0
- package/dist/agent/providers/pi/agent.js +57 -9
- package/dist/daemon/bootstrap.js +18 -8
- package/dist/daemon/dev-bootstrap.d.ts +6 -0
- package/dist/daemon/dev-bootstrap.js +28 -14
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.js +4 -0
- package/dist/extensions/curated-packs.js +3 -0
- package/dist/terminal/screen-buffer.d.ts +13 -0
- package/dist/terminal/screen-buffer.js +38 -1
- package/dist/terminal/terminal-manager.d.ts +35 -6
- package/dist/terminal/terminal-manager.js +45 -11
- package/dist/terminal/terminal-rpc.d.ts +1 -1
- package/dist/terminal/terminal-rpc.js +43 -8
- package/package.json +5 -4
|
@@ -5,6 +5,13 @@ export function registerTerminalHandlers(registry, deps, getActiveSessions) {
|
|
|
5
5
|
// Per (session, slot) stream unsubscribers.
|
|
6
6
|
const streamUnsubs = new Map();
|
|
7
7
|
const key = (session, slot) => `${session.id}:${slot}`;
|
|
8
|
+
// A terminal exit — self-exit (`exit`, a crash) or `kill()` — always broadcasts the same
|
|
9
|
+
// `terminals_update` signal, unconditionally to every active session. This is the ONLY exit
|
|
10
|
+
// broadcast: `kill_terminal_request` below relies on it rather than sending its own, since
|
|
11
|
+
// `manager.kill()` invokes this listener synchronously and a second broadcast would duplicate it.
|
|
12
|
+
manager.onTerminalExit(() => {
|
|
13
|
+
deps.broadcast(getActiveSessions(), { type: "terminals_update", terminals: manager.list() });
|
|
14
|
+
});
|
|
8
15
|
registry.register("list_terminals_request", () => ({
|
|
9
16
|
type: "list_terminals_response",
|
|
10
17
|
terminals: manager.list(),
|
|
@@ -40,10 +47,15 @@ export function registerTerminalHandlers(registry, deps, getActiveSessions) {
|
|
|
40
47
|
const slot = Number(ctx.message.slot);
|
|
41
48
|
const session = ctx.session;
|
|
42
49
|
// Restore mode is honored only when the daemon advertises the feature AND the client advertised
|
|
43
|
-
// the reflowable-snapshot capability
|
|
50
|
+
// the reflowable-snapshot capability AND asked for it by name. The wire literal is exactly
|
|
51
|
+
// "reflowable" (sprint-053/task-004) — any other requested value (including a future/typo'd
|
|
52
|
+
// one) is served and echoed as "basic", so the response never names a tier that was not
|
|
53
|
+
// actually served.
|
|
44
54
|
const requestedMode = ctx.message.restoreMode;
|
|
45
55
|
const clientReflowable = session.supports("terminal_reflowable_snapshot");
|
|
46
|
-
const restoreMode = deps.restoreModesEnabled && clientReflowable
|
|
56
|
+
const restoreMode = deps.restoreModesEnabled && clientReflowable && requestedMode === "reflowable"
|
|
57
|
+
? "reflowable"
|
|
58
|
+
: "basic";
|
|
47
59
|
streamUnsubs.get(key(session, slot))?.(); // replace existing subscription
|
|
48
60
|
try {
|
|
49
61
|
// Resize BEFORE subscribing, using the grid the attaching client sent (if any).
|
|
@@ -62,9 +74,11 @@ export function registerTerminalHandlers(registry, deps, getActiveSessions) {
|
|
|
62
74
|
//
|
|
63
75
|
// Validation and the same-size no-op both live in `manager.resize` — the one choke point every
|
|
64
76
|
// size path funnels through — so this passes the raw values straight through rather than
|
|
65
|
-
// growing a second, drifting copy of those rules here.
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
// growing a second, drifting copy of those rules here. Broadcasts `terminals_update` when the
|
|
78
|
+
// grid actually changed (sprint-053/task-007), so an already-attached second client's stale
|
|
79
|
+
// belief gets corrected without it having to guess from a redundant `Resize` of its own.
|
|
80
|
+
resizeAndBroadcast(manager, deps.broadcast, getActiveSessions, slot, Number(ctx.message.cols), Number(ctx.message.rows));
|
|
81
|
+
const unsub = manager.subscribe(slot, (frame) => session.sendBinary(frame), { restoreMode });
|
|
68
82
|
streamUnsubs.set(key(session, slot), unsub);
|
|
69
83
|
// Echo the PTY's real size so the client can seed its belief instead of guessing. Without
|
|
70
84
|
// this a reattaching client cannot know what it is attaching to, and has to send a blind
|
|
@@ -100,7 +114,6 @@ export function registerTerminalHandlers(registry, deps, getActiveSessions) {
|
|
|
100
114
|
registry.register("kill_terminal_request", (ctx) => {
|
|
101
115
|
const slot = Number(ctx.message.slot);
|
|
102
116
|
const ok = manager.kill(slot);
|
|
103
|
-
deps.broadcast(getActiveSessions(), { type: "terminals_update", terminals: manager.list() });
|
|
104
117
|
return { type: "kill_terminal_response", slot, ok };
|
|
105
118
|
});
|
|
106
119
|
registry.register("capture_terminal_request", (ctx) => {
|
|
@@ -135,8 +148,30 @@ export function registerTerminalHandlers(registry, deps, getActiveSessions) {
|
|
|
135
148
|
};
|
|
136
149
|
});
|
|
137
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Apply a resize and broadcast the refreshed inventory to every active session, but only when the
|
|
153
|
+
* grid actually changed (sprint-053/task-007). An unknown slot, an invalid grid, and a same-size
|
|
154
|
+
* no-op must all stay silent — the binary `Resize` frame path is the hot path of every coalesced
|
|
155
|
+
* pane-divider drag, and a broadcast per intermediate frame would defeat that coalescing.
|
|
156
|
+
*
|
|
157
|
+
* Compares `TerminalManager.get(slot)` before and after rather than trusting `resize`'s boolean
|
|
158
|
+
* return (which is `true` for both an applied change and a same-size no-op) — `get` returns the
|
|
159
|
+
* live entry object, which `resize` mutates in place, so the cols/rows are captured into locals
|
|
160
|
+
* before the call rather than held as a stale reference to the same object.
|
|
161
|
+
*/
|
|
162
|
+
function resizeAndBroadcast(manager, broadcast, getActiveSessions, slot, cols, rows) {
|
|
163
|
+
const before = manager.get(slot);
|
|
164
|
+
const beforeCols = before?.cols;
|
|
165
|
+
const beforeRows = before?.rows;
|
|
166
|
+
if (!manager.resize(slot, cols, rows))
|
|
167
|
+
return;
|
|
168
|
+
const after = manager.get(slot);
|
|
169
|
+
if (after && (after.cols !== beforeCols || after.rows !== beforeRows)) {
|
|
170
|
+
broadcast(getActiveSessions(), { type: "terminals_update", terminals: manager.list() });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
138
173
|
/** Binary terminal-input frame handler for the frame dispatcher (Input/Resize opcodes). */
|
|
139
|
-
export function makeTerminalBinaryHandler(manager) {
|
|
174
|
+
export function makeTerminalBinaryHandler(manager, broadcast, getActiveSessions) {
|
|
140
175
|
return (_session, bytes) => {
|
|
141
176
|
const frame = tryDecodeTerminalFrame(bytes);
|
|
142
177
|
if (!frame)
|
|
@@ -144,7 +179,7 @@ export function makeTerminalBinaryHandler(manager) {
|
|
|
144
179
|
if (frame.opcode === "Input")
|
|
145
180
|
manager.input(frame.slot, frame.data);
|
|
146
181
|
else if (frame.opcode === "Resize")
|
|
147
|
-
manager
|
|
182
|
+
resizeAndBroadcast(manager, broadcast, getActiveSessions, frame.slot, frame.cols, frame.rows);
|
|
148
183
|
};
|
|
149
184
|
}
|
|
150
185
|
//# sourceMappingURL=terminal-rpc.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@av-pi-studio/server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.95",
|
|
4
4
|
"bin": {
|
|
5
5
|
"pi-studio-daemon": "dist/daemon/main.js"
|
|
6
6
|
},
|
|
@@ -24,10 +24,11 @@
|
|
|
24
24
|
"clean": "rm -rf dist *.tsbuildinfo"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@av-pi-studio/highlight": "^0.0.
|
|
28
|
-
"@av-pi-studio/protocol": "^0.0.
|
|
29
|
-
"@av-pi-studio/relay": "^0.0.
|
|
27
|
+
"@av-pi-studio/highlight": "^0.0.95",
|
|
28
|
+
"@av-pi-studio/protocol": "^0.0.95",
|
|
29
|
+
"@av-pi-studio/relay": "^0.0.95",
|
|
30
30
|
"@earendil-works/pi-coding-agent": "^0.84.1",
|
|
31
|
+
"@xterm/addon-serialize": "^0.14.0",
|
|
31
32
|
"@xterm/headless": "^6.0.0",
|
|
32
33
|
"bcryptjs": "^3.0.3",
|
|
33
34
|
"lru-cache": "^11.5.1",
|