@provos/ironcurtain 0.12.0 → 0.13.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.
Files changed (211) hide show
  1. package/README.md +14 -12
  2. package/dist/cli.js +6 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config/config-command.d.ts +33 -1
  5. package/dist/config/config-command.js +608 -11
  6. package/dist/config/config-command.js.map +1 -1
  7. package/dist/config/openrouter-catalog.d.ts +46 -0
  8. package/dist/config/openrouter-catalog.js +111 -0
  9. package/dist/config/openrouter-catalog.js.map +1 -0
  10. package/dist/config/openrouter-models-fallback.d.ts +15 -0
  11. package/dist/config/openrouter-models-fallback.js +49 -0
  12. package/dist/config/openrouter-models-fallback.js.map +1 -0
  13. package/dist/config/types.d.ts +8 -0
  14. package/dist/config/user-config.d.ts +133 -7
  15. package/dist/config/user-config.js +234 -5
  16. package/dist/config/user-config.js.map +1 -1
  17. package/dist/daemon/daemon-command.js.map +1 -1
  18. package/dist/daemon/ironcurtain-daemon.js +6 -0
  19. package/dist/daemon/ironcurtain-daemon.js.map +1 -1
  20. package/dist/docker/adapters/claude-code.js +109 -1
  21. package/dist/docker/adapters/claude-code.js.map +1 -1
  22. package/dist/docker/adapters/codex.d.ts +10 -1
  23. package/dist/docker/adapters/codex.js +99 -20
  24. package/dist/docker/adapters/codex.js.map +1 -1
  25. package/dist/docker/adapters/goose.js +38 -2
  26. package/dist/docker/adapters/goose.js.map +1 -1
  27. package/dist/docker/agent-adapter.d.ts +29 -5
  28. package/dist/docker/agent-registry.js +1 -1
  29. package/dist/docker/agent-registry.js.map +1 -1
  30. package/dist/docker/apple-container-manager.d.ts +4 -4
  31. package/dist/docker/apple-container-manager.js +44 -22
  32. package/dist/docker/apple-container-manager.js.map +1 -1
  33. package/dist/docker/ca.js +9 -2
  34. package/dist/docker/ca.js.map +1 -1
  35. package/dist/docker/container-lifecycle.js +9 -0
  36. package/dist/docker/container-lifecycle.js.map +1 -1
  37. package/dist/docker/docker-agent-session.d.ts +31 -0
  38. package/dist/docker/docker-agent-session.js +67 -6
  39. package/dist/docker/docker-agent-session.js.map +1 -1
  40. package/dist/docker/docker-infrastructure.d.ts +55 -15
  41. package/dist/docker/docker-infrastructure.js +261 -61
  42. package/dist/docker/docker-infrastructure.js.map +1 -1
  43. package/dist/docker/docker-manager.js +127 -0
  44. package/dist/docker/docker-manager.js.map +1 -1
  45. package/dist/docker/docker-resource-lifecycle.d.ts +71 -0
  46. package/dist/docker/docker-resource-lifecycle.js +454 -0
  47. package/dist/docker/docker-resource-lifecycle.js.map +1 -0
  48. package/dist/docker/gc-command.d.ts +2 -0
  49. package/dist/docker/gc-command.js +37 -0
  50. package/dist/docker/gc-command.js.map +1 -0
  51. package/dist/docker/mitm-proxy.d.ts +6 -4
  52. package/dist/docker/mitm-proxy.js +105 -17
  53. package/dist/docker/mitm-proxy.js.map +1 -1
  54. package/dist/docker/network-topology.d.ts +16 -9
  55. package/dist/docker/network-topology.js +17 -10
  56. package/dist/docker/network-topology.js.map +1 -1
  57. package/dist/docker/openrouter.d.ts +107 -0
  58. package/dist/docker/openrouter.js +236 -0
  59. package/dist/docker/openrouter.js.map +1 -0
  60. package/dist/docker/orientation.js +1 -1
  61. package/dist/docker/orientation.js.map +1 -1
  62. package/dist/docker/platform.d.ts +3 -1
  63. package/dist/docker/platform.js +3 -1
  64. package/dist/docker/platform.js.map +1 -1
  65. package/dist/docker/provider-config.d.ts +6 -0
  66. package/dist/docker/provider-config.js.map +1 -1
  67. package/dist/docker/pty-session.d.ts +7 -0
  68. package/dist/docker/pty-session.js +111 -29
  69. package/dist/docker/pty-session.js.map +1 -1
  70. package/dist/docker/pty-types.d.ts +15 -0
  71. package/dist/docker/pty-types.js +8 -0
  72. package/dist/docker/pty-types.js.map +1 -1
  73. package/dist/docker/sse-extractor.js +55 -5
  74. package/dist/docker/sse-extractor.js.map +1 -1
  75. package/dist/docker/stream-delay.d.ts +86 -0
  76. package/dist/docker/stream-delay.js +218 -0
  77. package/dist/docker/stream-delay.js.map +1 -0
  78. package/dist/docker/token-stream-types.d.ts +15 -0
  79. package/dist/docker/trajectory-reassembler.d.ts +2 -2
  80. package/dist/docker/trajectory-reassembler.js +22 -2
  81. package/dist/docker/trajectory-reassembler.js.map +1 -1
  82. package/dist/docker/trajectory-tap.js +2 -2
  83. package/dist/docker/trajectory-tap.js.map +1 -1
  84. package/dist/docker/types.d.ts +63 -5
  85. package/dist/doctor/checks.d.ts +3 -3
  86. package/dist/doctor/checks.js +28 -11
  87. package/dist/doctor/checks.js.map +1 -1
  88. package/dist/doctor/doctor-command.js +1 -1
  89. package/dist/doctor/doctor-command.js.map +1 -1
  90. package/dist/escalation/escalation-watcher.js +6 -0
  91. package/dist/escalation/escalation-watcher.js.map +1 -1
  92. package/dist/{mux → escalation}/trusted-input.d.ts +7 -4
  93. package/dist/{mux → escalation}/trusted-input.js +8 -5
  94. package/dist/escalation/trusted-input.js.map +1 -0
  95. package/dist/hash.js.map +1 -1
  96. package/dist/index.js +37 -6
  97. package/dist/index.js.map +1 -1
  98. package/dist/mux/mux-app.d.ts +7 -0
  99. package/dist/mux/mux-app.js +17 -16
  100. package/dist/mux/mux-app.js.map +1 -1
  101. package/dist/mux/mux-command.js +8 -3
  102. package/dist/mux/mux-command.js.map +1 -1
  103. package/dist/mux/mux-input-handler.d.ts +26 -2
  104. package/dist/mux/mux-input-handler.js +93 -11
  105. package/dist/mux/mux-input-handler.js.map +1 -1
  106. package/dist/mux/mux-renderer.d.ts +2 -1
  107. package/dist/mux/mux-renderer.js +67 -0
  108. package/dist/mux/mux-renderer.js.map +1 -1
  109. package/dist/mux/provider-profile-snapshot.d.ts +44 -0
  110. package/dist/mux/provider-profile-snapshot.js +56 -0
  111. package/dist/mux/provider-profile-snapshot.js.map +1 -0
  112. package/dist/mux/types.d.ts +3 -2
  113. package/dist/mux/types.js +6 -2
  114. package/dist/mux/types.js.map +1 -1
  115. package/dist/observe/observe-command.js.map +1 -1
  116. package/dist/pipeline/constitution-compiler.js.map +1 -1
  117. package/dist/pipeline/generate-with-repair.js.map +1 -1
  118. package/dist/pipeline/refresh-lists.js.map +1 -1
  119. package/dist/pipeline/scenario-schema-validator.js.map +1 -1
  120. package/dist/{mux → pty}/pty-bridge.d.ts +39 -3
  121. package/dist/{mux → pty}/pty-bridge.js +68 -18
  122. package/dist/pty/pty-bridge.js.map +1 -0
  123. package/dist/pty/resolve-ironcurtain-bin.d.ts +17 -0
  124. package/dist/pty/resolve-ironcurtain-bin.js +22 -0
  125. package/dist/pty/resolve-ironcurtain-bin.js.map +1 -0
  126. package/dist/servers/fetch-server.js +2 -0
  127. package/dist/servers/fetch-server.js.map +1 -1
  128. package/dist/session/index.d.ts +1 -1
  129. package/dist/session/index.js +11 -2
  130. package/dist/session/index.js.map +1 -1
  131. package/dist/session/preflight.d.ts +19 -5
  132. package/dist/session/preflight.js +41 -25
  133. package/dist/session/preflight.js.map +1 -1
  134. package/dist/session/resource-budget-tracker.js +8 -0
  135. package/dist/session/resource-budget-tracker.js.map +1 -1
  136. package/dist/session/session-manager.d.ts +7 -0
  137. package/dist/session/session-manager.js.map +1 -1
  138. package/dist/session/types.d.ts +14 -0
  139. package/dist/signal/signal-bot-daemon.d.ts +1 -0
  140. package/dist/signal/signal-bot-daemon.js +9 -2
  141. package/dist/signal/signal-bot-daemon.js.map +1 -1
  142. package/dist/trusted-process/mcp-error-utils.js +4 -1
  143. package/dist/trusted-process/mcp-error-utils.js.map +1 -1
  144. package/dist/trusted-process/mcp-proxy-server.js +2 -0
  145. package/dist/trusted-process/mcp-proxy-server.js.map +1 -1
  146. package/dist/trusted-process/policy-engine.js.map +1 -1
  147. package/dist/trusted-process/tcp-server-transport.d.ts +7 -0
  148. package/dist/trusted-process/tcp-server-transport.js +48 -10
  149. package/dist/trusted-process/tcp-server-transport.js.map +1 -1
  150. package/dist/utils/preflight-checks.js +1 -3
  151. package/dist/utils/preflight-checks.js.map +1 -1
  152. package/dist/utils/stdio-guard.d.ts +1 -0
  153. package/dist/utils/stdio-guard.js +27 -0
  154. package/dist/utils/stdio-guard.js.map +1 -0
  155. package/dist/web-ui/__tests__/config-dispatch.test.d.ts +13 -0
  156. package/dist/web-ui/__tests__/config-dispatch.test.js +383 -0
  157. package/dist/web-ui/__tests__/config-dispatch.test.js.map +1 -0
  158. package/dist/web-ui/__tests__/json-rpc-dispatch.test.js +6 -0
  159. package/dist/web-ui/__tests__/json-rpc-dispatch.test.js.map +1 -1
  160. package/dist/web-ui/dispatch/config-dispatch.d.ts +15 -0
  161. package/dist/web-ui/dispatch/config-dispatch.js +277 -0
  162. package/dist/web-ui/dispatch/config-dispatch.js.map +1 -0
  163. package/dist/web-ui/dispatch/escalation-dispatch.js +11 -2
  164. package/dist/web-ui/dispatch/escalation-dispatch.js.map +1 -1
  165. package/dist/web-ui/dispatch/pty-dispatch.d.ts +15 -0
  166. package/dist/web-ui/dispatch/pty-dispatch.js +66 -0
  167. package/dist/web-ui/dispatch/pty-dispatch.js.map +1 -0
  168. package/dist/web-ui/dispatch/session-dispatch.js +69 -4
  169. package/dist/web-ui/dispatch/session-dispatch.js.map +1 -1
  170. package/dist/web-ui/dispatch/types.d.ts +12 -0
  171. package/dist/web-ui/dispatch/types.js +38 -1
  172. package/dist/web-ui/dispatch/types.js.map +1 -1
  173. package/dist/web-ui/dispatch/workflow-dispatch.js.map +1 -1
  174. package/dist/web-ui/json-rpc-dispatch.js +3 -0
  175. package/dist/web-ui/json-rpc-dispatch.js.map +1 -1
  176. package/dist/web-ui/pty-session-manager.d.ts +234 -0
  177. package/dist/web-ui/pty-session-manager.js +599 -0
  178. package/dist/web-ui/pty-session-manager.js.map +1 -0
  179. package/dist/web-ui/web-event-bus.d.ts +9 -0
  180. package/dist/web-ui/web-event-bus.js.map +1 -1
  181. package/dist/web-ui/web-session-transport.js.map +1 -1
  182. package/dist/web-ui/web-ui-server.d.ts +8 -0
  183. package/dist/web-ui/web-ui-server.js +25 -0
  184. package/dist/web-ui/web-ui-server.js.map +1 -1
  185. package/dist/web-ui/web-ui-types.d.ts +80 -1
  186. package/dist/web-ui/web-ui-types.js.map +1 -1
  187. package/dist/web-ui-static/assets/index-CCVI4nEK.css +1 -0
  188. package/dist/web-ui-static/assets/index-Dm012gvY.js +114 -0
  189. package/dist/web-ui-static/index.html +2 -2
  190. package/dist/workflow/daemon-gate-commands.js +38 -42
  191. package/dist/workflow/daemon-gate-commands.js.map +1 -1
  192. package/dist/workflow/machine-builder.js.map +1 -1
  193. package/dist/workflow/orchestrator.js +10 -7
  194. package/dist/workflow/orchestrator.js.map +1 -1
  195. package/dist/workflow/shutdown-signals.d.ts +7 -0
  196. package/dist/workflow/shutdown-signals.js +40 -0
  197. package/dist/workflow/shutdown-signals.js.map +1 -0
  198. package/dist/workflow/validate.js.map +1 -1
  199. package/dist/workflow/workflow-command.js +10 -8
  200. package/dist/workflow/workflow-command.js.map +1 -1
  201. package/dist/workflow/workflows/evolve/README.md +66 -0
  202. package/dist/workflow/workflows/vuln-discovery/README.md +54 -0
  203. package/docker/entrypoint-claude-code.sh +22 -0
  204. package/package.json +31 -27
  205. package/src/workflow/workflows/evolve/README.md +66 -0
  206. package/src/workflow/workflows/vuln-discovery/README.md +54 -0
  207. package/dist/mux/pty-bridge.js.map +0 -1
  208. package/dist/mux/trusted-input.js.map +0 -1
  209. package/dist/web-ui-static/assets/index-BD5U6ILh.css +0 -1
  210. package/dist/web-ui-static/assets/index-FMsHWEfK.js +0 -79
  211. package/packages/web-ui/README.md +0 -113
