@wrongstack/webui 0.155.0 → 0.250.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.
@@ -1,5 +1,5 @@
1
1
  import { WebSocket } from 'ws';
2
- import { Agent, EventBus, SessionWriter, ToolRegistry, ModelsRegistry, ConfigStore, SecretVault, ProviderConfig, ProviderApiKey } from '@wrongstack/core';
2
+ import { Agent, EventBus, SessionWriter, ToolRegistry, ModelsRegistry, ConfigStore, SecretVault, MemoryStore, ProviderConfig, ProviderApiKey, Context, Logger } from '@wrongstack/core';
3
3
  import * as http from 'node:http';
4
4
 
5
5
  interface WSServerMessage {
@@ -43,6 +43,12 @@ interface CreateHttpServerOptions {
43
43
  * is allowed to open a WebSocket back to the local server.
44
44
  */
45
45
  wsPort: number;
46
+ /**
47
+ * Path to the global WrongStack root (~/.wrongstack). Used by the
48
+ * /api/sessions and /api/sessions/:id/agents endpoints to read the
49
+ * cross-process SessionRegistry.
50
+ */
51
+ globalRoot?: string | undefined;
46
52
  }
47
53
  /**
48
54
  * Inject the live WS port into the served HTML so the frontend connects to
@@ -192,6 +198,118 @@ declare function errMessage(err: unknown): string;
192
198
  */
193
199
  declare function generateAuthToken(): string;
194
200
 
201
+ /**
202
+ * Shared file-operation WebSocket handlers for both the standalone WebUI
203
+ * server and the CLI's `--webui` embedded server. Extracted from the
204
+ * duplicated switch cases in `index.ts` and `cli/src/webui-server.ts`.
205
+ *
206
+ * Each function handles the full request→response cycle for one message
207
+ * type. Callers drop them into their switch statement:
208
+ *
209
+ * case 'files.tree': return handleFilesTree(ws, msg, projectRoot);
210
+ */
211
+
212
+ /**
213
+ * Build and send a nested directory tree for the File Explorer.
214
+ *
215
+ * Walks `projectRoot` to depth 10 max, skipping heavyweight dirs
216
+ * (node_modules, .git, dist, …) and dot-entries. Responds with
217
+ * `{ type: 'files.tree', payload: { root, tree } }`.
218
+ */
219
+ declare function handleFilesTree(ws: WebSocket, msg: unknown, projectRoot: string): Promise<void>;
220
+ /**
221
+ * Read a file's content for the Monaco editor.
222
+ *
223
+ * Guards against path traversal (`../` escapes). Responds with
224
+ * `{ type: 'files.read', payload: { filePath, content } }`.
225
+ */
226
+ declare function handleFilesRead(ws: WebSocket, msg: unknown, projectRoot: string): Promise<void>;
227
+ /**
228
+ * Write file content back to disk (atomic write via tmp + rename).
229
+ *
230
+ * Guards against path traversal. Responds with
231
+ * `{ type: 'files.written', payload: { filePath, success } }`.
232
+ */
233
+ declare function handleFilesWrite(ws: WebSocket, msg: unknown, projectRoot: string): Promise<void>;
234
+ /**
235
+ * Lightweight project file picker for the chat `@` mention popup.
236
+ *
237
+ * Walks `projectRoot` (max depth 8), skipping hidden and heavyweight
238
+ * dirs, then fuzzy-ranks results against `query`. Responds with
239
+ * `{ type: 'files.list', payload: { files } }`.
240
+ */
241
+ declare function handleFilesList(ws: WebSocket, msg: unknown, projectRoot: string): Promise<void>;
242
+
243
+ /**
244
+ * Shared memory-operation WebSocket handlers for both the standalone WebUI
245
+ * server and the CLI's `--webui` embedded server. Extracted from the
246
+ * duplicated switch cases in `index.ts` and `cli/src/webui-server.ts`.
247
+ *
248
+ * Each function handles the full request→response cycle for one message
249
+ * type. Callers drop them into their switch statement:
250
+ *
251
+ * case 'memory.list': return handleMemoryList(ws, memoryStore);
252
+ */
253
+
254
+ /**
255
+ * List all memory entries across all scopes.
256
+ * Responds with `{ type: 'memory.list', payload: { text } }`.
257
+ */
258
+ declare function handleMemoryList(ws: WebSocket, memoryStore: MemoryStore): Promise<void>;
259
+ /**
260
+ * Persist a new memory entry.
261
+ * Responds with `{ type: 'key.operation_result', payload: { success, message } }`.
262
+ */
263
+ declare function handleMemoryRemember(ws: WebSocket, msg: unknown, memoryStore: MemoryStore): Promise<void>;
264
+ /**
265
+ * Remove memory entries matching the given text.
266
+ * Responds with `{ type: 'key.operation_result', payload: { success, message } }`.
267
+ */
268
+ declare function handleMemoryForget(ws: WebSocket, msg: unknown, memoryStore: MemoryStore): Promise<void>;
269
+
270
+ /**
271
+ * Custom context modes — user-defined presets that are loaded from disk,
272
+ * merged with the built-in modes, and managed via WebSocket CRUD handlers.
273
+ *
274
+ * Stored in: ~/.wrongstack/custom-context-modes.json
275
+ * Format: { "modes": ContextWindowMode[] }
276
+ */
277
+ interface CustomContextMode {
278
+ id: string;
279
+ name: string;
280
+ description: string;
281
+ thresholds: {
282
+ warn: number;
283
+ soft: number;
284
+ hard: number;
285
+ };
286
+ aggressiveOn: string;
287
+ preserveK: number;
288
+ eliseThreshold: number;
289
+ targetLoad: number;
290
+ /** Whether this is a user-defined (custom) or built-in mode. */
291
+ custom: boolean;
292
+ }
293
+ interface CustomModeStore {
294
+ modes: Map<string, CustomContextMode>;
295
+ load: () => Promise<void>;
296
+ save: () => Promise<void>;
297
+ create: (mode: CustomContextMode) => {
298
+ ok: boolean;
299
+ error?: string | undefined;
300
+ };
301
+ update: (id: string, patch: Partial<CustomContextMode>) => {
302
+ ok: boolean;
303
+ error?: string | undefined;
304
+ };
305
+ remove: (id: string) => {
306
+ ok: boolean;
307
+ error?: string | undefined;
308
+ };
309
+ list: () => CustomContextMode[];
310
+ }
311
+ declare function createCustomModeStore(wrongstackDir: string): CustomModeStore;
312
+
195
313
  /** A hostname that refers to the local machine. */
196
314
  declare function isLoopbackHostname(hostname: string): boolean;
197
315
  /** True when the server is bound to a loopback interface (vs. LAN/0.0.0.0). */
@@ -312,10 +430,60 @@ declare function createProviderConfigIO(configPath: string): {
312
430
  save: (providers: Record<string, ProviderConfig>) => Promise<void>;
313
431
  };
314
432
 
433
+ interface AutoPhaseWSMessage {
434
+ type: string;
435
+ payload?: Record<string, unknown>;
436
+ }
437
+ /**
438
+ * AutoPhaseWebSocketHandler — WebSocket-based AutoPhase control.
439
+ *
440
+ * Message types:
441
+ * autophase.start → { title, phases?, autonomous? }
442
+ * autophase.pause → {}
443
+ * autophase.resume → {}
444
+ * autophase.stop → {}
445
+ * autophase.status → {}
446
+ * autophase.selectPhase → { phaseId }
447
+ * autophase.taskStatus → { taskId, status }
448
+ */
449
+ declare class AutoPhaseWebSocketHandler {
450
+ private agent;
451
+ private context;
452
+ private logger;
453
+ private events?;
454
+ private projectRoot?;
455
+ private orchestrator;
456
+ private graph;
457
+ private store;
458
+ private clients;
459
+ private broadcastInterval;
460
+ /** Aborts in-flight task agents when the run is stopped. */
461
+ private abort;
462
+ /** Optional per-phase git-worktree isolation (lazily created at start). */
463
+ private worktrees;
464
+ constructor(agent: Agent, context: Context, logger: Logger, storeDir: string, events?: EventBus | undefined, projectRoot?: string | undefined);
465
+ addClient(ws: WebSocket): void;
466
+ handleMessage(msg: AutoPhaseWSMessage): Promise<void>;
467
+ private handleStart;
468
+ /** Generic fallback phases when the LLM planner produces nothing usable. */
469
+ private defaultPhases;
470
+ /** Plan phases+todos for the goal via the LLM; fall back to defaults on failure. */
471
+ private planPhases;
472
+ private executeTaskWithAgent;
473
+ private handleTaskStatusChange;
474
+ private startBroadcast;
475
+ private stopBroadcast;
476
+ private broadcastState;
477
+ private buildState;
478
+ private sendState;
479
+ private broadcast;
480
+ private send;
481
+ }
482
+
315
483
  declare function startWebUI(opts?: {
316
484
  wsPort?: number | undefined;
317
485
  wsHost?: string | undefined;
318
486
  open?: boolean | undefined;
319
487
  }): Promise<void>;
320
488
 
321
- export { type BackendServices, type ConnectedClient, type KeyOpResult, type ProvidersRecord, type VerifyClientInput, type WSClientMessage, type WSServerMessage, type WebUIInstanceRecord, type WebUIOptions, addProvider, broadcast, browserOpenCommand, buildCspHeader, createHttpServer, createProviderConfigIO, defaultBaseDir, deleteKey, errMessage, extractToken, findFreePort, formatInstances, generateAuthToken, hostHeaderOk, injectWsPort, isLoopbackBind, isLoopbackHostname, isPortFree, listInstances, loadSavedProviders, maskedKey, normalizeKeys, openBrowser, registerInstance, registryPath, removeProvider, saveProviders, send, sendResult, setActiveKey, startWebUI, tokenMatches, unregisterInstance, upsertKey, verifyClient, writeKeysBack };
489
+ export { AutoPhaseWebSocketHandler, type BackendServices, type ConnectedClient, type CustomContextMode, type CustomModeStore, type KeyOpResult, type ProvidersRecord, type VerifyClientInput, type WSClientMessage, type WSServerMessage, type WebUIInstanceRecord, type WebUIOptions, addProvider, broadcast, browserOpenCommand, buildCspHeader, createCustomModeStore, createHttpServer, createProviderConfigIO, defaultBaseDir, deleteKey, errMessage, extractToken, findFreePort, formatInstances, generateAuthToken, handleFilesList, handleFilesRead, handleFilesTree, handleFilesWrite, handleMemoryForget, handleMemoryList, handleMemoryRemember, hostHeaderOk, injectWsPort, isLoopbackBind, isLoopbackHostname, isPortFree, listInstances, loadSavedProviders, maskedKey, normalizeKeys, openBrowser, registerInstance, registryPath, removeProvider, saveProviders, send, sendResult, setActiveKey, startWebUI, tokenMatches, unregisterInstance, upsertKey, verifyClient, writeKeysBack };