@wrongstack/webui-server 0.309.0 → 0.310.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 (48) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +17839 -18568
  3. package/dist/server/collab/annotations.d.ts +26 -0
  4. package/dist/server/collab/broadcast-scheduler.d.ts +30 -0
  5. package/dist/server/collab/collab-context.d.ts +60 -0
  6. package/dist/server/collab/controller.d.ts +25 -0
  7. package/dist/server/collab/dispatcher.d.ts +27 -0
  8. package/dist/server/collab/injection.d.ts +26 -0
  9. package/dist/server/collab/membership.d.ts +20 -0
  10. package/dist/server/collab/mirror.d.ts +14 -0
  11. package/dist/server/collab/replay.d.ts +20 -0
  12. package/dist/server/collab/session-registry.d.ts +74 -0
  13. package/dist/server/collaboration-ws-handler.d.ts +28 -149
  14. package/dist/server/embedded-host-adapters.d.ts +4 -4
  15. package/dist/server/entry.js +16918 -17411
  16. package/dist/server/frontend-static-serve.d.ts +2 -0
  17. package/dist/server/index.d.ts +25 -25
  18. package/dist/server/open-browser.d.ts +9 -0
  19. package/dist/server/pre-context-services.d.ts +2 -1
  20. package/dist/server/provider/catalog.d.ts +15 -0
  21. package/dist/server/provider/custom-models.d.ts +13 -0
  22. package/dist/server/provider/keys-records.d.ts +2 -0
  23. package/dist/server/provider/keys.d.ts +36 -0
  24. package/dist/server/provider/mutations.d.ts +34 -0
  25. package/dist/server/provider/oauth.d.ts +17 -0
  26. package/dist/server/provider/probe.d.ts +9 -0
  27. package/dist/server/provider/projection.d.ts +50 -0
  28. package/dist/server/provider-handlers.d.ts +38 -87
  29. package/dist/server/standalone-session-identity.d.ts +2 -1
  30. package/dist/server/token-estimator.d.ts +19 -8
  31. package/package.json +13 -16
  32. package/dist/protocol/client-conversation.d.ts +0 -3
  33. package/dist/protocol/client-integrations.d.ts +0 -3
  34. package/dist/protocol/client-operations.d.ts +0 -3
  35. package/dist/protocol/client-workspace.d.ts +0 -3
  36. package/dist/protocol/connection-fsm.d.ts +0 -39
  37. package/dist/protocol/decoder.d.ts +0 -6
  38. package/dist/protocol/index.d.ts +0 -8
  39. package/dist/protocol/index.js +0 -960
  40. package/dist/protocol/projections.d.ts +0 -131
  41. package/dist/protocol/registry.d.ts +0 -6
  42. package/dist/protocol/replay-payload.d.ts +0 -41
  43. package/dist/protocol/server-conversation.d.ts +0 -3
  44. package/dist/protocol/server-integrations.d.ts +0 -3
  45. package/dist/protocol/server-operations.d.ts +0 -4
  46. package/dist/protocol/server-workspace.d.ts +0 -3
  47. package/dist/protocol/types.d.ts +0 -24
  48. package/dist/protocol/version.d.ts +0 -26
