@wrongstack/webui-server 0.284.1 → 0.286.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 (176) hide show
  1. package/dist/index.d.ts +11 -2300
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +1807 -539
  4. package/dist/index.js.map +7 -1
  5. package/dist/server/autophase-routes.d.ts +10 -0
  6. package/dist/server/autophase-routes.d.ts.map +1 -0
  7. package/dist/server/autophase-ws-handler.d.ts +87 -0
  8. package/dist/server/autophase-ws-handler.d.ts.map +1 -0
  9. package/dist/server/backend-services.d.ts +103 -0
  10. package/dist/server/backend-services.d.ts.map +1 -0
  11. package/dist/server/boot.d.ts +19 -0
  12. package/dist/server/boot.d.ts.map +1 -0
  13. package/dist/server/brain-routes.d.ts +11 -0
  14. package/dist/server/brain-routes.d.ts.map +1 -0
  15. package/dist/server/codebase-indexing.d.ts +15 -0
  16. package/dist/server/codebase-indexing.d.ts.map +1 -0
  17. package/dist/server/collaboration-ws-handler.d.ts +167 -0
  18. package/dist/server/collaboration-ws-handler.d.ts.map +1 -0
  19. package/dist/server/completion-handlers.d.ts +39 -0
  20. package/dist/server/completion-handlers.d.ts.map +1 -0
  21. package/dist/server/connection-handler.d.ts +72 -0
  22. package/dist/server/connection-handler.d.ts.map +1 -0
  23. package/dist/server/context-meta.d.ts +28 -0
  24. package/dist/server/context-meta.d.ts.map +1 -0
  25. package/dist/server/custom-context-modes.d.ts +43 -0
  26. package/dist/server/custom-context-modes.d.ts.map +1 -0
  27. package/dist/server/design-handlers.d.ts +40 -0
  28. package/dist/server/design-handlers.d.ts.map +1 -0
  29. package/dist/server/discover-mailbox-bridge.d.ts +26 -0
  30. package/dist/server/discover-mailbox-bridge.d.ts.map +1 -0
  31. package/dist/server/entry.d.ts +2 -2
  32. package/dist/server/entry.d.ts.map +1 -0
  33. package/dist/server/entry.js +1595 -562
  34. package/dist/server/entry.js.map +7 -1
  35. package/dist/server/eternal-iteration-broadcast.d.ts +11 -0
  36. package/dist/server/eternal-iteration-broadcast.d.ts.map +1 -0
  37. package/dist/server/file-handlers.d.ts +45 -0
  38. package/dist/server/file-handlers.d.ts.map +1 -0
  39. package/dist/server/file-picker.d.ts +26 -0
  40. package/dist/server/file-picker.d.ts.map +1 -0
  41. package/dist/server/git-handlers.d.ts +55 -0
  42. package/dist/server/git-handlers.d.ts.map +1 -0
  43. package/dist/server/goal-handlers.d.ts +19 -0
  44. package/dist/server/goal-handlers.d.ts.map +1 -0
  45. package/dist/server/handlers/index.d.ts +12 -0
  46. package/dist/server/handlers/index.d.ts.map +1 -0
  47. package/dist/server/handlers/worklist-handlers.d.ts +49 -0
  48. package/dist/server/handlers/worklist-handlers.d.ts.map +1 -0
  49. package/dist/server/handlers.d.ts +1 -51
  50. package/dist/server/handlers.js +17 -8
  51. package/dist/server/handlers.js.map +7 -1
  52. package/dist/server/http-server/analytics-handler.d.ts +35 -0
  53. package/dist/server/http-server/analytics-handler.d.ts.map +1 -0
  54. package/dist/server/http-server/api-handlers.d.ts +44 -0
  55. package/dist/server/http-server/api-handlers.d.ts.map +1 -0
  56. package/dist/server/http-server.d.ts +108 -0
  57. package/dist/server/http-server.d.ts.map +1 -0
  58. package/dist/server/index.d.ts +93 -0
  59. package/dist/server/index.d.ts.map +1 -0
  60. package/dist/server/instance-registry.d.ts +63 -0
  61. package/dist/server/instance-registry.d.ts.map +1 -0
  62. package/dist/server/kanban-routes.d.ts +7 -0
  63. package/dist/server/kanban-routes.d.ts.map +1 -0
  64. package/dist/server/lifecycle.d.ts +51 -0
  65. package/dist/server/lifecycle.d.ts.map +1 -0
  66. package/dist/server/mailbox-handlers.d.ts +63 -0
  67. package/dist/server/mailbox-handlers.d.ts.map +1 -0
  68. package/dist/server/mailbox-routes.d.ts +11 -0
  69. package/dist/server/mailbox-routes.d.ts.map +1 -0
  70. package/dist/server/mcp-handlers.d.ts +55 -0
  71. package/dist/server/mcp-handlers.d.ts.map +1 -0
  72. package/dist/server/mcp-routes.d.ts +41 -0
  73. package/dist/server/mcp-routes.d.ts.map +1 -0
  74. package/dist/server/memory-handlers.d.ts +28 -0
  75. package/dist/server/memory-handlers.d.ts.map +1 -0
  76. package/dist/server/message-dispatcher.d.ts +41 -0
  77. package/dist/server/message-dispatcher.d.ts.map +1 -0
  78. package/dist/server/mode-handlers.d.ts +50 -0
  79. package/dist/server/mode-handlers.d.ts.map +1 -0
  80. package/dist/server/mode-routes.d.ts +8 -0
  81. package/dist/server/mode-routes.d.ts.map +1 -0
  82. package/dist/server/model-auto-discovery.d.ts +9 -0
  83. package/dist/server/model-auto-discovery.d.ts.map +1 -0
  84. package/dist/server/model-catalog.d.ts +16 -0
  85. package/dist/server/model-catalog.d.ts.map +1 -0
  86. package/dist/server/open-browser.d.ts +16 -0
  87. package/dist/server/open-browser.d.ts.map +1 -0
  88. package/dist/server/path-containment.d.ts +3 -0
  89. package/dist/server/path-containment.d.ts.map +1 -0
  90. package/dist/server/pending-confirms.d.ts +14 -0
  91. package/dist/server/pending-confirms.d.ts.map +1 -0
  92. package/dist/server/port-utils.d.ts +28 -0
  93. package/dist/server/port-utils.d.ts.map +1 -0
  94. package/dist/server/pre-context-services.d.ts +60 -0
  95. package/dist/server/pre-context-services.d.ts.map +1 -0
  96. package/dist/server/pref-helpers.d.ts +43 -0
  97. package/dist/server/pref-helpers.d.ts.map +1 -0
  98. package/dist/server/prefs-routes.d.ts +27 -0
  99. package/dist/server/prefs-routes.d.ts.map +1 -0
  100. package/dist/server/process-handlers.d.ts +20 -0
  101. package/dist/server/process-handlers.d.ts.map +1 -0
  102. package/dist/server/project-handlers.d.ts +53 -0
  103. package/dist/server/project-handlers.d.ts.map +1 -0
  104. package/dist/server/project-routes.d.ts +10 -0
  105. package/dist/server/project-routes.d.ts.map +1 -0
  106. package/dist/server/projects-manifest.d.ts +18 -0
  107. package/dist/server/projects-manifest.d.ts.map +1 -0
  108. package/dist/server/prompts-handlers.d.ts +38 -0
  109. package/dist/server/prompts-handlers.d.ts.map +1 -0
  110. package/dist/server/provider-config-io.d.ts +15 -0
  111. package/dist/server/provider-config-io.d.ts.map +1 -0
  112. package/dist/server/provider-config-standalone.d.ts +13 -0
  113. package/dist/server/provider-config-standalone.d.ts.map +1 -0
  114. package/dist/server/provider-handlers.d.ts +74 -0
  115. package/dist/server/provider-handlers.d.ts.map +1 -0
  116. package/dist/server/provider-keys.d.ts +53 -0
  117. package/dist/server/provider-keys.d.ts.map +1 -0
  118. package/dist/server/provider-routes.d.ts +13 -0
  119. package/dist/server/provider-routes.d.ts.map +1 -0
  120. package/dist/server/provider-store.d.ts +26 -0
  121. package/dist/server/provider-store.d.ts.map +1 -0
  122. package/dist/server/routes.d.ts +187 -0
  123. package/dist/server/routes.d.ts.map +1 -0
  124. package/dist/server/sdd-board-routes.d.ts +11 -0
  125. package/dist/server/sdd-board-routes.d.ts.map +1 -0
  126. package/dist/server/sdd-board-ws-handler.d.ts +57 -0
  127. package/dist/server/sdd-board-ws-handler.d.ts.map +1 -0
  128. package/dist/server/sdd-wizard-routes.d.ts +16 -0
  129. package/dist/server/sdd-wizard-routes.d.ts.map +1 -0
  130. package/dist/server/sdd-wizard-wiring.d.ts +26 -0
  131. package/dist/server/sdd-wizard-wiring.d.ts.map +1 -0
  132. package/dist/server/sdd-wizard-ws-handler.d.ts +66 -0
  133. package/dist/server/sdd-wizard-ws-handler.d.ts.map +1 -0
  134. package/dist/server/server-runtime.d.ts +118 -0
  135. package/dist/server/server-runtime.d.ts.map +1 -0
  136. package/dist/server/session-handlers.d.ts +57 -0
  137. package/dist/server/session-handlers.d.ts.map +1 -0
  138. package/dist/server/session-routes.d.ts +23 -0
  139. package/dist/server/session-routes.d.ts.map +1 -0
  140. package/dist/server/setup-events.d.ts +67 -0
  141. package/dist/server/setup-events.d.ts.map +1 -0
  142. package/dist/server/setup-screen.d.ts +44 -0
  143. package/dist/server/setup-screen.d.ts.map +1 -0
  144. package/dist/server/shell-git-routes.d.ts +10 -0
  145. package/dist/server/shell-git-routes.d.ts.map +1 -0
  146. package/dist/server/shell-open.d.ts +12 -0
  147. package/dist/server/shell-open.d.ts.map +1 -0
  148. package/dist/server/skills-handlers.d.ts +77 -0
  149. package/dist/server/skills-handlers.d.ts.map +1 -0
  150. package/dist/server/specs-routes.d.ts +11 -0
  151. package/dist/server/specs-routes.d.ts.map +1 -0
  152. package/dist/server/specs-ws-handler.d.ts +34 -0
  153. package/dist/server/specs-ws-handler.d.ts.map +1 -0
  154. package/dist/server/standalone-session-identity.d.ts +35 -0
  155. package/dist/server/standalone-session-identity.d.ts.map +1 -0
  156. package/dist/server/start-webui.d.ts +29 -0
  157. package/dist/server/start-webui.d.ts.map +1 -0
  158. package/dist/server/terminal-ws-handler.d.ts +70 -0
  159. package/dist/server/terminal-ws-handler.d.ts.map +1 -0
  160. package/dist/server/token-estimator.d.ts +66 -0
  161. package/dist/server/token-estimator.d.ts.map +1 -0
  162. package/dist/server/types.d.ts +143 -0
  163. package/dist/server/types.d.ts.map +1 -0
  164. package/dist/server/usage-cost.d.ts +39 -0
  165. package/dist/server/usage-cost.d.ts.map +1 -0
  166. package/dist/server/worktree-ws-handler.d.ts +67 -0
  167. package/dist/server/worktree-ws-handler.d.ts.map +1 -0
  168. package/dist/server/ws-auth.d.ts +83 -0
  169. package/dist/server/ws-auth.d.ts.map +1 -0
  170. package/dist/server/ws-payload-validation.d.ts +126 -0
  171. package/dist/server/ws-payload-validation.d.ts.map +1 -0
  172. package/dist/server/ws-utils.d.ts +38 -0
  173. package/dist/server/ws-utils.d.ts.map +1 -0
  174. package/dist/server/zip.d.ts +9 -0
  175. package/dist/server/zip.d.ts.map +1 -0
  176. package/package.json +11 -12
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Running-instance registry for the standalone WebUI server.
3
+ *
4
+ * Every live `wstackui` process records itself in a single JSON file under the
5
+ * wstack home dir (`~/.wrongstack/webui-instances.json`) so a user running
6
+ * several instances (one per project, or several per project on different
7
+ * ports) can see at a glance which ports are open for which path.
8
+ *
9
+ * Design notes:
10
+ * - **Self-healing**: every register/unregister/list prunes entries whose PID
11
+ * is no longer alive (`process.kill(pid, 0)`), so a crashed instance that
12
+ * never got to unregister doesn't leave a ghost behind.
13
+ * - **Atomic writes**: the file is rewritten via `atomicWrite` (tmp + rename),
14
+ * so a concurrent reader never sees a half-written file. Two instances
15
+ * starting at the *exact* same millisecond could still race the
16
+ * read-modify-write — acceptable for a best-effort tracking file, and the
17
+ * next register() heals any dropped entry.
18
+ * - **Best-effort**: a failure to read/write the registry must NEVER take the
19
+ * server down. Callers wrap these in `.catch()`.
20
+ */
21
+ /** One running WebUI process. */
22
+ export interface WebUIInstanceRecord {
23
+ /** OS process id — also the liveness key. */
24
+ pid: number;
25
+ /** HTTP port serving the React frontend. */
26
+ httpPort: number;
27
+ /** WebSocket port for the agent backend. */
28
+ wsPort: number;
29
+ /** Bind host (e.g. 127.0.0.1 or 0.0.0.0). */
30
+ host: string;
31
+ /** Absolute project root the instance booted against. */
32
+ projectRoot: string;
33
+ /** Display name (basename of projectRoot). */
34
+ projectName: string;
35
+ /** ISO timestamp when the instance registered. */
36
+ startedAt: string;
37
+ /** Convenience open-in-browser URL. */
38
+ url: string;
39
+ }
40
+ /** Default wstack home dir (`~/.wrongstack`). Callers may override the base. */
41
+ export declare function defaultBaseDir(): string;
42
+ /** Resolve the registry file path for a given base dir. */
43
+ export declare function registryPath(baseDir?: string): string;
44
+ /**
45
+ * Liveness probe. `process.kill(pid, 0)` sends no signal — it only checks the
46
+ * process exists. ESRCH ⇒ dead; EPERM ⇒ alive but owned by another user (still
47
+ * counts as alive). Any other error is treated conservatively as "alive" so we
48
+ * never prune an instance we simply failed to probe.
49
+ */
50
+ export declare function isPidAlive(pid: number): boolean;
51
+ /**
52
+ * Register (or refresh) this instance. Prunes dead entries and any stale entry
53
+ * for our own PID before adding the current record. Best-effort — rejects only
54
+ * on a hard fs error, which callers swallow.
55
+ */
56
+ export declare function registerInstance(record: WebUIInstanceRecord, baseDir?: string): Promise<void>;
57
+ /** Remove this instance (called on graceful shutdown). Also prunes dead pids. */
58
+ export declare function unregisterInstance(pid: number, baseDir?: string): Promise<void>;
59
+ /** List live instances, pruning any dead entries encountered. */
60
+ export declare function listInstances(baseDir?: string): Promise<WebUIInstanceRecord[]>;
61
+ /** Human-readable table of running instances for `wstackui --list`. */
62
+ export declare function formatInstances(instances: WebUIInstanceRecord[]): string;
63
+ //# sourceMappingURL=instance-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-registry.d.ts","sourceRoot":"","sources":["../../src/server/instance-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,iCAAiC;AACjC,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;CACb;AAOD,gFAAgF;AAChF,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAyB,GAAG,MAAM,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ/C;AA0BD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,GAAE,MAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,iFAAiF;AACjF,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,iEAAiE;AACjE,wBAAsB,aAAa,CACjC,OAAO,GAAE,MAAyB,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAUhC;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,SAAS,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAaxE"}
@@ -0,0 +1,7 @@
1
+ import type { WebSocket } from 'ws';
2
+ import type { WSClientMessage } from './types.js';
3
+ export interface KanbanRouteContext {
4
+ projectRoot: string;
5
+ }
6
+ export declare function handleKanbanRoute(ws: WebSocket, msg: WSClientMessage, ctx: KanbanRouteContext): Promise<boolean>;
7
+ //# sourceMappingURL=kanban-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanban-routes.d.ts","sourceRoot":"","sources":["../../src/server/kanban-routes.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB;AAUD,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,OAAO,CAAC,CAwlBlB"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Process lifecycle for the WebUI server: graceful shutdown and the
3
+ * SIGINT/SIGTERM wiring that triggers it.
4
+ *
5
+ * On a termination signal we (best-effort) flush + close the active session,
6
+ * close every connected WebSocket, stop the HTTP and WS servers, then exit.
7
+ * A re-entrancy guard makes a second signal during shutdown a no-op (rapid
8
+ * double Ctrl+C no longer runs the teardown twice).
9
+ *
10
+ * Extracted from `index.ts` as a parameterized factory so the teardown
11
+ * sequence can be unit tested without a real process signal, server, or
12
+ * `process.exit` — `log` and `exit` are injectable seams.
13
+ */
14
+ export interface LifecycleResources {
15
+ /** Persist + close the active session (best-effort; errors are logged). */
16
+ flushSession: () => Promise<void>;
17
+ /**
18
+ * Returns the currently-connected client sockets to close. A thunk (not a
19
+ * snapshot) so shutdown closes whoever is connected *at signal time*, not
20
+ * whoever was connected when the handler was registered.
21
+ */
22
+ clients: () => Iterable<{
23
+ close: () => void;
24
+ }>;
25
+ /** Servers to stop (HTTP + WS). `null`/`undefined` entries are skipped. */
26
+ servers: Array<{
27
+ close: () => void;
28
+ } | null | undefined>;
29
+ /**
30
+ * Optional best-effort cleanup run after the session flush and before exit
31
+ * (e.g. removing this process from the running-instance registry). Errors are
32
+ * logged, never thrown — cleanup must not block a clean shutdown.
33
+ */
34
+ onShutdown?: (() => Promise<void> | void) | undefined;
35
+ /** Output sink. Defaults to `console.log`. */
36
+ log?: ((msg: string) => void) | undefined;
37
+ /** Process exit. Defaults to `process.exit`. Injectable for tests. */
38
+ exit?: ((code: number) => void) | undefined;
39
+ }
40
+ /**
41
+ * Build the graceful-shutdown handler. Returns an idempotent async function:
42
+ * the first call runs the teardown, subsequent calls (e.g. a second SIGINT)
43
+ * return immediately.
44
+ */
45
+ export declare function createShutdown(res: LifecycleResources): () => Promise<void>;
46
+ /**
47
+ * Register the shutdown handler on SIGINT and SIGTERM. Returns an unregister
48
+ * function that detaches both listeners (useful for tests and clean restarts).
49
+ */
50
+ export declare function registerShutdownHandlers(res: LifecycleResources): () => void;
51
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/server/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;IAC/C,2EAA2E;IAC3E,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IACtD,8CAA8C;IAC9C,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1C,sEAAsE;IACtE,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CA0B3E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAQ5E"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Mailbox WebSocket handlers for the WebUI.
3
+ *
4
+ * Handles `mailbox.messages` and `mailbox.agents` message types.
5
+ * The frontend sends these to populate the mailbox panel; the server
6
+ * reads from the project-level GlobalMailbox and responds.
7
+ */
8
+ import type { WebSocket } from 'ws';
9
+ export interface MailboxHandlerDeps {
10
+ /** Absolute project root. */
11
+ projectRoot: string;
12
+ /** Global WrongStack root (~/.wrongstack). */
13
+ globalRoot: string;
14
+ }
15
+ /**
16
+ * List recent mailbox messages. Frontend sends:
17
+ * { type: 'mailbox.messages', limit?: number, incompleteOnly?: boolean }
18
+ *
19
+ * Uses `incompleteOnly` so the server filters to active/unread messages,
20
+ * making readByCount === 0 a reliable "unread to all agents" signal for
21
+ * the ActivityBar badge count.
22
+ */
23
+ export declare function handleMailboxMessages(ws: WebSocket, deps: MailboxHandlerDeps, payload: {
24
+ limit?: number;
25
+ agentId?: string;
26
+ unreadOnly?: boolean;
27
+ incompleteOnly?: boolean;
28
+ } | undefined): Promise<void>;
29
+ /**
30
+ * List registered agents. Frontend sends:
31
+ * { type: 'mailbox.agents', onlineOnly?: boolean }
32
+ */
33
+ export declare function handleMailboxAgents(ws: WebSocket, deps: MailboxHandlerDeps, payload: {
34
+ onlineOnly?: boolean;
35
+ } | undefined): Promise<void>;
36
+ /**
37
+ * Delete all messages from the mailbox. Frontend sends:
38
+ * { type: 'mailbox.clear' }
39
+ * Server responds with 'mailbox.cleared'.
40
+ */
41
+ export declare function handleMailboxClear(ws: WebSocket, deps: MailboxHandlerDeps): Promise<void>;
42
+ /**
43
+ * Purge stale/orphaned messages from the mailbox. Frontend sends:
44
+ * { type: 'mailbox.purge', payload?: { completedMaxAgeMs?: number; incompleteMaxAgeMs?: number } }
45
+ * Server responds with 'mailbox.purged'.
46
+ */
47
+ export declare function handleMailboxPurge(ws: WebSocket, deps: MailboxHandlerDeps, opts?: {
48
+ completedMaxAgeMs?: number;
49
+ incompleteMaxAgeMs?: number;
50
+ }): Promise<void>;
51
+ /**
52
+ * Auto-compact the mailbox: removes expired (TTL) messages, messages read
53
+ * by all online agents, and stale messages — all in one pass. Frontend sends:
54
+ * { type: 'mailbox.compact', payload?: { readMaxAgeMs?, defaultTtlMs?, ... } }
55
+ * Server responds with 'mailbox.compacted' containing the result.
56
+ */
57
+ export declare function handleMailboxCompact(ws: WebSocket, deps: MailboxHandlerDeps, opts?: {
58
+ readMaxAgeMs?: number;
59
+ defaultTtlMs?: number;
60
+ completedMaxAgeMs?: number;
61
+ incompleteMaxAgeMs?: number;
62
+ }): Promise<void>;
63
+ //# sourceMappingURL=mailbox-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-handlers.d.ts","sourceRoot":"","sources":["../../src/server/mailbox-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAIpC,MAAM,WAAW,kBAAkB;IACjC,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB;AAID;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GACxG,OAAO,CAAC,IAAI,CAAC,CAgCf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GAC5C,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,kBAAkB,EACxB,IAAI,CAAC,EAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GACjE,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,kBAAkB,EACxB,IAAI,CAAC,EAAE;IACL,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,GACA,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,11 @@
1
+ import type { WebSocket } from 'ws';
2
+ import type { WSClientMessage } from './types.js';
3
+ export interface MailboxRouteHandlers {
4
+ messages: (ws: WebSocket, msg: WSClientMessage) => Promise<void> | void;
5
+ agents: (ws: WebSocket, msg: WSClientMessage) => Promise<void> | void;
6
+ clear: (ws: WebSocket, msg: WSClientMessage) => Promise<void> | void;
7
+ purge: (ws: WebSocket, msg: WSClientMessage) => Promise<void> | void;
8
+ compact: (ws: WebSocket, msg: WSClientMessage) => Promise<void> | void;
9
+ }
10
+ export declare function handleMailboxRoute(ws: WebSocket, msg: WSClientMessage, handlers: MailboxRouteHandlers): Promise<boolean>;
11
+ //# sourceMappingURL=mailbox-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-routes.d.ts","sourceRoot":"","sources":["../../src/server/mailbox-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxE,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACtE,KAAK,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrE,KAAK,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxE;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * MCP management handlers for the WebUI server (both the standalone
3
+ * `wstackui` server and the CLI's embedded `--webui` server).
4
+ *
5
+ * These are thin WebSocket translators over the shared, surface-agnostic
6
+ * management core in `@wrongstack/mcp` (`manage.ts`) — the SAME core the REPL
7
+ * `/mcp` command writes against (same config.json, same MCPRegistry). All the
8
+ * config IO, url/header persistence, and live registry start/stop logic lives
9
+ * there; here we only map structured results to WS events the browser expects.
10
+ */
11
+ import { type MCPRegistry, type MCPServerOperationalHealth } from '@wrongstack/mcp';
12
+ import type { WebSocket } from 'ws';
13
+ import type { WSClientMessage } from './types.js';
14
+ /** Wire view of a server as the browser MCP panel consumes it. */
15
+ export interface MCPServerView {
16
+ name: string;
17
+ transport: string;
18
+ status: 'stopped' | 'connecting' | 'connected' | 'sleeping' | 'discovering' | 'error';
19
+ enabled: boolean;
20
+ description?: string;
21
+ tools?: string[];
22
+ error?: string;
23
+ pid?: number;
24
+ lazy?: boolean;
25
+ health?: MCPServerOperationalHealth;
26
+ }
27
+ /** mcp.list — configured servers merged with live registry status + tools. */
28
+ export declare function handleMcpList(ws: WebSocket, _msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
29
+ /** mcp.add — persist a new server (incl. url/headers) and start it if enabled. */
30
+ export declare function handleMcpAdd(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
31
+ /** mcp.update — re-persist config (incl. url/headers) and re-apply to registry. */
32
+ export declare function handleMcpUpdate(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
33
+ /** mcp.remove — stop the server and delete it from config. */
34
+ export declare function handleMcpRemove(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
35
+ /** mcp.enable — flip enabled:true in config and start the server. */
36
+ export declare function handleMcpEnable(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
37
+ /** mcp.disable — stop the server and flip enabled:false in config. */
38
+ export declare function handleMcpDisable(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
39
+ /** mcp.sleep — stop a running server (config stays enabled). */
40
+ export declare function handleMcpSleep(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
41
+ /** mcp.wake — restart a sleeping/stopped server from config. */
42
+ export declare function handleMcpWake(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
43
+ /** mcp.restart — stop + start a server. */
44
+ export declare function handleMcpRestart(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
45
+ /** mcp.discover — ensure the server is running and report its live tools. */
46
+ export declare function handleMcpDiscover(ws: WebSocket, msg: WSClientMessage, globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
47
+ /** mcp.resources — list cached resources/templates, refreshing only when explicitly requested. */
48
+ export declare function handleMcpResources(ws: WebSocket, msg: WSClientMessage, _globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
49
+ /** mcp.prompts — list cached prompts, refreshing only when explicitly requested. */
50
+ export declare function handleMcpPrompts(ws: WebSocket, msg: WSClientMessage, _globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
51
+ /** mcp.resource.read — explicit user selection; returns an untrusted provenance envelope. */
52
+ export declare function handleMcpResourceRead(ws: WebSocket, msg: WSClientMessage, _globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
53
+ /** mcp.prompt.get — explicit user selection; prompt argument values stay out of provenance. */
54
+ export declare function handleMcpPromptGet(ws: WebSocket, msg: WSClientMessage, _globalConfigPath: string, mcpRegistry?: MCPRegistry): Promise<void>;
55
+ //# sourceMappingURL=mcp-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-handlers.d.ts","sourceRoot":"","sources":["../../src/server/mcp-handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { WebSocket } from 'ws';
2
+ import type { WSClientMessage } from './types.js';
3
+ export interface McpRouteHandlers {
4
+ list: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
5
+ add: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
6
+ update: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
7
+ remove: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
8
+ enable: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
9
+ disable: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
10
+ sleep: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
11
+ wake: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
12
+ restart: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
13
+ discover: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
14
+ resources: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
15
+ prompts: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
16
+ resourceRead: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
17
+ promptGet: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
18
+ }
19
+ /**
20
+ * Chain-of-responsibility dispatcher for the `mcp.*` WS message family.
21
+ * Returns `true` if the message was handled by this layer (so the caller's
22
+ * chain short-circuits), `false` if it should fall through to the next layer
23
+ * or the residual switch.
24
+ *
25
+ * Owned prefixes (10 message types — full coverage of the MCP management
26
+ * surface; the WebUI MCP panel only ever talks to the server through these):
27
+ * - mcp.list
28
+ * - mcp.add
29
+ * - mcp.update
30
+ * - mcp.remove
31
+ * - mcp.enable
32
+ * - mcp.disable
33
+ * - mcp.sleep
34
+ * - mcp.wake
35
+ * - mcp.restart
36
+ * - mcp.discover
37
+ *
38
+ * Regression-tested by packages/webui/tests/server/dispatcher-routing.test.ts.
39
+ */
40
+ export declare function handleMcpRoute(ws: WebSocket, msg: WSClientMessage, handlers: McpRouteHandlers): Promise<boolean>;
41
+ //# sourceMappingURL=mcp-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-routes.d.ts","sourceRoot":"","sources":["../../src/server/mcp-routes.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,GAAG,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,KAAK,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,YAAY,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,OAAO,CAAC,CA+ClB"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared memory-operation WebSocket handlers for both the standalone WebUI
3
+ * server and the CLI's `--webui` embedded server. Extracted from the
4
+ * duplicated switch cases in `index.ts` and `cli/src/webui-server.ts`.
5
+ *
6
+ * Each function handles the full request→response cycle for one message
7
+ * type. Callers drop them into their switch statement:
8
+ *
9
+ * case 'memory.list': return handleMemoryList(ws, memoryStore);
10
+ */
11
+ import type { WebSocket } from 'ws';
12
+ import type { MemoryStore } from '@wrongstack/core';
13
+ /**
14
+ * List all memory entries across all scopes.
15
+ * Responds with `{ type: 'memory.list', payload: { text } }`.
16
+ */
17
+ export declare function handleMemoryList(ws: WebSocket, memoryStore: MemoryStore): Promise<void>;
18
+ /**
19
+ * Persist a new memory entry.
20
+ * Responds with `{ type: 'key.operation_result', payload: { success, message } }`.
21
+ */
22
+ export declare function handleMemoryRemember(ws: WebSocket, msg: unknown, memoryStore: MemoryStore): Promise<void>;
23
+ /**
24
+ * Remove memory entries matching the given text.
25
+ * Responds with `{ type: 'key.operation_result', payload: { success, message } }`.
26
+ */
27
+ export declare function handleMemoryForget(ws: WebSocket, msg: unknown, memoryStore: MemoryStore): Promise<void>;
28
+ //# sourceMappingURL=memory-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-handlers.d.ts","sourceRoot":"","sources":["../../src/server/memory-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,SAAS,EACb,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -0,0 +1,41 @@
1
+ import type { WebSocket } from 'ws';
2
+ import type { PendingConfirm } from './pending-confirms.js';
3
+ import type { AllRoutes, WebuiCallbacks, WebuiDeps, WebuiMutableState } from './routes.js';
4
+ import type { ConnectedClient, WSClientMessage } from './types.js';
5
+ /**
6
+ * Shared run-lock control. `user_message` acquires/releases it around
7
+ * `agent.run`. Both the dispatcher and the mutable-state wiring read through this object
8
+ * so a second user_message while running is rejected and a project swap can
9
+ * tear down the in-flight run.
10
+ */
11
+ export interface RunLockControl {
12
+ get(): AbortController | null;
13
+ set(ctrl: AbortController | null): void;
14
+ }
15
+ export interface MessageDispatcherOptions {
16
+ state: WebuiMutableState;
17
+ deps: WebuiDeps;
18
+ cb: WebuiCallbacks;
19
+ routes: AllRoutes;
20
+ /** Prompt-library context ({ promptLoader, promptUsage }). */
21
+ promptsCtx: {
22
+ promptLoader: unknown;
23
+ promptUsage: unknown;
24
+ };
25
+ /** Codebase-indexing side-effect hook (files.write notifies the indexer). */
26
+ codebaseIndexing: {
27
+ onFileWritten: (filePath: string) => void;
28
+ };
29
+ /** Shared run-lock guarding concurrent agent.run() calls. */
30
+ runLock: RunLockControl;
31
+ /** Pending permission confirmations — tool.confirm_result resolves one. */
32
+ pendingConfirms: Map<string, PendingConfirm>;
33
+ }
34
+ /**
35
+ * Build the inbound message dispatcher. Mirrors the `handleMessage` closure
36
+ * that lived inline in `startWebUI`. Reads live config/session/projectRoot
37
+ * through `state`, services through `deps`, and the boot-local closures
38
+ * through `cb` — same reference semantics, no behaviour change.
39
+ */
40
+ export declare function createMessageDispatcher(opts: MessageDispatcherOptions): (ws: WebSocket, _client: ConnectedClient, msg: WSClientMessage) => Promise<void>;
41
+ //# sourceMappingURL=message-dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-dispatcher.d.ts","sourceRoot":"","sources":["../../src/server/message-dispatcher.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AA8BpC,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAc7E,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgB3F,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKnE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,IAAI,eAAe,GAAG,IAAI,CAAC;IAC9B,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;CACzC;AACD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,cAAc,CAAC;IACnB,MAAM,EAAE,SAAS,CAAC;IAClB,8DAA8D;IAC9D,UAAU,EAAE;QAAE,YAAY,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5D,6EAA6E;IAC7E,gBAAgB,EAAE;QAAE,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;IAChE,6DAA6D;IAC7D,OAAO,EAAE,cAAc,CAAC;IACxB,2EAA2E;IAC3E,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC9C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAumBlF"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Mode route handlers — extracted from the startWebUI closure in index.ts.
3
+ * Mirrors createProviderHandlers: a factory that closes the handler bodies over
4
+ * an explicit context object instead of the giant startWebUI scope. The one
5
+ * piece of outer mutable state (the `modeId` let) is threaded in as a setter so
6
+ * the factory stays a pure function of its context.
7
+ */
8
+ import type { WebSocket } from 'ws';
9
+ import { type Context, DefaultSystemPromptBuilder, type MemoryStore, type DefaultModeStore, type SkillLoader, type ToolRegistry } from '@wrongstack/core';
10
+ import type { ConnectedClient } from './types.js';
11
+ import type { ModeRouteHandlers } from './mode-routes.js';
12
+ /** The rich payload startWebUI's sessionStartPayload() resolves to. Matches the
13
+ * WSSessionStart wire shape; broadcast() accepts it for a 'session.start' msg. */
14
+ type SessionStartPayload = {
15
+ sessionId: string;
16
+ model: string;
17
+ provider: string;
18
+ maxContext: number;
19
+ inputCost: number;
20
+ outputCost: number;
21
+ cacheReadCost: number;
22
+ projectName: string;
23
+ projectRoot: string;
24
+ cwd: string;
25
+ mode: string;
26
+ contextMode: string;
27
+ };
28
+ type ModelCapabilities = NonNullable<ConstructorParameters<typeof DefaultSystemPromptBuilder>[0]>['modelCapabilities'];
29
+ export interface ModeHandlersContext {
30
+ modeStore: DefaultModeStore;
31
+ memoryStore: MemoryStore;
32
+ skillLoader: SkillLoader | undefined;
33
+ modelCapabilities: ModelCapabilities;
34
+ context: Context;
35
+ toolRegistry: ToolRegistry;
36
+ config: {
37
+ provider: string;
38
+ model: string;
39
+ };
40
+ projectRoot: string;
41
+ globalRoot: string;
42
+ clients: Map<WebSocket, ConnectedClient>;
43
+ /** Update the outer `modeId` binding on a successful switch. */
44
+ setModeId: (id: string) => void;
45
+ /** Rebuilds the rich session.start payload broadcast after a mode switch. */
46
+ sessionStartPayload: () => Promise<SessionStartPayload>;
47
+ }
48
+ export declare function createModeHandlers(ctx: ModeHandlersContext): ModeRouteHandlers;
49
+ export {};
50
+ //# sourceMappingURL=mode-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-handlers.d.ts","sourceRoot":"","sources":["../../src/server/mode-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,EACL,KAAK,OAAO,EACZ,0BAA0B,EAE1B,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAI1D;mFACmF;AACnF,KAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AACF,KAAK,iBAAiB,GAAG,WAAW,CAClC,qBAAqB,CAAC,OAAO,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAC5D,CAAC,mBAAmB,CAAC,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACzC,gEAAgE;IAChE,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,6EAA6E;IAC7E,mBAAmB,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACzD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,GAAG,iBAAiB,CA8E9E"}
@@ -0,0 +1,8 @@
1
+ import type { WebSocket } from 'ws';
2
+ import type { WSClientMessage } from './types.js';
3
+ export interface ModeRouteHandlers {
4
+ listModes: (ws: WebSocket) => Promise<void>;
5
+ switchMode: (ws: WebSocket, msg: WSClientMessage) => Promise<void>;
6
+ }
7
+ export declare function handleModeRoute(ws: WebSocket, msg: WSClientMessage, handlers: ModeRouteHandlers): Promise<boolean>;
8
+ //# sourceMappingURL=mode-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-routes.d.ts","sourceRoot":"","sources":["../../src/server/mode-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAWlB"}
@@ -0,0 +1,9 @@
1
+ import type { Config, Logger } from '@wrongstack/core';
2
+ export declare function discoverAndMergeWebuiProviders(opts: {
3
+ config: Config;
4
+ registry: unknown;
5
+ cacheDir: string;
6
+ logger?: Pick<Logger, 'debug' | 'info' | 'warn'> | undefined;
7
+ fetchImpl?: typeof fetch | undefined;
8
+ }): Promise<void>;
9
+ //# sourceMappingURL=model-auto-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-auto-discovery.d.ts","sourceRoot":"","sources":["../../src/server/model-auto-discovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,MAAM,EACN,MAAM,EAIP,MAAM,kBAAkB,CAAC;AAmD1B,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC;IAC7D,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAC;CACtC,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDhB"}
@@ -0,0 +1,16 @@
1
+ import type { ModelsRegistry, ProviderConfig, ResolvedModel, ResolvedProvider } from '@wrongstack/core';
2
+ export declare const SIBLING_CATALOG: Record<string, string>;
3
+ /**
4
+ * Resolve the catalog entry to use for a saved provider's WebUI model list.
5
+ * Runtime discovery injects provider-specific catalogs under the saved provider
6
+ * id (for example `omniroute`), while older aliases may still need to fall
7
+ * back to their generic wire/catalog `type`.
8
+ */
9
+ export declare function resolveProviderCatalogForModels(modelsRegistry: Pick<ModelsRegistry, 'getProvider'>, providerId: string, cfg: Pick<ProviderConfig, 'type'> | undefined): Promise<ResolvedProvider | undefined>;
10
+ /**
11
+ * Resolve model metadata for a selected config provider. Prefer the saved
12
+ * provider id so provider-specific runtime discovery (for example Omniroute)
13
+ * supplies context/cost/capability metadata; fall back to cfg.type for aliases.
14
+ */
15
+ export declare function resolveProviderModelMetadata(modelsRegistry: Pick<ModelsRegistry, 'getModel' | 'getProvider'> & Partial<Pick<ModelsRegistry, 'listProviders'>>, providerId: string, modelId: string, cfg: Pick<ProviderConfig, 'type' | 'family' | 'models' | 'customModels' | 'capabilities'> | undefined): Promise<ResolvedModel | undefined>;
16
+ //# sourceMappingURL=model-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../src/server/model-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAG1B,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIlD,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,+BAA+B,CACnD,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,EACnD,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,SAAS,GAC5C,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAOvC;AAED;;;;GAIG;AACH,wBAAsB,4BAA4B,CAChD,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,aAAa,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,EACjH,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,GAAG,SAAS,GACpG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAuCpC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Best-effort "open this URL in the default browser" for `--webui --open`.
3
+ *
4
+ * Cross-platform via the OS opener (`start` / `open` / `xdg-open`). Fully
5
+ * fire-and-forget: a missing opener, a headless box, or a spawn failure must
6
+ * NEVER take the server down — the URL is always also printed to the console.
7
+ */
8
+ /** Resolve the platform's URL-opener command + args. */
9
+ export declare function browserOpenCommand(url: string, platform?: NodeJS.Platform): {
10
+ command: string;
11
+ args: string[];
12
+ };
13
+ /** Spawn the OS browser-opener for `url` and register it as a protected
14
+ * process so it survives kill/killAll. Never throws. */
15
+ export declare function openBrowser(url: string, platform?: NodeJS.Platform): void;
16
+ //# sourceMappingURL=open-browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-browser.d.ts","sourceRoot":"","sources":["../../src/server/open-browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,wDAAwD;AACxD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAUrC;AAED;yDACyD;AACzD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,IAAI,CA0C3F"}
@@ -0,0 +1,3 @@
1
+ export declare function isPathInside(root: string, target: string): boolean;
2
+ export declare function resolveWorkingDirInsideProject(projectRoot: string, inputPath: string): Promise<string>;
3
+ //# sourceMappingURL=path-containment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-containment.d.ts","sourceRoot":"","sources":["../../src/server/path-containment.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,wBAAsB,8BAA8B,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgC5G"}
@@ -0,0 +1,14 @@
1
+ export type ConfirmDecision = 'yes' | 'no' | 'always' | 'deny';
2
+ export interface PendingConfirm {
3
+ resolve: (decision: ConfirmDecision) => void;
4
+ decisionSource?: string | undefined;
5
+ riskTier?: 'safe' | 'standard' | 'destructive' | undefined;
6
+ /** The exact `tool.confirm_needed` broadcast payload, kept so the prompt
7
+ * can be replayed to clients that connect while the confirm is pending
8
+ * (e.g. a browser refresh mid-prompt). */
9
+ payload?: Record<string, unknown> | undefined;
10
+ }
11
+ export declare function isDestructivePendingConfirm(confirm: PendingConfirm): boolean;
12
+ export declare function resolveYoloEligiblePendingConfirms(pendingConfirms: Map<string, PendingConfirm>): void;
13
+ export declare function resolveAllPendingConfirms(pendingConfirms: Map<string, PendingConfirm>, decision: ConfirmDecision): void;
14
+ //# sourceMappingURL=pending-confirms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-confirms.d.ts","sourceRoot":"","sources":["../../src/server/pending-confirms.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;IAC3D;;+CAE2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC/C;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAE5E;AAED,wBAAgB,kCAAkC,CAChD,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAC3C,IAAI,CAKN;AAED,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EAC5C,QAAQ,EAAE,eAAe,GACxB,IAAI,CAKN"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Free-port discovery for the standalone WebUI server.
3
+ *
4
+ * When a user runs several instances, the default ports (HTTP 3456 / WS 3457)
5
+ * are taken by the first one. Rather than make the user hand-pick `PORT` /
6
+ * `WS_PORT` for every extra instance, the server probes upward from the
7
+ * requested port and binds the first free one — then stamps that real port into
8
+ * the served HTML and the instance registry so everything stays consistent.
9
+ *
10
+ * The probe binds a throwaway `net.Server`, then closes it, so there is a tiny
11
+ * TOCTOU window between "found free" and "the real server binds it". For local
12
+ * single-user multi-instance use that race is negligible; if it ever loses, the
13
+ * real bind fails loudly with EADDRINUSE exactly as before.
14
+ */
15
+ /** Resolve true when `port` can be bound on `host`, false on EADDRINUSE/EACCES. */
16
+ export declare function isPortFree(host: string, port: number): Promise<boolean>;
17
+ export interface FindFreePortOptions {
18
+ /** Ports to skip even if free (e.g. one already chosen for the sibling server). */
19
+ exclude?: Set<number> | undefined;
20
+ /** How many consecutive ports to try before giving up. Default 200. */
21
+ maxTries?: number | undefined;
22
+ }
23
+ /**
24
+ * Find the first free port at or above `startPort` on `host`, skipping any in
25
+ * `exclude`. Throws if nothing is free within `maxTries` steps.
26
+ */
27
+ export declare function findFreePort(host: string, startPort: number, opts?: FindFreePortOptions): Promise<number>;
28
+ //# sourceMappingURL=port-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-utils.d.ts","sourceRoot":"","sources":["../../src/server/port-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAavE;AAED,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAiBjB"}