@@ -0,0 +1,599 @@
1
+ /**
2
+ * PtySessionManager -- owns the daemon-side lifecycle of Docker-agent PTY
3
+ * sessions streamed to the web UI as live terminals.
4
+ *
5
+ * Each managed session ({@link PtyWebSession}) wraps one {@link PtyBridge}
6
+ * (a spawned `ironcurtain start --pty` child) and fans its terminal output out
7
+ * to a set of subscribed WebSocket clients as coalesced, base64-encoded
8
+ * `session.pty_output` deltas, with a one-shot `session.pty_replay` snapshot on
9
+ * attach/resync. This mirrors the TokenStreamBridge targeted-delivery pattern
10
+ * (per-client subscribe + `removeAllForClient`); the two are independent.
11
+ *
12
+ * PTY sessions are a distinct session kind. They are NOT `ManagedSession`s (they
13
+ * have no Session/Transport); they only borrow a label via
14
+ * `sessionManager.reserveLabel()`. Lifecycle: created via `sessions.create` in
15
+ * docker mode, reaped on explicit `sessions.end`, on child exit, on an idle-TTL
16
+ * backstop ({@link PTY_IDLE_TTL_MS}), or on daemon shutdown (`close()`).
17
+ *
18
+ * Escalation bridging (Phase 4): once `bridge.onSessionDiscovered` yields an
19
+ * `escalationDir`, an {@link EscalationWatcher} (the same file-watch primitive
20
+ * mux uses) is started for the session. Detected requests are re-emitted as
21
+ * `escalation.created` DTOs (`sessionSource: { kind: 'web-pty' }`) onto the
22
+ * {@link WebEventBus}, so the existing structured Escalations UI works on top
23
+ * of the terminal. `resolveEscalation` writes the response file and emits
24
+ * `escalation.resolved` so the UI clears the card.
25
+ */
26
+ import { createPtyBridge } from '../pty/pty-bridge.js';
27
+ import { resolveIroncurtainBin } from '../pty/resolve-ironcurtain-bin.js';
28
+ import { createEscalationWatcher } from '../escalation/escalation-watcher.js';
29
+ import { writeTrustedUserContext } from '../escalation/trusted-input.js';
30
+ import { RpcError, SessionNotFoundError } from './web-ui-types.js';
31
+ import * as logger from '../logger.js';
32
+ // Runtime edge is one-directional (this module -> dispatch/types.ts); the
33
+ // back-reference from types.ts to PtyWebSession/PtySessionManager is type-only.
34
+ import { toPtySessionDto } from './dispatch/types.js';
35
+ // ---------------------------------------------------------------------------
36
+ // Constants (hard-coded per design §6/§11 -- no config schema for v1)
37
+ // ---------------------------------------------------------------------------
38
+ /**
39
+ * Idle-TTL leak backstop: a PTY session with no subscribers for this long is
40
+ * reaped (kills the child + container). Generous by design so a browser reload,
41
+ * laptop sleep, or wifi blip does not kill a working agent. Set to `0` to
42
+ * disable (local testing). Not a config knob for v1 (§6).
43
+ */
44
+ export const PTY_IDLE_TTL_MS = 30 * 60 * 1000;
45
+ /** Initial PTY size; the first attaching browser re-sizes via ptyResize (§11 D1). */
46
+ const PTY_INITIAL_COLS = 80;
47
+ const PTY_INITIAL_ROWS = 24;
48
+ /** Output coalescing: flush accumulated onData on this timer or at the byte cap. */
49
+ const PTY_COALESCE_MS = 16;
50
+ /**
51
+ * Drain-poll interval while a client is backpressured: coarser than the 16ms
52
+ * coalesce timer so a slow/backgrounded client does not cause 60+ daemon
53
+ * wakeups/sec just to poll `bufferedAmount`. New output still reaches healthy
54
+ * clients at the coalesce cadence because `scheduleFlush` lets a shorter request
55
+ * preempt this longer poll.
56
+ */
57
+ const PTY_DRAIN_POLL_MS = 150;
58
+ const PTY_COALESCE_MAX_BYTES = 32 * 1024;
59
+ /** Backpressure threshold: above this `bufferedAmount`, skip deltas + resync on drain. */
60
+ const PTY_BACKPRESSURE_BYTES = 4 * 1024 * 1024;
61
+ /** Replayed scrollback tail cap (§11 Q2): keeps a pty_replay frame under maxPayload. */
62
+ const PTY_REPLAY_SCROLLBACK = 1000;
63
+ /** Bounded await for child exits on daemon shutdown (mirrors mux doShutdown). */
64
+ const PTY_CLOSE_TIMEOUT_MS = 5000;
65
+ /**
66
+ * Delay before the injected Enter (`\r`) on a trusted message, so Claude Code's
67
+ * Ink UI processes the text and the submit as distinct input events. A single
68
+ * `text\r` write can arrive as one chunk and Ink may not trigger Enter (mux
69
+ * parity -- see mux-app.ts).
70
+ */
71
+ const PTY_ENTER_DELAY_MS = 50;
72
+ // ---------------------------------------------------------------------------
73
+ // Encoding + collaborator seams
74
+ // ---------------------------------------------------------------------------
75
+ /** Terminal bytes are carried over the (JSON-text) WS as base64. */
76
+ function encodeBytes(text) {
77
+ return Buffer.from(text, 'utf8').toString('base64');
78
+ }
79
+ function decodeBytes(b64) {
80
+ return Buffer.from(b64, 'base64').toString('utf8');
81
+ }
82
+ /**
83
+ * Builds the `EscalationDto` the web UI consumes from a raw `EscalationRequest`,
84
+ * tagged as a PTY session. Mirrors `WebSessionTransport.createEscalationHandler`'s
85
+ * DTO shape exactly (the frontend Escalations UI is shared), differing only in
86
+ * the `sessionSource` discriminant.
87
+ */
88
+ function buildPtyEscalationDto(request, label) {
89
+ return {
90
+ escalationId: request.escalationId,
91
+ sessionLabel: label,
92
+ sessionSource: { kind: 'web-pty' },
93
+ toolName: request.toolName,
94
+ serverName: request.serverName,
95
+ arguments: request.arguments,
96
+ reason: request.reason,
97
+ context: request.context,
98
+ whitelistCandidates: request.whitelistCandidates,
99
+ receivedAt: new Date().toISOString(),
100
+ };
101
+ }
102
+ /**
103
+ * Thrown by `create()` when the PTY runtime is unavailable (node-pty fails to
104
+ * load, or the serialize addon is missing). Surfaced as a clean RPC error so a
105
+ * builtin-only / broken host degrades instead of crashing the daemon (§11 D1).
106
+ */
107
+ export class PtyUnavailableError extends RpcError {
108
+ constructor(detail) {
109
+ super('INTERNAL_ERROR', `PTY terminal unavailable: ${detail}`);
110
+ this.name = 'PtyUnavailableError';
111
+ }
112
+ }
113
+ // ---------------------------------------------------------------------------
114
+ // PtyWebSession -- one bridge + its subscriber set + the coalescing streamer
115
+ // ---------------------------------------------------------------------------
116
+ export class PtyWebSession {
117
+ label;
118
+ bridge;
119
+ sender;
120
+ persona;
121
+ /** Discovered escalation dir; the {@link escalationWatcher} polls it. */
122
+ escalationDir;
123
+ /** Watcher over {@link escalationDir}; set by the manager once discovered. */
124
+ escalationWatcher = null;
125
+ /** ISO timestamp of the most recent browser attach (surfaced in the DTO). */
126
+ lastAttachedAt = null;
127
+ createdAt = new Date().toISOString();
128
+ /** Escalation DTOs currently pending for this session, keyed by id. */
129
+ pendingEscalations = new Map();
130
+ subscribers = new Set();
131
+ /** Clients skipped due to backpressure; resynced with a fresh snapshot on drain. */
132
+ desynced = new Set();
133
+ buffer = '';
134
+ bufferBytes = 0;
135
+ flushTimer = null;
136
+ /** Delay (ms) of the pending flush timer, so a shorter request can preempt a longer one. */
137
+ flushTimerDelay = PTY_COALESCE_MS;
138
+ constructor(label, bridge, sender, persona) {
139
+ this.label = label;
140
+ this.bridge = bridge;
141
+ this.sender = sender;
142
+ this.persona = persona;
143
+ }
144
+ get alive() {
145
+ return this.bridge.alive;
146
+ }
147
+ get subscriberCount() {
148
+ return this.subscribers.size;
149
+ }
150
+ hasSubscribers() {
151
+ return this.subscribers.size > 0;
152
+ }
153
+ /**
154
+ * Attaches one client: drains any coalesced output to the existing
155
+ * subscribers, sends this client a fresh full-screen snapshot, then
156
+ * subscribes it. Draining first makes the snapshot the single source of
157
+ * truth so a still-buffered chunk is never re-delivered to the new client
158
+ * after it subscribes (closes the replay/subscribe overlap; the bridge's
159
+ * post-write onData ordering invariant closes the serialize/subscribe race).
160
+ */
161
+ attach(client) {
162
+ this.flushNow();
163
+ this.sendReplay(client);
164
+ this.subscribers.add(client);
165
+ this.lastAttachedAt = new Date().toISOString();
166
+ }
167
+ /** Removes a client from the subscriber + desync sets. */
168
+ removeSubscriber(client) {
169
+ this.subscribers.delete(client);
170
+ this.desynced.delete(client);
171
+ }
172
+ /** Wired to `bridge.onData`: accumulate + flush on timer or at the byte cap. */
173
+ pushChunk(chunk) {
174
+ this.buffer += chunk;
175
+ this.bufferBytes += Buffer.byteLength(chunk, 'utf8');
176
+ if (this.bufferBytes >= PTY_COALESCE_MAX_BYTES) {
177
+ this.flushNow();
178
+ }
179
+ else {
180
+ this.scheduleFlush();
181
+ }
182
+ }
183
+ // --- Escalation state (Phase 4) ---
184
+ /** Records a newly detected escalation's DTO. */
185
+ addPendingEscalation(dto) {
186
+ this.pendingEscalations.set(dto.escalationId, dto);
187
+ }
188
+ /** Drops a pending escalation (resolved or expired). */
189
+ removePendingEscalation(escalationId) {
190
+ this.pendingEscalations.delete(escalationId);
191
+ }
192
+ hasEscalation(escalationId) {
193
+ return this.pendingEscalations.has(escalationId);
194
+ }
195
+ listEscalationDtos() {
196
+ return [...this.pendingEscalations.values()];
197
+ }
198
+ /**
199
+ * Resolves a pending escalation by writing the response file via the watcher,
200
+ * then drops it from the pending map. Returns whether the response was
201
+ * accepted (false if the request had already expired). Emitting
202
+ * `escalation.resolved` is the manager's responsibility.
203
+ */
204
+ resolveEscalation(escalationId, decision, options) {
205
+ const accepted = this.escalationWatcher?.resolve(escalationId, decision, options) ?? false;
206
+ this.pendingEscalations.delete(escalationId);
207
+ return accepted;
208
+ }
209
+ /** Clears timers + buffered state; leaves subscriber routing to the manager. */
210
+ dispose() {
211
+ if (this.flushTimer) {
212
+ clearTimeout(this.flushTimer);
213
+ this.flushTimer = null;
214
+ }
215
+ this.escalationWatcher?.stop();
216
+ this.escalationWatcher = null;
217
+ this.pendingEscalations.clear();
218
+ this.subscribers.clear();
219
+ this.desynced.clear();
220
+ this.buffer = '';
221
+ this.bufferBytes = 0;
222
+ }
223
+ scheduleFlush(delayMs = PTY_COALESCE_MS) {
224
+ // A shorter request (new output at the coalesce cadence) preempts a pending
225
+ // longer one (the backpressure drain poll), so healthy clients never wait
226
+ // the coarse interval for output while another client is backpressured.
227
+ if (this.flushTimer) {
228
+ if (delayMs >= this.flushTimerDelay)
229
+ return;
230
+ clearTimeout(this.flushTimer);
231
+ }
232
+ this.flushTimerDelay = delayMs;
233
+ this.flushTimer = setTimeout(() => {
234
+ this.flushTimer = null;
235
+ this.flushNow();
236
+ }, delayMs);
237
+ }
238
+ /**
239
+ * Flushes the coalesced buffer to healthy subscribers, then resyncs any
240
+ * backpressured client that has since drained. A resync sends a full snapshot
241
+ * (which already reflects the drained delta via the onData ordering
242
+ * invariant), so a just-resynced client is intentionally excluded from the
243
+ * same cycle's delta to avoid a double-render.
244
+ */
245
+ flushNow() {
246
+ if (this.flushTimer) {
247
+ clearTimeout(this.flushTimer);
248
+ this.flushTimer = null;
249
+ }
250
+ const data = this.buffer;
251
+ this.buffer = '';
252
+ this.bufferBytes = 0;
253
+ if (data.length > 0) {
254
+ const recipients = new Set();
255
+ for (const client of this.subscribers) {
256
+ if (this.desynced.has(client))
257
+ continue;
258
+ if (client.bufferedAmount > PTY_BACKPRESSURE_BYTES) {
259
+ this.desynced.add(client);
260
+ continue;
261
+ }
262
+ recipients.add(client);
263
+ }
264
+ if (recipients.size > 0) {
265
+ this.sender.sendToSubscribers(recipients, 'session.pty_output', {
266
+ label: this.label,
267
+ data: encodeBytes(data),
268
+ });
269
+ }
270
+ }
271
+ for (const client of [...this.desynced]) {
272
+ if (client.bufferedAmount <= PTY_BACKPRESSURE_BYTES)
273
+ this.sendReplay(client);
274
+ }
275
+ // Keep polling for drain while any client is still backpressured, at the
276
+ // coarser drain interval (a fresh output burst preempts it back to 16ms).
277
+ if (this.desynced.size > 0)
278
+ this.scheduleFlush(PTY_DRAIN_POLL_MS);
279
+ }
280
+ /** Sends a one-shot full-screen snapshot; clears the client's desync flag. */
281
+ sendReplay(client) {
282
+ this.desynced.delete(client);
283
+ const snapshot = encodeBytes(this.bridge.serialize({ scrollback: PTY_REPLAY_SCROLLBACK }));
284
+ this.sender.sendToSubscribers(new Set([client]), 'session.pty_replay', {
285
+ label: this.label,
286
+ snapshot,
287
+ });
288
+ }
289
+ }
290
+ // ---------------------------------------------------------------------------
291
+ // PtySessionManager
292
+ // ---------------------------------------------------------------------------
293
+ export class PtySessionManager {
294
+ sessions = new Map();
295
+ idleTimers = new Map();
296
+ sender;
297
+ sessionManager;
298
+ eventBus;
299
+ mode;
300
+ ownerId;
301
+ ownerPid;
302
+ captureTracesDefault;
303
+ createBridge;
304
+ runPreflight;
305
+ idleTtlMs;
306
+ preflightPromise;
307
+ constructor(options) {
308
+ this.sender = options.sender;
309
+ this.sessionManager = options.sessionManager;
310
+ this.eventBus = options.eventBus;
311
+ this.mode = options.mode;
312
+ this.ownerId = `webui-${options.daemonId}`;
313
+ this.ownerPid = options.daemonPid;
314
+ this.captureTracesDefault = options.captureTracesDefault ?? false;
315
+ this.createBridge = options.createBridge ?? createPtyBridge;
316
+ this.runPreflight = options.preflight ?? defaultPreflight;
317
+ this.idleTtlMs = options.idleTtlMs ?? PTY_IDLE_TTL_MS;
318
+ }
319
+ /** Number of live PTY sessions (for the status DTO + create cap, §11 D4). */
320
+ get size() {
321
+ return this.sessions.size;
322
+ }
323
+ has(label) {
324
+ return this.sessions.has(label);
325
+ }
326
+ /**
327
+ * Spawns a Docker-agent PTY child and registers it. Fails cleanly with a
328
+ * {@link PtyUnavailableError} if the PTY runtime cannot be loaded. Returns the
329
+ * borrowed label. The initial size is a sane 80x24 default; the first browser
330
+ * attach re-sizes it (§11 D1).
331
+ */
332
+ async create(options = {}) {
333
+ await this.preflight();
334
+ const label = this.sessionManager.reserveLabel();
335
+ const { bin, prefixArgs } = resolveIroncurtainBin();
336
+ const agent = this.mode.kind === 'docker' ? this.mode.agent : 'claude-code';
337
+ const captureTraces = options.captureTraces ?? this.captureTracesDefault;
338
+ const bridge = await this.createBridge({
339
+ cols: PTY_INITIAL_COLS,
340
+ rows: PTY_INITIAL_ROWS,
341
+ ironcurtainBin: bin,
342
+ prefixArgs,
343
+ agent,
344
+ ...(options.persona ? { persona: options.persona } : {}),
345
+ ...(options.workspacePath ? { workspacePath: options.workspacePath } : {}),
346
+ ...(options.providerProfileName ? { providerProfileName: options.providerProfileName } : {}),
347
+ ...(options.model ? { model: options.model } : {}),
348
+ captureTraces,
349
+ muxId: this.ownerId,
350
+ muxPid: this.ownerPid,
351
+ });
352
+ const session = new PtyWebSession(label, bridge, this.sender, options.persona);
353
+ // Register + announce the session BEFORE wiring the bridge handlers. A child
354
+ // that already exited by now makes `bridge.onExit` fire its callback
355
+ // synchronously; if the session were not yet in the map, `handleExit` would
356
+ // no-op and leak the entry (armed idle timer, `session.created` with no
357
+ // matching `session.ended`). Registering first makes that a clean
358
+ // created -> ended. A freshly created session has no subscribers yet, so the
359
+ // idle backstop guards against a browser that crashes between create and
360
+ // attach; the first attach cancels it.
361
+ this.sessions.set(label, session);
362
+ this.startIdleTimer(label);
363
+ this.eventBus.emit('session.created', toPtySessionDto(session));
364
+ bridge.onData((chunk) => session.pushChunk(chunk));
365
+ bridge.onExit(() => this.handleExit(label));
366
+ // Phase 4: capture the escalation dir and start bridging its escalations
367
+ // to the structured Escalations UI over the WebEventBus.
368
+ bridge.onSessionDiscovered((reg) => {
369
+ if (!reg)
370
+ return;
371
+ session.escalationDir = reg.escalationDir;
372
+ this.startEscalationWatcher(session, reg.escalationDir);
373
+ });
374
+ return { label };
375
+ }
376
+ /**
377
+ * Attaches a client to a session's terminal stream: a synchronous
378
+ * snapshot-then-subscribe (see {@link PtyWebSession.attach}). Cancels the
379
+ * session's idle-TTL timer.
380
+ */
381
+ attach(label, client) {
382
+ const session = this.sessions.get(label);
383
+ if (!session)
384
+ throw new SessionNotFoundError(label);
385
+ session.attach(client);
386
+ this.clearIdleTimer(label);
387
+ }
388
+ /** Detaches a client; starts the idle-TTL timer if the session is now empty. */
389
+ detach(label, client) {
390
+ const session = this.sessions.get(label);
391
+ if (!session)
392
+ return;
393
+ session.removeSubscriber(client);
394
+ if (!session.hasSubscribers())
395
+ this.startIdleTimer(label);
396
+ }
397
+ /** Removes a disconnecting client from every session (mirrors the token bridge). */
398
+ removeAllForClient(client) {
399
+ for (const [label, session] of this.sessions) {
400
+ session.removeSubscriber(client);
401
+ if (!session.hasSubscribers())
402
+ this.startIdleTimer(label);
403
+ }
404
+ }
405
+ /** Forwards decoded keystroke bytes to the child PTY stdin. */
406
+ input(label, dataB64) {
407
+ const session = this.requireSession(label);
408
+ session.bridge.write(decodeBytes(dataB64));
409
+ }
410
+ /**
411
+ * Sends a TRUSTED user message. Writes user-context.json (source
412
+ * `mux-trusted-input`, fresh timestamp) to the session's escalation dir so the
413
+ * auto-approver can act on the user's intent, then injects the message into
414
+ * the child PTY. This is the web-ui equivalent of mux's command-mode trusted
415
+ * input -- the ONLY path that lets a browser user authorize auto-approval;
416
+ * raw {@link input} keystrokes are never trusted. If discovery has not yet
417
+ * yielded the escalation dir, the message is still injected but is NOT trusted
418
+ * (a warning is logged); the user simply gets an escalation instead.
419
+ */
420
+ sendPrompt(label, text) {
421
+ const session = this.requireSession(label);
422
+ if (!session.bridge.alive)
423
+ return;
424
+ if (session.escalationDir) {
425
+ try {
426
+ writeTrustedUserContext(session.escalationDir, text);
427
+ }
428
+ catch (err) {
429
+ // A failed trusted-context write (I/O error, bad dir perms) must not
430
+ // swallow the message: fall through and inject it UNTRUSTED (approvable
431
+ // actions then escalate to a human) rather than aborting the RPC.
432
+ logger.warn(`[WebUI] PTY session #${label}: trusted user-context write failed (${err instanceof Error ? err.message : String(err)}); message sent untrusted`);
433
+ }
434
+ }
435
+ else {
436
+ logger.warn(`[WebUI] PTY session #${label}: escalation dir not ready; message sent untrusted`);
437
+ }
438
+ // Inject the text, then the Enter separately after a short delay (see
439
+ // PTY_ENTER_DELAY_MS). Capture the bridge so a session reaped in the gap
440
+ // doesn't throw.
441
+ session.bridge.write(text);
442
+ const bridge = session.bridge;
443
+ setTimeout(() => {
444
+ if (bridge.alive)
445
+ bridge.write('\r');
446
+ }, PTY_ENTER_DELAY_MS);
447
+ }
448
+ /** Resizes the child PTY (browser xterm is just another resize source). */
449
+ resize(label, cols, rows) {
450
+ const session = this.requireSession(label);
451
+ session.bridge.resize(cols, rows);
452
+ }
453
+ /** Explicitly ends a session (kills the child -> container teardown). */
454
+ end(label) {
455
+ this.endInternal(label, 'user_ended');
456
+ }
457
+ /** Kills all bridges with a bounded await (mirrors mux doShutdown). */
458
+ async close() {
459
+ const sessions = [...this.sessions.values()];
460
+ this.sessions.clear();
461
+ for (const timer of this.idleTimers.values())
462
+ clearTimeout(timer);
463
+ this.idleTimers.clear();
464
+ const exits = sessions.map((session) => new Promise((resolve) => {
465
+ session.bridge.onExit(() => resolve());
466
+ session.dispose();
467
+ session.bridge.kill();
468
+ }));
469
+ const timeout = new Promise((resolve) => setTimeout(resolve, PTY_CLOSE_TIMEOUT_MS));
470
+ await Promise.race([Promise.allSettled(exits), timeout]);
471
+ }
472
+ /** SessionDto snapshots for `sessions.list`. */
473
+ listDtos() {
474
+ return [...this.sessions.values()].map((session) => toPtySessionDto(session));
475
+ }
476
+ getDto(label) {
477
+ const session = this.sessions.get(label);
478
+ return session ? toPtySessionDto(session) : undefined;
479
+ }
480
+ // -------------------------------------------------------------------------
481
+ // Escalation bridging (Phase 4)
482
+ // -------------------------------------------------------------------------
483
+ /** Whether any live PTY session has this escalation pending. */
484
+ hasEscalation(escalationId) {
485
+ return this.findEscalationOwner(escalationId) !== undefined;
486
+ }
487
+ /**
488
+ * Resolves a PTY escalation: writes the response file, drops the pending
489
+ * entry, and emits `escalation.resolved` so the UI clears the card (§11 D3).
490
+ * Returns whether the response was accepted (false if it had already expired).
491
+ */
492
+ resolveEscalation(escalationId, decision, options) {
493
+ const session = this.findEscalationOwner(escalationId);
494
+ if (!session) {
495
+ throw new RpcError('ESCALATION_NOT_FOUND', `No pending PTY escalation: ${escalationId}`);
496
+ }
497
+ const accepted = session.resolveEscalation(escalationId, decision, options);
498
+ this.eventBus.emit('escalation.resolved', { escalationId, decision });
499
+ return accepted;
500
+ }
501
+ /** All escalations pending across live PTY sessions, for the list union. */
502
+ listPendingEscalationDtos() {
503
+ return [...this.sessions.values()].flatMap((session) => session.listEscalationDtos());
504
+ }
505
+ findEscalationOwner(escalationId) {
506
+ for (const session of this.sessions.values()) {
507
+ if (session.hasEscalation(escalationId))
508
+ return session;
509
+ }
510
+ return undefined;
511
+ }
512
+ /**
513
+ * Starts an {@link EscalationWatcher} over a discovered escalation dir (idempotent
514
+ * per session). Detected requests are re-emitted as `escalation.created` DTOs and
515
+ * expiries as `escalation.expired`, mirroring the turn-based transport.
516
+ */
517
+ startEscalationWatcher(session, escalationDir) {
518
+ if (session.escalationWatcher)
519
+ return;
520
+ const watcher = createEscalationWatcher(escalationDir, {
521
+ onEscalation: (request) => {
522
+ const dto = buildPtyEscalationDto(request, session.label);
523
+ session.addPendingEscalation(dto);
524
+ this.eventBus.emit('escalation.created', dto);
525
+ },
526
+ onEscalationExpired: (escalationId) => {
527
+ session.removePendingEscalation(escalationId);
528
+ this.eventBus.emit('escalation.expired', { escalationId, sessionLabel: session.label });
529
+ },
530
+ });
531
+ session.escalationWatcher = watcher;
532
+ watcher.start();
533
+ }
534
+ // -------------------------------------------------------------------------
535
+ // Internals
536
+ // -------------------------------------------------------------------------
537
+ requireSession(label) {
538
+ const session = this.sessions.get(label);
539
+ if (!session)
540
+ throw new SessionNotFoundError(label);
541
+ return session;
542
+ }
543
+ handleExit(label) {
544
+ // On explicit end()/idle reap the session is already removed; this fires
545
+ // for a child that exited on its own (agent quit / crash).
546
+ const session = this.sessions.get(label);
547
+ if (!session)
548
+ return;
549
+ this.sessions.delete(label);
550
+ this.clearIdleTimer(label);
551
+ session.dispose();
552
+ this.eventBus.emit('session.ended', { label, reason: 'pty_exited' });
553
+ }
554
+ endInternal(label, reason) {
555
+ const session = this.sessions.get(label);
556
+ if (!session)
557
+ return;
558
+ // Remove before killing so the bridge's onExit -> handleExit is a no-op
559
+ // (no duplicate session.ended, whether kill fires onExit sync or async).
560
+ this.sessions.delete(label);
561
+ this.clearIdleTimer(label);
562
+ session.dispose();
563
+ session.bridge.kill();
564
+ this.eventBus.emit('session.ended', { label, reason });
565
+ }
566
+ startIdleTimer(label) {
567
+ if (this.idleTtlMs <= 0)
568
+ return; // disabled
569
+ this.clearIdleTimer(label);
570
+ this.idleTimers.set(label, setTimeout(() => {
571
+ this.idleTimers.delete(label);
572
+ this.endInternal(label, 'idle_reaped');
573
+ }, this.idleTtlMs));
574
+ }
575
+ clearIdleTimer(label) {
576
+ const timer = this.idleTimers.get(label);
577
+ if (timer) {
578
+ clearTimeout(timer);
579
+ this.idleTimers.delete(label);
580
+ }
581
+ }
582
+ preflight() {
583
+ if (!this.preflightPromise) {
584
+ this.preflightPromise = this.runPreflight().catch((err) => {
585
+ // Reset so a later create() re-probes rather than caching a failure
586
+ // from a transient load error.
587
+ this.preflightPromise = undefined;
588
+ throw new PtyUnavailableError(err instanceof Error ? err.message : String(err));
589
+ });
590
+ }
591
+ return this.preflightPromise;
592
+ }
593
+ }
594
+ /** Default runtime probe: node-pty must load and the serialize addon must exist. */
595
+ async function defaultPreflight() {
596
+ await import('node-pty');
597
+ await import('@xterm/addon-serialize');
598
+ }
599
+ //# sourceMappingURL=pty-session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty-session-manager.js","sourceRoot":"","sources":["../../src/web-ui/pty-session-manager.ts"],"names":[],"mappings":"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"}
@@ -139,6 +139,14 @@ export interface WebEventMap {
139
139
  label: number;
140
140
  events: readonly TokenStreamEvent[];
141
141
  };