@@ -1,960 +0,0 @@
1
- // src/protocol/connection-fsm.ts
2
- var DEFAULT_SURFACE_CONNECTION_CONFIG = {
3
- maxReconnectAttempts: 10,
4
- initialBackoffMs: 1e3,
5
- maxBackoffMs: 3e4,
6
- backoffMultiplier: 2,
7
- jitterRatio: 0,
8
- queueLimit: 1e3,
9
- heartbeatIntervalMs: 0,
10
- heartbeatTimeoutMs: 0
11
- };
12
- function createSurfaceConnectionState() {
13
- return { phase: "idle", reconnectAttempt: 0, lastActivityAt: null, stopped: false };
14
- }
15
- function markConnectionConnecting(state) {
16
- if (state.stopped) return state;
17
- return { ...state, phase: "connecting" };
18
- }
19
- function markConnectionOpen(state, now = Date.now()) {
20
- return {
21
- ...state,
22
- phase: "open",
23
- reconnectAttempt: 0,
24
- lastActivityAt: now,
25
- stopped: false
26
- };
27
- }
28
- function markConnectionActivity(state, now = Date.now()) {
29
- return { ...state, lastActivityAt: now };
30
- }
31
- function stopConnection(state) {
32
- return { ...state, phase: "closed", stopped: true };
33
- }
34
- function resetConnection(state) {
35
- return { ...state, phase: "idle", reconnectAttempt: 0, stopped: false };
36
- }
37
- function planConnectionReconnect(state, config, now = Date.now(), random = Math.random) {
38
- if (state.stopped || state.reconnectAttempt >= config.maxReconnectAttempts) {
39
- return { state: { ...state, phase: "closed" }, plan: null };
40
- }
41
- const attempt = state.reconnectAttempt + 1;
42
- const base = Math.min(
43
- config.initialBackoffMs * config.backoffMultiplier ** (attempt - 1),
44
- config.maxBackoffMs
45
- );
46
- const centeredJitter = (random() * 2 - 1) * config.jitterRatio;
47
- const delayMs = Math.max(0, Math.round(base * (1 + centeredJitter)));
48
- return {
49
- state: { ...state, phase: "reconnecting", reconnectAttempt: attempt },
50
- plan: { attempt, delayMs, retryAt: now + delayMs }
51
- };
52
- }
53
- function isConnectionHeartbeatTimedOut(state, config, now = Date.now()) {
54
- if (state.phase !== "open" || state.lastActivityAt === null) return false;
55
- if (config.heartbeatIntervalMs <= 0) return false;
56
- return now - state.lastActivityAt > config.heartbeatIntervalMs + config.heartbeatTimeoutMs;
57
- }
58
- function enqueueBounded(queue, item, limit) {
59
- if (limit <= 0) return { queue: [], dropped: item };
60
- if (queue.length < limit) return { queue: [...queue, item], dropped: null };
61
- return { queue: [...queue.slice(queue.length - limit + 1), item], dropped: queue[0] ?? null };
62
- }
63
-
64
- // src/protocol/client-conversation.ts
65
- var CLIENT_CONVERSATION_MESSAGE_TYPES = [
66
- "abort",
67
- "ping",
68
- "user_message",
69
- "tool.confirm_result",
70
- "topic.advice",
71
- "completion.request",
72
- "model.switch",
73
- "model.refine",
74
- "model.fallback_choice",
75
- "autonomy.switch",
76
- "context.clear",
77
- "context.compact",
78
- "context.debug",
79
- "context.editor.open",
80
- "context.editor.validate",
81
- "context.editor.apply",
82
- "context.mode.create",
83
- "context.mode.delete",
84
- "context.mode.switch",
85
- "context.mode.update",
86
- "context.modes.list",
87
- "context.repair",
88
- "mode.switch",
89
- "modes.list",
90
- "session.checkpoints",
91
- "session.delete",
92
- "session.inspect",
93
- "session.new",
94
- "session.rename",
95
- "session.resume",
96
- "session.rewind",
97
- "session.save",
98
- "sessions.list",
99
- "side_effects.list",
100
- "stats.get",
101
- "todo.update",
102
- "todos.clear",
103
- "todos.get",
104
- "todos.remove"
105
- ];
106
- var CLIENT_COLLABORATION_MESSAGE_TYPES = [
107
- "collab.join",
108
- "collab.leave",
109
- "collab.annotate",
110
- "collab.resolve",
111
- "collab.request_pause",
112
- "collab.resume",
113
- "collab.grant_control",
114
- "collab.inject_tool",
115
- "mailbox.action",
116
- "mailbox.agents",
117
- "mailbox.clear",
118
- "mailbox.compact",
119
- "mailbox.messages",
120
- "mailbox.purge",
121
- "mailbox.send"
122
- ];
123
-
124
- // src/protocol/client-integrations.ts
125
- var CLIENT_KNOWLEDGE_MESSAGE_TYPES = [
126
- "brain.ask",
127
- "brain.config.get",
128
- "brain.config.set",
129
- "brain.risk",
130
- "brain.status",
131
- "chronicle.facet",
132
- "chronicle.facets",
133
- "chronicle.graph",
134
- "chronicle.metrics",
135
- "chronicle.query",
136
- "chronicle.status",
137
- "config.doctor",
138
- "design.list",
139
- "design.materialize",
140
- "design.set",
141
- "design.state",
142
- "design.swap",
143
- "design.tune",
144
- "design.use",
145
- "design.verify",
146
- "memory.list",
147
- "memory.sage.backfillRecoverable",
148
- "memory.sage.candidateResolve",
149
- "memory.sage.delete",
150
- "memory.sage.forFile",
151
- "memory.sage.get",
152
- "memory.sage.graph",
153
- "memory.sage.list",
154
- "memory.sage.listCandidates",
155
- "memory.sage.listPage",
156
- "memory.sage.recover",
157
- "memory.sage.remember",
158
- "memory.sage.searchBreakdown",
159
- "memory.sage.update"
160
- ];
161
- var CLIENT_EXTENSION_MESSAGE_TYPES = [
162
- "auth.oauth.cancel",
163
- "auth.oauth.code",
164
- "auth.oauth.start",
165
- "mcp.add",
166
- "mcp.disable",
167
- "mcp.discover",
168
- "mcp.enable",
169
- "mcp.list",
170
- "mcp.prompt.get",
171
- "mcp.prompts",
172
- "mcp.remove",
173
- "mcp.resource.read",
174
- "mcp.resources",
175
- "mcp.restart",
176
- "mcp.sleep",
177
- "mcp.update",
178
- "mcp.wake",
179
- "prompts.content",
180
- "prompts.create",
181
- "prompts.favorite",
182
- "prompts.journal",
183
- "prompts.list",
184
- "prompts.recent",
185
- "prompts.search",
186
- "prompts.used",
187
- "skills.content",
188
- "skills.create",
189
- "skills.edit",
190
- "skills.export",
191
- "skills.install",
192
- "skills.list",
193
- "skills.uninstall",
194
- "skills.update"
195
- ];
196
-
197
- // src/protocol/client-operations.ts
198
- var CLIENT_GOAL_MESSAGE_TYPES = [
199
- "goal-state.get",
200
- "goal.addTask",
201
- "goal.assess",
202
- "goal.assignTask",
203
- "goal.clear",
204
- "goal.get",
205
- "goal.list",
206
- "goal.load",
207
- "goal.moveTask",
208
- "goal.pause",
209
- "goal.resume",
210
- "goal.retryTask",
211
- "goal.revert",
212
- "goal.runTask",
213
- "goal.save",
214
- "goal.selectPhase",
215
- "goal.start",
216
- "goal.state",
217
- "goal.status",
218
- "goal.stop",
219
- "goal.taskStatus",
220
- "goal.toggleAutonomous",
221
- "plan.get",
222
- "plan.item.update",
223
- "plan.template_use",
224
- "task.update",
225
- "tasks.get"
226
- ];
227
- var CLIENT_SDD_MESSAGE_TYPES = [
228
- "sdd.board.cancel_task",
229
- "sdd.board.cleanup_worktrees",
230
- "sdd.board.delete_task",
231
- "sdd.board.destroy",
232
- "sdd.board.get",
233
- "sdd.board.list",
234
- "sdd.board.pause",
235
- "sdd.board.reassign",
236
- "sdd.board.resume",
237
- "sdd.board.retry",
238
- "sdd.board.retry_all_failed",
239
- "sdd.board.rollback",
240
- "sdd.board.set_task_fallbacks",
241
- "sdd.board.set_task_model",
242
- "sdd.board.set_task_verification",
243
- "sdd.board.split_task",
244
- "sdd.board.stop",
245
- "sdd.run.from_graph",
246
- "sdd.run.from_spec",
247
- "sdd.run.start",
248
- "sdd.spec.approve",
249
- "sdd.spec.discard",
250
- "sdd.spec.get",
251
- "sdd.spec.message",
252
- "sdd.spec.rewind",
253
- "sdd.spec.start",
254
- "specs.get",
255
- "specs.list",
256
- "specs.taskStatus"
257
- ];
258
-
259
- // src/protocol/client-workspace.ts
260
- var CLIENT_WORKSPACE_MESSAGE_TYPES = [
261
- "files.create",
262
- "files.delete",
263
- "files.list",
264
- "files.move",
265
- "files.read",
266
- "files.rename",
267
- "files.skeleton",
268
- "files.tree",
269
- "files.write",
270
- "git.changes",
271
- "git.diff",
272
- "git.info",
273
- "projects.add",
274
- "projects.list",
275
- "projects.select",
276
- "working_dir.set",
277
- "worktree.cleanup",
278
- "worktree.diff",
279
- "worktree.merge",
280
- "worktree.remove",
281
- "worktree.scan",
282
- "shell.open",
283
- "process.kill",
284
- "process.killAll",
285
- "process.list",
286
- "terminal.close",
287
- "terminal.create",
288
- "terminal.input",
289
- "terminal.resize"
290
- ];
291
- var CLIENT_CONFIGURATION_MESSAGE_TYPES = [
292
- "codebase.index.server.shutdown",
293
- "connections.health",
294
- "connections.service_action",
295
- "diag.get",
296
- "key.add",
297
- "key.delete",
298
- "key.set_active",
299
- "key.update",
300
- "prefs.get",
301
- "prefs.update",
302
- "provider.add",
303
- "provider.clear_models",
304
- "provider.custom_models.remove",
305
- "provider.custom_models.set",
306
- "provider.models",
307
- "provider.models.search",
308
- "provider.probe",
309
- "provider.remove",
310
- "provider.status.clear",
311
- "provider.status.get",
312
- "provider.status.retry",
313
- "provider.undo_clear",
314
- "provider.update",
315
- "providers.list",
316
- "providers.saved",
317
- "tool.disable",
318
- "tool.enable",
319
- "tools.list",
320
- "webui.shutdown"
321
- ];
322
-
323
- // src/protocol/server-conversation.ts
324
- var SERVER_CONVERSATION_MESSAGE_TYPES = [
325
- "error",
326
- "log",
327
- "pong",
328
- "side_effects",
329
- "agent.status_changed",
330
- "agent.timeline.message",
331
- "client.status_update",
332
- "chimera.report_available",
333
- "compaction.failed",
334
- "completion.result",
335
- "context.compacted",
336
- "context.debug",
337
- "context.editor.snapshot",
338
- "context.editor.validation",
339
- "context.editor.applied",
340
- "context.mode.changed",
341
- "context.modes.list",
342
- "context.repaired",
343
- "ctx.max_context",
344
- "ctx.pct",
345
- "delegate.completed",
346
- "delegate.started",
347
- "iteration.completed",
348
- "iteration.limit_reached",
349
- "iteration.started",
350
- "model.refine_result",
351
- "modes.list",
352
- "provider.active_blocked",
353
- "provider.error",
354
- "provider.fallback",
355
- "provider.fallback_pending",
356
- "provider.response",
357
- "provider.retry",
358
- "provider.status_changed",
359
- "provider.stream_error",
360
- "provider.text_delta",
361
- "provider.thinking_delta",
362
- "run.result",
363
- "session.checkpoints",
364
- "session.damaged",
365
- "session.end",
366
- "session.inspect",
367
- "session.rewound",
368
- "session.start",
369
- "session.stats",
370
- "sessions.list",
371
- "sessions.status_update",
372
- "stats.get",
373
- "token.cost_estimate_unavailable",
374
- "token.threshold",
375
- "tool.confirm_needed",
376
- "tool.disabled",
377
- "tool.enabled",
378
- "tool.executed",
379
- "tool.loop_detected",
380
- "tool.progress",
381
- "tool.started",
382
- "topic.advice_result",
383
- "tools.list",
384
- "trust.persisted"
385
- ];
386
- var SERVER_COLLABORATION_MESSAGE_TYPES = [
387
- "collab.annotation.added",
388
- "collab.annotation.resolved",
389
- "collab.event",
390
- "collab.injection.granted",
391
- "collab.participant.joined",
392
- "collab.participant.left",
393
- "collab.pause.granted",
394
- "collab.pause.released",
395
- "collab.state",
396
- "mailbox.action_result",
397
- "mailbox.agent_registered",
398
- "mailbox.agent_deregistered",
399
- "mailbox.agents",
400
- "mailbox.cleared",
401
- "mailbox.compacted",
402
- "mailbox.event",
403
- "mailbox.messages",
404
- "mailbox.sent",
405
- "mailbox.purged",
406
- "mailbox.received",
407
- "subagent.budget_extended",
408
- "subagent.event"
409
- ];
410
-
411
- // src/protocol/server-integrations.ts
412
- var SERVER_KNOWLEDGE_MESSAGE_TYPES = [
413
- "brain.answer",
414
- "brain.config",
415
- "brain.event",
416
- "brain.status",
417
- "chronicle.error",
418
- "chronicle.facet_result",
419
- "chronicle.facets_result",
420
- "chronicle.graph_result",
421
- "chronicle.metrics_result",
422
- "chronicle.query_result",
423
- "chronicle.status_result",
424
- "config.doctor.result",
425
- "design.list",
426
- "design.materialize",
427
- "design.set",
428
- "design.state",
429
- "design.swap",
430
- "design.tune",
431
- "design.use",
432
- "design.verify",
433
- "memory.event",
434
- "memory.list",
435
- "memory.sage.backfillRecoverable",
436
- "memory.sage.candidateResolve",
437
- "memory.sage.delete",
438
- "memory.sage.forFile",
439
- "memory.sage.get",
440
- "memory.sage.graph",
441
- "memory.sage.list",
442
- "memory.sage.listCandidates",
443
- "memory.sage.listPage",
444
- "memory.sage.recover",
445
- "memory.sage.remember",
446
- "memory.sage.searchBreakdown",
447
- "memory.sage.update"
448
- ];
449
- var SERVER_EXTENSION_MESSAGE_TYPES = [
450
- "mcp.content.error",
451
- "mcp.content.selected",
452
- "mcp.list",
453
- "mcp.operation_result",
454
- "mcp.prompts",
455
- "mcp.resources",
456
- "mcp.server.added",
457
- "mcp.server.connected",
458
- "mcp.server.disconnected",
459
- "mcp.server.discovered",
460
- "mcp.server.error",
461
- "mcp.server.reconnected",
462
- "mcp.server.removed",
463
- "mcp.server.sleeping",
464
- "mcp.server.updated",
465
- "mcp.server.waking",
466
- "prompts.content",
467
- "prompts.created",
468
- "prompts.favorite",
469
- "prompts.journal",
470
- "prompts.list",
471
- "prompts.recent",
472
- "prompts.search",
473
- "prompts.used",
474
- "skills.content",
475
- "skills.created",
476
- "skills.edited",
477
- "skills.exported",
478
- "skills.installed",
479
- "skills.list",
480
- "skills.uninstalled",
481
- "skills.updated"
482
- ];
483
-
484
- // src/protocol/server-operations.ts
485
- var SERVER_GOAL_MESSAGE_TYPES = [
486
- "budget.decision",
487
- "budget.threshold_reached",
488
- "coordinator.stats",
489
- "coordinator.status",
490
- "eternal.iteration",
491
- "fleet.concurrency_update",
492
- "goal-state.updated",
493
- "goal.assess.result",
494
- "goal.list",
495
- "goal.paused",
496
- "goal.resumed",
497
- "goal.saved",
498
- "goal.error",
499
- "goal.stopped",
500
- "goal.failed",
501
- "goal.completed",
502
- "goal.cleared",
503
- "goal.reverted",
504
- "goal.progress",
505
- "goal.state",
506
- "in_flight.ended",
507
- "in_flight.started",
508
- "plan.updated",
509
- "task.completed",
510
- "task.failed",
511
- "task.pending",
512
- "task.started",
513
- "tasks.updated",
514
- "todos.cleared",
515
- "todos.updated"
516
- ];
517
- var SERVER_SDD_MESSAGE_TYPES = [
518
- "kanban.task.activity",
519
- "sdd.board.lifecycle_result",
520
- "sdd.board.list",
521
- "sdd.board.snapshot",
522
- "sdd.run.started",
523
- "sdd.spec.agent_text",
524
- "sdd.spec.error",
525
- "sdd.spec.snapshot",
526
- "specs.detail",
527
- "specs.list"
528
- ];
529
- var SERVER_AUTOMATION_MESSAGE_TYPES = [
530
- "consensus.vote_cast",
531
- "consensus.vote_initiated",
532
- "consensus.vote_resolved",
533
- "cron.job_fired",
534
- "cron.snapshot",
535
- "techstack.job.cancelled",
536
- "techstack.job.failed",
537
- "techstack.job.progress",
538
- "techstack.job.started",
539
- "techstack.report.delivered",
540
- "techstack.report.ready",
541
- "techstack.snapshot.updated",
542
- "techstack.workspace.completed"
543
- ];
544
-
545
- // src/protocol/server-workspace.ts
546
- var SERVER_WORKSPACE_MESSAGE_TYPES = [
547
- "checkpoint.written",
548
- "codemap.file_event",
549
- "codemap.index_updated",
550
- "codemap.tool_executed",
551
- "codemap.tool_started",
552
- "file.saved",
553
- "files.created",
554
- "files.deleted",
555
- "files.list",
556
- "files.moved",
557
- "files.read",
558
- "files.renamed",
559
- "files.skeleton_result",
560
- "files.tree",
561
- "files.tree.changed",
562
- "files.written",
563
- "git.changes",
564
- "git.diff",
565
- "git.info",
566
- "process.list",
567
- "projects.added",
568
- "projects.list",
569
- "projects.selected",
570
- "terminal.exit",
571
- "terminal.output",
572
- "working_dir.changed",
573
- "worktree.cleanup_result",
574
- "worktree.diff_result",
575
- "worktree.event",
576
- "worktree.merge_result",
577
- "worktree.orphans",
578
- "worktree.state"
579
- ];
580
- var SERVER_CONFIGURATION_MESSAGE_TYPES = [
581
- "auth.oauth.status",
582
- "codebase.index.server.shutdown_result",
583
- "connections.auto_heal_status",
584
- "connections.health_error",
585
- "connections.health_result",
586
- "connections.service_action_result",
587
- "diag.get",
588
- "key.operation_result",
589
- "model.switch_result",
590
- "prefs.updated",
591
- "provider.catalog",
592
- "provider.models",
593
- "provider.models.search_result",
594
- "provider.probe",
595
- "provider.status.snapshot",
596
- "providers.saved"
597
- ];
598
-
599
- // src/protocol/registry.ts
600
- var CLIENT_MESSAGE_TYPES = [
601
- ...CLIENT_CONVERSATION_MESSAGE_TYPES,
602
- ...CLIENT_COLLABORATION_MESSAGE_TYPES,
603
- ...CLIENT_WORKSPACE_MESSAGE_TYPES,
604
- ...CLIENT_CONFIGURATION_MESSAGE_TYPES,
605
- ...CLIENT_GOAL_MESSAGE_TYPES,
606
- ...CLIENT_SDD_MESSAGE_TYPES,
607
- ...CLIENT_KNOWLEDGE_MESSAGE_TYPES,
608
- ...CLIENT_EXTENSION_MESSAGE_TYPES
609
- ];
610
- var SERVER_MESSAGE_TYPES = [
611
- ...SERVER_CONVERSATION_MESSAGE_TYPES,
612
- ...SERVER_COLLABORATION_MESSAGE_TYPES,
613
- ...SERVER_WORKSPACE_MESSAGE_TYPES,
614
- ...SERVER_CONFIGURATION_MESSAGE_TYPES,
615
- ...SERVER_GOAL_MESSAGE_TYPES,
616
- ...SERVER_SDD_MESSAGE_TYPES,
617
- ...SERVER_AUTOMATION_MESSAGE_TYPES,
618
- ...SERVER_KNOWLEDGE_MESSAGE_TYPES,
619
- ...SERVER_EXTENSION_MESSAGE_TYPES
620
- ];
621
- var CLIENT_TYPE_SET = new Set(CLIENT_MESSAGE_TYPES);
622
- var SERVER_TYPE_SET = new Set(SERVER_MESSAGE_TYPES);
623
- function isRegisteredMessageType(type, direction) {
624
- const exact = direction === "client" ? CLIENT_TYPE_SET : SERVER_TYPE_SET;
625
- return exact.has(type) || type.startsWith("kanban.") && type.length > "kanban.".length || type.startsWith("agent-roster.") && type.length > "agent-roster.".length;
626
- }
627
-
628
- // src/protocol/decoder.ts
629
- var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
630
- var MAX_PAYLOAD_DEPTH = 32;
631
- function inspectValue(value, path, depth) {
632
- if (depth > MAX_PAYLOAD_DEPTH) {
633
- return { code: "too_deep", message: "Protocol payload exceeds the nesting limit", path };
634
- }
635
- if (value === null || typeof value !== "object") return null;
636
- for (const key of Object.keys(value)) {
637
- const childPath = `${path}.${key}`;
638
- if (FORBIDDEN_KEYS.has(key)) {
639
- return { code: "unsafe_key", message: `Unsafe protocol key: ${key}`, path: childPath };
640
- }
641
- const issue = inspectValue(value[key], childPath, depth + 1);
642
- if (issue) return issue;
643
- }
644
- return null;
645
- }
646
- function decodeProtocolMessage(input, direction) {
647
- if (input === null || typeof input !== "object" || Array.isArray(input)) {
648
- return {
649
- ok: false,
650
- issue: { code: "invalid_envelope", message: "Protocol message must be an object" }
651
- };
652
- }
653
- const envelope = input;
654
- if (typeof envelope["type"] !== "string" || envelope["type"].length === 0) {
655
- return {
656
- ok: false,
657
- issue: { code: "invalid_type", message: "Protocol message type must be a non-empty string" }
658
- };
659
- }
660
- if (!isRegisteredMessageType(envelope["type"], direction)) {
661
- return {
662
- ok: false,
663
- issue: { code: "unknown_type", message: `Unknown ${direction} message: ${envelope["type"]}` }
664
- };
665
- }
666
- if (direction === "server" && !Object.hasOwn(envelope, "payload")) {
667
- return {
668
- ok: false,
669
- issue: { code: "invalid_envelope", message: "Server protocol messages require a payload" }
670
- };
671
- }
672
- const issue = inspectValue(envelope, "$", 0);
673
- if (issue) return { ok: false, issue };
674
- return { ok: true, message: input };
675
- }
676
- function decodeProtocolFrame(frame, direction) {
677
- try {
678
- return decodeProtocolMessage(JSON.parse(frame), direction);
679
- } catch {
680
- return {
681
- ok: false,
682
- issue: { code: "invalid_envelope", message: "Protocol frame is not valid JSON" }
683
- };
684
- }
685
- }
686
-
687
- // src/protocol/projections.ts
688
- function record(value) {
689
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
690
- }
691
- function text(value, fallback = "") {
692
- return typeof value === "string" ? value : fallback;
693
- }
694
- function finite(value, fallback = 0) {
695
- return typeof value === "number" && Number.isFinite(value) ? value : fallback;
696
- }
697
- function optionalArray(value) {
698
- return value === void 0 || Array.isArray(value);
699
- }
700
- function isValidHqTotals(totals) {
701
- return finite(totals["activeProjects"]) === totals["activeProjects"] && finite(totals["activeClients"]) === totals["activeClients"] && finite(totals["activeSessions"]) === totals["activeSessions"] && finite(totals["activeSubagents"]) === totals["activeSubagents"] && finite(totals["unreadMailboxMessages"]) === totals["unreadMailboxMessages"] && finite(totals["incompleteMailboxMessages"]) === totals["incompleteMailboxMessages"] && finite(totals["totalCostUsd"]) === totals["totalCostUsd"];
702
- }
703
- function projectSessionMessage(message) {
704
- if (message.type !== "session.start") return null;
705
- const payload = record(message.payload);
706
- if (!payload) return null;
707
- return {
708
- kind: "session",
709
- id: text(payload["sessionId"]),
710
- provider: text(payload["provider"]),
711
- model: text(payload["model"]),
712
- projectName: text(payload["projectName"], "Project"),
713
- cwd: text(payload["cwd"]),
714
- maxContext: finite(payload["maxContext"]),
715
- reset: payload["reset"] === true,
716
- replayMessages: Array.isArray(payload["replayMessages"]) ? payload["replayMessages"] : null,
717
- replayMarkers: Array.isArray(payload["replayMarkers"]) ? payload["replayMarkers"] : null,
718
- replayUsage: record(payload["replayUsage"])
719
- };
720
- }
721
- function projectChatMessage(message) {
722
- const payload = record(message.payload);
723
- if (!payload) return null;
724
- switch (message.type) {
725
- case "provider.thinking_delta": {
726
- const value = text(payload["text"]);
727
- return value ? { kind: "thinking-delta", text: value } : null;
728
- }
729
- case "provider.text_delta": {
730
- const value = text(payload["text"]);
731
- return value ? { kind: "text-delta", text: value, messageId: text(payload["messageId"]) } : null;
732
- }
733
- case "provider.response":
734
- return {
735
- kind: "response",
736
- content: payload["content"],
737
- stopReason: text(payload["stopReason"])
738
- };
739
- case "run.result":
740
- return {
741
- kind: "run-result",
742
- status: text(payload["status"]),
743
- iterations: finite(payload["iterations"], 1),
744
- ...typeof payload["finalText"] === "string" ? { finalText: payload["finalText"] } : {}
745
- };
746
- case "error":
747
- return { kind: "error", message: text(payload["message"], "Run failed") };
748
- default:
749
- return null;
750
- }
751
- }
752
- function projectToolMessage(message) {
753
- const payload = record(message.payload);
754
- if (!payload) return null;
755
- if (message.type === "tool.started") {
756
- const name = text(payload["name"], "tool");
757
- return {
758
- kind: "started",
759
- id: text(payload["id"], name),
760
- name,
761
- input: payload["input"],
762
- messageId: text(payload["messageId"])
763
- };
764
- }
765
- if (message.type === "tool.progress") {
766
- const event = record(payload["event"]);
767
- return {
768
- kind: "progress",
769
- id: text(payload["id"]),
770
- name: text(payload["name"], "tool"),
771
- eventType: text(event?.["type"]),
772
- text: text(event?.["text"]).trim()
773
- };
774
- }
775
- if (message.type === "tool.executed") {
776
- return {
777
- kind: "executed",
778
- id: text(payload["id"]),
779
- name: text(payload["name"]),
780
- ok: payload["ok"] !== false,
781
- durationMs: finite(payload["durationMs"]),
782
- ...typeof payload["output"] === "string" ? { output: payload["output"] } : {},
783
- ...Array.isArray(payload["sage"]) ? { sage: payload["sage"].filter((line) => typeof line === "string") } : {}
784
- };
785
- }
786
- return null;
787
- }
788
- function optionalFinite(value) {
789
- if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
790
- return value;
791
- }
792
- function optionalString(value) {
793
- return typeof value === "string" && value.length > 0 ? value : void 0;
794
- }
795
- function projectFleetMessage(message) {
796
- const payload = record(message.payload);
797
- if (!payload) return null;
798
- switch (message.type) {
799
- case "fleet.concurrency_update":
800
- return {
801
- kind: "concurrency",
802
- active: finite(payload["fleetConcurrency"]),
803
- maximum: finite(payload["fleetConcurrencyMax"]),
804
- maxSpawns: optionalFinite(payload["maxSpawns"]),
805
- usedSpawns: optionalFinite(payload["usedSpawns"]),
806
- remainingSpawns: optionalFinite(payload["remainingSpawns"]),
807
- maxSpawnsSource: optionalString(payload["maxSpawnsSource"]),
808
- maxConcurrentSource: optionalString(payload["maxConcurrentSource"]),
809
- effectiveSource: optionalString(payload["effectiveSource"]),
810
- checkpointMaxSpawns: optionalFinite(payload["checkpointMaxSpawns"]),
811
- ceilingMismatch: payload["ceilingMismatch"] === true ? true : void 0
812
- };
813
- case "client.status_update":
814
- return { kind: "client-status", status: payload };
815
- case "sessions.status_update":
816
- return {
817
- kind: "sessions",
818
- sessions: Array.isArray(payload["sessions"]) ? payload["sessions"] : []
819
- };
820
- case "coordinator.stats":
821
- return {
822
- kind: "coordinator",
823
- agents: Array.isArray(payload["subagentStatuses"]) ? payload["subagentStatuses"].filter(
824
- (item) => record(item) !== null
825
- ) : []
826
- };
827
- default:
828
- return null;
829
- }
830
- }
831
- function projectHqFleetMessage(message) {
832
- if (message.type !== "hq.snapshot") return null;
833
- const snapshot = record(message.snapshot);
834
- const totals = snapshot ? record(snapshot["totals"]) : null;
835
- if (!snapshot || typeof snapshot["generatedAt"] !== "string" || !Array.isArray(snapshot["clients"]) || !Array.isArray(snapshot["projects"]) || !Array.isArray(snapshot["sessions"]) || !Array.isArray(snapshot["fleets"]) || !Array.isArray(snapshot["mailboxes"]) || !totals || !isValidHqTotals(totals) || !optionalArray(snapshot["machines"]) || !optionalArray(snapshot["liveSessions"]) || !optionalArray(snapshot["mcpServers"])) {
836
- return null;
837
- }
838
- return { kind: "hq-snapshot", snapshot };
839
- }
840
- function projectHqEventMessage(message) {
841
- if (message.type !== "hq.event") return null;
842
- const event = record(message.event);
843
- if (!event || typeof event["id"] !== "string" || typeof event["type"] !== "string" || typeof event["timestamp"] !== "string" || typeof event["clientId"] !== "string" || typeof event["projectId"] !== "string" || typeof event["seq"] !== "number") {
844
- return null;
845
- }
846
- return { kind: "hq-event", event };
847
- }
848
- function projectHqAlertMessage(message) {
849
- if (message.type !== "hq.alert") return null;
850
- if (typeof message["severity"] !== "string" || !["info", "warn", "error"].includes(message["severity"]) || typeof message["message"] !== "string" || typeof message["timestamp"] !== "string") {
851
- return null;
852
- }
853
- return { kind: "hq-alert", alert: message };
854
- }
855
- function projectHqCommandStatusMessage(message) {
856
- if (message.type !== "hq.command_status") return null;
857
- const command = record(message.command);
858
- if (!command || typeof command["commandId"] !== "string" || typeof command["type"] !== "string" || typeof command["clientId"] !== "string" || typeof command["enqueuedBy"] !== "string" || typeof command["enqueuedAt"] !== "string" || typeof command["status"] !== "string" || !["queued", "delivered", "acked"].includes(command["status"])) {
859
- return null;
860
- }
861
- return { kind: "hq-command-status", command };
862
- }
863
-
864
- // src/protocol/replay-payload.ts
865
- import { CHAT_MARKER_SOURCES, projectSessionMarkers } from "@wrongstack/core/types/session-markers";
866
- var REPLAY_MESSAGE_CAP = 2e3;
867
- function buildReplayPayload(source) {
868
- const out = {};
869
- const messages = source.messages;
870
- if (messages.length > 0) {
871
- out.replayMessages = messages.length > REPLAY_MESSAGE_CAP ? messages.slice(-REPLAY_MESSAGE_CAP) : [...messages];
872
- }
873
- if (source.events && source.events.length > 0) {
874
- const markers = projectSessionMarkers(source.events, CHAT_MARKER_SOURCES);
875
- if (markers.length > 0) out.replayMarkers = markers;
876
- }
877
- const usage = source.usage;
878
- if (usage && usage.input + usage.output + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0) > 0) {
879
- out.replayUsage = {
880
- input: usage.input,
881
- output: usage.output,
882
- cacheRead: usage.cacheRead ?? 0,
883
- cacheWrite: usage.cacheWrite ?? 0
884
- };
885
- }
886
- return out;
887
- }
888
-
889
- // src/protocol/version.ts
890
- var SURFACE_PROTOCOL_VERSION = 1;
891
- var SURFACE_PROTOCOL_MIN_VERSION = 1;
892
- var SURFACE_PROTOCOL_CAPABILITIES = [
893
- "protocol.directional-decoder",
894
- "protocol.recursive-key-safety",
895
- "chronicle.query",
896
- "chronicle.facet",
897
- "chronicle.facets",
898
- "chronicle.graph",
899
- "chronicle.metrics",
900
- "chronicle.status",
901
- "connections.health",
902
- /** Bounded topic-shift advice plus same-session provider-context boundaries. */
903
- "context.topic-boundary",
904
- /** Interview resume/discard + lastAgentText/lastRunId continuity. */
905
- "sdd.interview.continuity",
906
- /** Launch multi-agent runs from a graph id or resolved spec id. */
907
- "sdd.run.from_graph"
908
- ];
909
- function protocolAdvertisement() {
910
- return {
911
- protocolVersion: SURFACE_PROTOCOL_VERSION,
912
- protocolCapabilities: [...SURFACE_PROTOCOL_CAPABILITIES]
913
- };
914
- }
915
- function negotiateProtocol(peer) {
916
- const peerVersion = peer.protocolVersion;
917
- const legacyPeer = peerVersion === void 0;
918
- const version = legacyPeer ? SURFACE_PROTOCOL_VERSION : Math.min(peerVersion, SURFACE_PROTOCOL_VERSION);
919
- const compatible = legacyPeer || Number.isInteger(peerVersion) && peerVersion >= SURFACE_PROTOCOL_MIN_VERSION;
920
- const advertised = new Set(peer.protocolCapabilities ?? []);
921
- return {
922
- compatible,
923
- legacyPeer,
924
- version,
925
- capabilities: SURFACE_PROTOCOL_CAPABILITIES.filter((item) => advertised.has(item))
926
- };
927
- }
928
- export {
929
- CLIENT_MESSAGE_TYPES,
930
- DEFAULT_SURFACE_CONNECTION_CONFIG,
931
- REPLAY_MESSAGE_CAP,
932
- SERVER_MESSAGE_TYPES,
933
- SURFACE_PROTOCOL_CAPABILITIES,
934
- SURFACE_PROTOCOL_MIN_VERSION,
935
- SURFACE_PROTOCOL_VERSION,
936
- buildReplayPayload,
937
- createSurfaceConnectionState,
938
- decodeProtocolFrame,
939
- decodeProtocolMessage,
940
- enqueueBounded,
941
- isConnectionHeartbeatTimedOut,
942
- isRegisteredMessageType,
943
- markConnectionActivity,
944
- markConnectionConnecting,
945
- markConnectionOpen,
946
- negotiateProtocol,
947
- planConnectionReconnect,
948
- projectChatMessage,
949
- projectFleetMessage,
950
- projectHqAlertMessage,
951
- projectHqCommandStatusMessage,
952
- projectHqEventMessage,
953
- projectHqFleetMessage,
954
- projectSessionMessage,
955
- projectToolMessage,
956
- protocolAdvertisement,
957
- resetConnection,
958
- stopConnection
959
- };
960
- //# sourceMappingURL=index.js.map