142
+ 'session.pty_output': {
143
+ label: number;
144
+ data: string;
145
+ };
146
+ 'session.pty_replay': {
147
+ label: number;
148
+ snapshot: string;
149
+ };
142
150
  'persona.compile.started': {
143
151
  name: string;
144
152
  operationId: string;
@@ -163,6 +171,7 @@ export interface WebEventMap {
163
171
  error: string;
164
172
  };
165
173
  'personas.changed': Record<string, never>;
174
+ 'config.changed': Record<string, never>;
166
175
  }
167
176
  export type WebEventName = keyof WebEventMap;
168
177
  export type WebEventHandler = EventHandler<WebEventMap>;
@@ -1 +1 @@
1
- {"version":3,"file":"web-event-bus.js","sourceRoot":"","sources":["../../src/web-ui/web-event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,OAAO,EAAE,aAAa,EAAqB,MAAM,iCAAiC,CAAC;AA0FnF;;;;;GAKG;AACH,MAAM,OAAO,WAAY,SAAQ,aAA0B;CAAG"}
1
+ {"version":3,"file":"web-event-bus.js","sourceRoot":"","sources":["../../src/web-ui/web-event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,OAAO,EAAE,aAAa,EAAqB,MAAM,iCAAiC,CAAC;AAuGnF;;;;;GAKG;AACH,MAAM,OAAO,WAAY,SAAQ,aAA0B;CAAG"}