agent-comms 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +1 -1
  3. package/dist/bridges/pi/index.d.ts.map +1 -1
  4. package/dist/bridges/pi/index.js +29 -1
  5. package/dist/bridges/pi/index.js.map +1 -1
  6. package/dist/bridges/user/web/build.d.ts +12 -0
  7. package/dist/bridges/user/web/build.d.ts.map +1 -0
  8. package/dist/bridges/user/web/build.js +83 -0
  9. package/dist/bridges/user/web/build.js.map +1 -0
  10. package/dist/bridges/user/web/frontend/api.d.ts +29 -0
  11. package/dist/bridges/user/web/frontend/api.d.ts.map +1 -0
  12. package/dist/bridges/user/web/frontend/api.js +121 -0
  13. package/dist/bridges/user/web/frontend/api.js.map +1 -0
  14. package/dist/bridges/user/web/frontend/dom.d.ts +38 -0
  15. package/dist/bridges/user/web/frontend/dom.d.ts.map +1 -0
  16. package/dist/bridges/user/web/frontend/dom.js +71 -0
  17. package/dist/bridges/user/web/frontend/dom.js.map +1 -0
  18. package/dist/bridges/user/web/frontend/input.d.ts +22 -0
  19. package/dist/bridges/user/web/frontend/input.d.ts.map +1 -0
  20. package/dist/bridges/user/web/frontend/input.js +129 -0
  21. package/dist/bridges/user/web/frontend/input.js.map +1 -0
  22. package/dist/bridges/user/web/frontend/main.d.ts +8 -0
  23. package/dist/bridges/user/web/frontend/main.d.ts.map +1 -0
  24. package/dist/bridges/user/web/frontend/main.js +141 -0
  25. package/dist/bridges/user/web/frontend/main.js.map +1 -0
  26. package/dist/bridges/user/web/frontend/render.d.ts +30 -0
  27. package/dist/bridges/user/web/frontend/render.d.ts.map +1 -0
  28. package/dist/bridges/user/web/frontend/render.js +129 -0
  29. package/dist/bridges/user/web/frontend/render.js.map +1 -0
  30. package/dist/bridges/user/web/frontend/state.d.ts +34 -0
  31. package/dist/bridges/user/web/frontend/state.d.ts.map +1 -0
  32. package/dist/bridges/user/web/frontend/state.js +71 -0
  33. package/dist/bridges/user/web/frontend/state.js.map +1 -0
  34. package/dist/bridges/user/web/frontend/test/dom.unit.test.d.ts +5 -0
  35. package/dist/bridges/user/web/frontend/test/dom.unit.test.d.ts.map +1 -0
  36. package/dist/bridges/user/web/frontend/test/dom.unit.test.js +149 -0
  37. package/dist/bridges/user/web/frontend/test/dom.unit.test.js.map +1 -0
  38. package/dist/bridges/user/web/frontend/test/input.unit.test.d.ts +5 -0
  39. package/dist/bridges/user/web/frontend/test/input.unit.test.d.ts.map +1 -0
  40. package/dist/bridges/user/web/frontend/test/input.unit.test.js +131 -0
  41. package/dist/bridges/user/web/frontend/test/input.unit.test.js.map +1 -0
  42. package/dist/bridges/user/web/frontend/test/render.unit.test.d.ts +5 -0
  43. package/dist/bridges/user/web/frontend/test/render.unit.test.d.ts.map +1 -0
  44. package/dist/bridges/user/web/frontend/test/render.unit.test.js +436 -0
  45. package/dist/bridges/user/web/frontend/test/render.unit.test.js.map +1 -0
  46. package/dist/bridges/user/web/frontend/test/state.unit.test.d.ts +5 -0
  47. package/dist/bridges/user/web/frontend/test/state.unit.test.d.ts.map +1 -0
  48. package/dist/bridges/user/web/frontend/test/state.unit.test.js +119 -0
  49. package/dist/bridges/user/web/frontend/test/state.unit.test.js.map +1 -0
  50. package/dist/bridges/user/web/frontend/types.d.ts +157 -0
  51. package/dist/bridges/user/web/frontend/types.d.ts.map +1 -0
  52. package/dist/bridges/user/web/frontend/types.js +8 -0
  53. package/dist/bridges/user/web/frontend/types.js.map +1 -0
  54. package/dist/bridges/user/web/generated-html.d.ts +6 -0
  55. package/dist/bridges/user/web/generated-html.d.ts.map +1 -0
  56. package/dist/bridges/user/web/generated-html.js +179 -0
  57. package/dist/bridges/user/web/generated-html.js.map +1 -0
  58. package/dist/bridges/user/web/server.js +1 -1
  59. package/dist/bridges/user/web/server.js.map +1 -1
  60. package/dist/test/{coordinator-socket-error.test.d.ts → coordinator-socket-error.integration.test.d.ts} +1 -1
  61. package/dist/test/coordinator-socket-error.integration.test.d.ts.map +1 -0
  62. package/dist/test/{coordinator-socket-error.test.js → coordinator-socket-error.integration.test.js} +1 -1
  63. package/dist/test/coordinator-socket-error.integration.test.js.map +1 -0
  64. package/dist/test/{mesh-e2e.test.d.ts → mesh-e2e.integration.test.d.ts} +1 -1
  65. package/dist/test/mesh-e2e.integration.test.d.ts.map +1 -0
  66. package/dist/test/{mesh-e2e.test.js → mesh-e2e.integration.test.js} +1 -1
  67. package/dist/test/mesh-e2e.integration.test.js.map +1 -0
  68. package/dist/test/{mesh-smoke.test.d.ts → mesh-smoke.integration.test.d.ts} +1 -1
  69. package/dist/test/mesh-smoke.integration.test.d.ts.map +1 -0
  70. package/dist/test/{mesh-smoke.test.js → mesh-smoke.integration.test.js} +1 -1
  71. package/dist/test/mesh-smoke.integration.test.js.map +1 -0
  72. package/package.json +8 -2
  73. package/dist/bridges/user/web/index.html.d.ts +0 -8
  74. package/dist/bridges/user/web/index.html.d.ts.map +0 -1
  75. package/dist/bridges/user/web/index.html.js +0 -391
  76. package/dist/bridges/user/web/index.html.js.map +0 -1
  77. package/dist/test/coordinator-socket-error.test.d.ts.map +0 -1
  78. package/dist/test/coordinator-socket-error.test.js.map +0 -1
  79. package/dist/test/mesh-e2e.test.d.ts.map +0 -1
  80. package/dist/test/mesh-e2e.test.js.map +0 -1
  81. package/dist/test/mesh-smoke.test.d.ts.map +0 -1
  82. package/dist/test/mesh-smoke.test.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Entry point — bootstraps the web UI.
3
+ *
4
+ * Imports all modules, binds DOM events, connects WebSocket,
5
+ * and wires up the render loop.
6
+ */
7
+ import "./styles.css";
8
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,cAAc,CAAC"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Entry point — bootstraps the web UI.
3
+ *
4
+ * Imports all modules, binds DOM events, connects WebSocket,
5
+ * and wires up the render loop.
6
+ */
7
+ import "./styles.css";
8
+ import { CommsWs, fetchAgents, fetchRoomMessages, fetchRooms } from "./api.js";
9
+ import { requireElement } from "./dom.js";
10
+ import { parseInput } from "./input.js";
11
+ import { clearMessages, renderDeliveryEvent, renderHeader, renderMessageHistory, renderRoomList, renderAgentList, renderSystemMessage, renderStatusMessage, } from "./render.js";
12
+ import { State } from "./state.js";
13
+ // ---------------------------------------------------------------------------
14
+ // DOM elements
15
+ // ---------------------------------------------------------------------------
16
+ const messagesEl = requireElement(document, "#messages");
17
+ const inputRaw = requireElement(document, "#input", "input");
18
+ const headerEl = requireElement(document, "#header");
19
+ const roomListEl = requireElement(document, "#room-list");
20
+ const agentListEl = requireElement(document, "#agent-list");
21
+ const messageTarget = { messagesEl };
22
+ const sidebarTarget = { roomListEl, agentListEl };
23
+ // ---------------------------------------------------------------------------
24
+ // State
25
+ // ---------------------------------------------------------------------------
26
+ const state = new State();
27
+ // Re-render sidebar on state changes
28
+ state.subscribe((s) => {
29
+ renderRoomList(document, sidebarTarget, s.rooms, s.currentRoom, onJoinRoom);
30
+ renderAgentList(document, sidebarTarget, s.agents, onSelectAgent);
31
+ });
32
+ // ---------------------------------------------------------------------------
33
+ // WebSocket
34
+ // ---------------------------------------------------------------------------
35
+ const ws = new CommsWs({
36
+ onOpen: () => {
37
+ state.setConnected(true);
38
+ renderSystemMessage(document, messageTarget, "Connected to mesh");
39
+ },
40
+ onClose: () => {
41
+ state.setConnected(false);
42
+ renderSystemMessage(document, messageTarget, "Disconnected — reconnecting...");
43
+ },
44
+ onFrame: handleFrame,
45
+ });
46
+ function handleFrame(frame) {
47
+ switch (frame.type) {
48
+ case "delivery":
49
+ renderDeliveryEvent(document, messageTarget, frame.event, state.get().currentRoom);
50
+ // Some events require a state refresh
51
+ if (frame.event.type === "member_joined" ||
52
+ frame.event.type === "member_left" ||
53
+ frame.event.type === "member_status") {
54
+ void refreshState();
55
+ }
56
+ break;
57
+ case "result":
58
+ renderSystemMessage(document, messageTarget, frame.result.content);
59
+ if (!frame.result.isError) {
60
+ // Auto-switch current room after successful join_room via command
61
+ if (pendingAction?.action === "join_room" && !state.get().currentRoom) {
62
+ const roomId = pendingAction.room;
63
+ state.setDmTarget(undefined);
64
+ state.setCurrentRoom(roomId);
65
+ renderHeader({ headerEl }, roomId);
66
+ }
67
+ void refreshState();
68
+ }
69
+ pendingAction = undefined;
70
+ break;
71
+ case "error":
72
+ renderStatusMessage(document, messageTarget, `Error: ${frame.message}`);
73
+ break;
74
+ case "state":
75
+ state.applyState(frame.agents, frame.rooms);
76
+ break;
77
+ }
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Actions
81
+ // ---------------------------------------------------------------------------
82
+ let pendingAction;
83
+ function sendAction(action) {
84
+ pendingAction = action;
85
+ ws.sendAction(action);
86
+ }
87
+ async function refreshState() {
88
+ const [agents, rooms] = await Promise.all([fetchAgents(), fetchRooms()]);
89
+ state.setAgents(agents);
90
+ state.setRooms(rooms);
91
+ }
92
+ async function onJoinRoom(roomId) {
93
+ state.setDmTarget(undefined);
94
+ state.setCurrentRoom(roomId);
95
+ renderHeader({ headerEl }, roomId);
96
+ clearMessages(messageTarget);
97
+ sendAction({ action: "join_room", room: roomId });
98
+ // Load history
99
+ const messages = await fetchRoomMessages(roomId);
100
+ renderMessageHistory(document, messageTarget, messages);
101
+ renderSystemMessage(document, messageTarget, `Joined ${roomId}`);
102
+ inputRaw.focus();
103
+ }
104
+ function onSelectAgent(agentId) {
105
+ state.setCurrentRoom(undefined);
106
+ state.setDmTarget(agentId);
107
+ clearMessages(messageTarget);
108
+ renderHeader({ headerEl }, `DM with ${agentId}`);
109
+ inputRaw.focus();
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Input handling
113
+ // ---------------------------------------------------------------------------
114
+ function handleInput() {
115
+ const text = inputRaw.value;
116
+ inputRaw.value = "";
117
+ const result = parseInput(text, state.get().currentRoom, state.get().dmTarget);
118
+ switch (result.kind) {
119
+ case "action":
120
+ sendAction(result.action);
121
+ break;
122
+ case "local":
123
+ renderSystemMessage(document, messageTarget, result.result.text);
124
+ break;
125
+ case "ignored":
126
+ break;
127
+ }
128
+ }
129
+ const sendBtn = requireElement(document, "#send-btn");
130
+ sendBtn.onclick = handleInput;
131
+ inputRaw.addEventListener("keydown", (e) => {
132
+ if (e.key === "Enter")
133
+ handleInput();
134
+ });
135
+ // ---------------------------------------------------------------------------
136
+ // Boot
137
+ // ---------------------------------------------------------------------------
138
+ ws.connect();
139
+ void refreshState();
140
+ inputRaw.focus();
141
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Render functions — pure DOM construction from state and data.
3
+ *
4
+ * Every function takes a document (or element) and data, returns DOM nodes.
5
+ * No side effects, no global state. Testable with jsdom.
6
+ */
7
+ import type { Agent, DeliveryEvent, Room, RoomMessage } from "./types.js";
8
+ export interface MessageTarget {
9
+ messagesEl: HTMLElement;
10
+ }
11
+ export declare function renderChatMessage(doc: Document, target: MessageTarget, sender: string, content: string, timestamp: string): void;
12
+ export declare function renderDmMessage(doc: Document, target: MessageTarget, sender: string, content: string, timestamp: string): void;
13
+ export declare function renderSystemMessage(doc: Document, target: MessageTarget, text: string): void;
14
+ export declare function renderStatusMessage(doc: Document, target: MessageTarget, text: string): void;
15
+ export declare function clearMessages(target: MessageTarget): void;
16
+ export declare function renderDeliveryEvent(doc: Document, target: MessageTarget, event: DeliveryEvent, currentRoom: string | undefined): void;
17
+ export interface SidebarTarget {
18
+ roomListEl: HTMLElement;
19
+ agentListEl: HTMLElement;
20
+ }
21
+ export type RoomAction = (roomId: string) => void | Promise<void>;
22
+ export declare function renderRoomList(doc: Document, target: SidebarTarget, rooms: Room[], currentRoom: string | undefined, onJoin: RoomAction): void;
23
+ export type AgentSelectAction = (agentId: string) => void;
24
+ export declare function renderAgentList(doc: Document, target: SidebarTarget, agents: Agent[], onSelect?: AgentSelectAction): void;
25
+ export interface HeaderTarget {
26
+ headerEl: HTMLElement;
27
+ }
28
+ export declare function renderHeader(target: HeaderTarget, text: string): void;
29
+ export declare function renderMessageHistory(doc: Document, target: MessageTarget, messages: RoomMessage[]): void;
30
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO1E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,WAAW,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,IAAI,CAON;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,MAAM,GACX,IAAI,CAMN;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,MAAM,GACX,IAAI,CAMN;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAEzD;AAMD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,IAAI,CA2EN;AAMD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,WAAW,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,IAAI,EAAE,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,UAAU,GACjB,IAAI,CAgBN;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAE1D,wBAAgB,eAAe,CAC7B,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,IAAI,CAqBN;AAMD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAErE;AAMD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,WAAW,EAAE,GACtB,IAAI,CAIN"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Render functions — pure DOM construction from state and data.
3
+ *
4
+ * Every function takes a document (or element) and data, returns DOM nodes.
5
+ * No side effects, no global state. Testable with jsdom.
6
+ */
7
+ import { clearChildren, createElement, escapeHtml, formatTime } from "./dom.js";
8
+ export function renderChatMessage(doc, target, sender, content, timestamp) {
9
+ const time = formatTime(timestamp);
10
+ const div = doc.createElement("div");
11
+ div.className = "msg";
12
+ div.innerHTML = `<span class="sender">${escapeHtml(doc, sender)}</span><span class="time">${time}</span>: ${escapeHtml(doc, content)}`;
13
+ target.messagesEl.appendChild(div);
14
+ target.messagesEl.scrollTop = target.messagesEl.scrollHeight;
15
+ }
16
+ export function renderDmMessage(doc, target, sender, content, timestamp) {
17
+ const time = formatTime(timestamp);
18
+ const div = doc.createElement("div");
19
+ div.className = "msg dm";
20
+ div.innerHTML = `<span class="dm-badge">DM</span> <span class="sender">${escapeHtml(doc, sender)}</span><span class="time">${time}</span>: ${escapeHtml(doc, content)}`;
21
+ target.messagesEl.appendChild(div);
22
+ target.messagesEl.scrollTop = target.messagesEl.scrollHeight;
23
+ }
24
+ export function renderSystemMessage(doc, target, text) {
25
+ const div = doc.createElement("div");
26
+ div.className = "msg system";
27
+ div.textContent = text;
28
+ target.messagesEl.appendChild(div);
29
+ target.messagesEl.scrollTop = target.messagesEl.scrollHeight;
30
+ }
31
+ export function renderStatusMessage(doc, target, text) {
32
+ const div = doc.createElement("div");
33
+ div.className = "msg status";
34
+ div.textContent = text;
35
+ target.messagesEl.appendChild(div);
36
+ target.messagesEl.scrollTop = target.messagesEl.scrollHeight;
37
+ }
38
+ export function clearMessages(target) {
39
+ clearChildren(target.messagesEl);
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Delivery event rendering
43
+ // ---------------------------------------------------------------------------
44
+ export function renderDeliveryEvent(doc, target, event, currentRoom) {
45
+ switch (event.type) {
46
+ case "room_message":
47
+ if (currentRoom === event.message.room) {
48
+ renderChatMessage(doc, target, event.message.from, event.message.content, event.message.timestamp);
49
+ }
50
+ break;
51
+ case "dm":
52
+ renderDmMessage(doc, target, event.message.from, event.message.content, event.message.timestamp);
53
+ break;
54
+ case "member_joined":
55
+ renderSystemMessage(doc, target, `${event.agent} joined ${event.room}`);
56
+ break;
57
+ case "member_left":
58
+ renderSystemMessage(doc, target, `${event.agent} left ${event.room}`);
59
+ break;
60
+ case "member_status":
61
+ renderStatusMessage(doc, target, `${event.agent} is now ${event.status} in ${event.room}`);
62
+ break;
63
+ case "delivery_status":
64
+ renderStatusMessage(doc, target, `Message ${event.messageId} ${event.status} by ${event.agent}`);
65
+ break;
66
+ case "room_members":
67
+ if (currentRoom === event.room) {
68
+ const memberList = event.members
69
+ .map((m) => `${m.name} (${m.status})`)
70
+ .join(", ");
71
+ renderSystemMessage(doc, target, `Members: ${memberList}`);
72
+ }
73
+ break;
74
+ case "room_invite": {
75
+ const desc = event.roomDescription ? ` — ${event.roomDescription}` : "";
76
+ renderSystemMessage(doc, target, `${event.fromName} invited you to "${event.room}"${desc}`);
77
+ break;
78
+ }
79
+ case "invite_declined":
80
+ renderSystemMessage(doc, target, `${event.agentName} declined invite to ${event.room}: "${event.reason}"`);
81
+ break;
82
+ }
83
+ }
84
+ export function renderRoomList(doc, target, rooms, currentRoom, onJoin) {
85
+ clearChildren(target.roomListEl);
86
+ for (const room of rooms) {
87
+ const isActive = currentRoom === room.id;
88
+ const typeIndicator = room.type.charAt(0).toUpperCase();
89
+ const memberCount = room.members.length;
90
+ const div = doc.createElement("div");
91
+ div.className = `room-item${isActive ? " active" : ""}`;
92
+ div.innerHTML = `${typeIndicator} ${escapeHtml(doc, room.name)} <span style="color:var(--dim)">(${String(memberCount)})</span>`;
93
+ div.onclick = () => {
94
+ void onJoin(room.id);
95
+ };
96
+ target.roomListEl.appendChild(div);
97
+ }
98
+ }
99
+ export function renderAgentList(doc, target, agents, onSelect) {
100
+ clearChildren(target.agentListEl);
101
+ for (const agent of agents) {
102
+ const div = doc.createElement("div");
103
+ div.className = "agent-item";
104
+ const dot = createElement(doc, "span", {
105
+ class: `status-dot ${agent.status}`,
106
+ });
107
+ const name = doc.createTextNode(` ${agent.name}`);
108
+ div.appendChild(dot);
109
+ div.appendChild(name);
110
+ if (onSelect) {
111
+ div.onclick = () => {
112
+ onSelect(agent.id);
113
+ };
114
+ }
115
+ target.agentListEl.appendChild(div);
116
+ }
117
+ }
118
+ export function renderHeader(target, text) {
119
+ target.headerEl.textContent = text;
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // Room history (batch load)
123
+ // ---------------------------------------------------------------------------
124
+ export function renderMessageHistory(doc, target, messages) {
125
+ for (const m of messages) {
126
+ renderChatMessage(doc, target, m.from, m.content, m.timestamp);
127
+ }
128
+ }
129
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Client state — minimal observable state for the UI.
3
+ *
4
+ * No DOM dependency. Testable in isolation.
5
+ * Consumers subscribe to changes and re-render as needed.
6
+ */
7
+ import type { Agent, Room } from "./types.js";
8
+ export type StateChangeListener = (state: Readonly<ClientState>) => void;
9
+ export interface ClientState {
10
+ currentRoom: string | undefined;
11
+ dmTarget: string | undefined;
12
+ agents: Agent[];
13
+ rooms: Room[];
14
+ connected: boolean;
15
+ }
16
+ export declare class State {
17
+ private state;
18
+ private readonly listeners;
19
+ /** Subscribe to state changes. Returns an unsubscribe function. */
20
+ subscribe(listener: StateChangeListener): () => void;
21
+ /** Read the current state (shallow copy). */
22
+ get(): Readonly<ClientState>;
23
+ setCurrentRoom(roomId: string | undefined): void;
24
+ setDmTarget(agentId: string | undefined): void;
25
+ setAgents(agents: Agent[]): void;
26
+ setRooms(rooms: Room[]): void;
27
+ setConnected(connected: boolean): void;
28
+ /** Bulk update from a state frame (initial WS connection). */
29
+ applyState(agents: Agent[], rooms: Room[]): void;
30
+ /** Reset to initial state. */
31
+ reset(): void;
32
+ private notify;
33
+ }
34
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;AAEzE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAUD,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;IAE5D,mEAAmE;IACnE,SAAS,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAOpD,6CAA6C;IAC7C,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC;IAQ5B,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKhD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAK9C,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;IAKhC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAK7B,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAKtC,8DAA8D;IAC9D,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAKhD,8BAA8B;IAC9B,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,MAAM;CAMf"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Client state — minimal observable state for the UI.
3
+ *
4
+ * No DOM dependency. Testable in isolation.
5
+ * Consumers subscribe to changes and re-render as needed.
6
+ */
7
+ const INITIAL_STATE = {
8
+ currentRoom: undefined,
9
+ dmTarget: undefined,
10
+ agents: [],
11
+ rooms: [],
12
+ connected: false,
13
+ };
14
+ export class State {
15
+ state = { ...INITIAL_STATE };
16
+ listeners = new Set();
17
+ /** Subscribe to state changes. Returns an unsubscribe function. */
18
+ subscribe(listener) {
19
+ this.listeners.add(listener);
20
+ return () => {
21
+ this.listeners.delete(listener);
22
+ };
23
+ }
24
+ /** Read the current state (shallow copy). */
25
+ get() {
26
+ return this.state;
27
+ }
28
+ // -----------------------------------------------------------------------
29
+ // Mutations — each notifies listeners
30
+ // -----------------------------------------------------------------------
31
+ setCurrentRoom(roomId) {
32
+ this.state = { ...this.state, currentRoom: roomId };
33
+ this.notify();
34
+ }
35
+ setDmTarget(agentId) {
36
+ this.state = { ...this.state, dmTarget: agentId };
37
+ this.notify();
38
+ }
39
+ setAgents(agents) {
40
+ this.state = { ...this.state, agents };
41
+ this.notify();
42
+ }
43
+ setRooms(rooms) {
44
+ this.state = { ...this.state, rooms };
45
+ this.notify();
46
+ }
47
+ setConnected(connected) {
48
+ this.state = { ...this.state, connected };
49
+ this.notify();
50
+ }
51
+ /** Bulk update from a state frame (initial WS connection). */
52
+ applyState(agents, rooms) {
53
+ this.state = { ...this.state, agents, rooms };
54
+ this.notify();
55
+ }
56
+ /** Reset to initial state. */
57
+ reset() {
58
+ this.state = { ...INITIAL_STATE };
59
+ this.notify();
60
+ }
61
+ // -----------------------------------------------------------------------
62
+ // Internal
63
+ // -----------------------------------------------------------------------
64
+ notify() {
65
+ const snapshot = this.state;
66
+ for (const listener of this.listeners) {
67
+ listener(snapshot);
68
+ }
69
+ }
70
+ }
71
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,aAAa,GAAgB;IACjC,WAAW,EAAE,SAAS;IACtB,QAAQ,EAAE,SAAS;IACnB,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,SAAS,EAAE,KAAK;CACjB,CAAC;AAEF,MAAM,OAAO,KAAK;IACR,KAAK,GAAgB,EAAE,GAAG,aAAa,EAAE,CAAC;IACjC,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE5D,mEAAmE;IACnE,SAAS,CAAC,QAA6B;QACrC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IAED,6CAA6C;IAC7C,GAAG;QACD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,0EAA0E;IAC1E,sCAAsC;IACtC,0EAA0E;IAE1E,cAAc,CAAC,MAA0B;QACvC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,WAAW,CAAC,OAA2B;QACrC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,SAAS,CAAC,MAAe;QACvB,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,QAAQ,CAAC,KAAa;QACpB,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,YAAY,CAAC,SAAkB;QAC7B,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,8DAA8D;IAC9D,UAAU,CAAC,MAAe,EAAE,KAAa;QACvC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,8BAA8B;IAC9B,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,0EAA0E;IAC1E,WAAW;IACX,0EAA0E;IAElE,MAAM;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for dom.ts — DOM helper functions.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=dom.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.unit.test.d.ts","sourceRoot":"","sources":["../../../../../../src/bridges/user/web/frontend/test/dom.unit.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Unit tests for dom.ts — DOM helper functions.
3
+ */
4
+ import { describe, it } from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { Window } from "happy-dom";
7
+ import { clearChildren, createElement, escapeHtml, formatTime, querySelector, requireElement, } from "../dom.js";
8
+ function createDoc() {
9
+ const window = new Window();
10
+ return {
11
+ doc: window.document,
12
+ cleanup: () => {
13
+ window.close();
14
+ },
15
+ };
16
+ }
17
+ describe("dom", () => {
18
+ describe("escapeHtml", () => {
19
+ it("escapes <, >, &, quotes", () => {
20
+ const { doc, cleanup } = createDoc();
21
+ try {
22
+ assert.strictEqual(escapeHtml(doc, "<script>alert('xss')</script>"), "&lt;script&gt;alert('xss')&lt;/script&gt;");
23
+ }
24
+ finally {
25
+ cleanup();
26
+ }
27
+ });
28
+ it("passes through safe text unchanged", () => {
29
+ const { doc, cleanup } = createDoc();
30
+ try {
31
+ assert.strictEqual(escapeHtml(doc, "hello world"), "hello world");
32
+ }
33
+ finally {
34
+ cleanup();
35
+ }
36
+ });
37
+ });
38
+ describe("formatTime", () => {
39
+ it("extracts HH:MM:SS from ISO string", () => {
40
+ assert.strictEqual(formatTime("2025-05-23T14:30:45.123Z"), "14:30:45");
41
+ });
42
+ });
43
+ describe("createElement", () => {
44
+ it("creates element with attributes and children", () => {
45
+ const { doc, cleanup } = createDoc();
46
+ try {
47
+ const el = createElement(doc, "div", { class: "test" }, "hello");
48
+ assert.strictEqual(el.tagName, "DIV");
49
+ assert.strictEqual(el.getAttribute("class"), "test");
50
+ assert.strictEqual(el.textContent, "hello");
51
+ }
52
+ finally {
53
+ cleanup();
54
+ }
55
+ });
56
+ it("creates element without attributes or children", () => {
57
+ const { doc, cleanup } = createDoc();
58
+ try {
59
+ const el = createElement(doc, "span");
60
+ assert.strictEqual(el.tagName, "SPAN");
61
+ assert.strictEqual(el.childNodes.length, 0);
62
+ }
63
+ finally {
64
+ cleanup();
65
+ }
66
+ });
67
+ it("appends Node children", () => {
68
+ const { doc, cleanup } = createDoc();
69
+ try {
70
+ const child = doc.createElement("strong");
71
+ child.textContent = "bold";
72
+ const el = createElement(doc, "p", undefined, child);
73
+ assert.strictEqual(el.querySelector("strong")?.textContent, "bold");
74
+ }
75
+ finally {
76
+ cleanup();
77
+ }
78
+ });
79
+ });
80
+ describe("clearChildren", () => {
81
+ it("removes all children from an element", () => {
82
+ const { doc, cleanup } = createDoc();
83
+ try {
84
+ const parent = doc.createElement("div");
85
+ parent.appendChild(doc.createElement("span"));
86
+ parent.appendChild(doc.createElement("span"));
87
+ assert.strictEqual(parent.childNodes.length, 2);
88
+ clearChildren(parent);
89
+ assert.strictEqual(parent.childNodes.length, 0);
90
+ }
91
+ finally {
92
+ cleanup();
93
+ }
94
+ });
95
+ });
96
+ describe("querySelector", () => {
97
+ it("returns element when found", () => {
98
+ const { doc, cleanup } = createDoc();
99
+ try {
100
+ const parent = doc.createElement("div");
101
+ const child = doc.createElement("span");
102
+ child.id = "target";
103
+ parent.appendChild(child);
104
+ doc.body.appendChild(parent);
105
+ const result = querySelector(doc, "#target");
106
+ assert.ok(result);
107
+ assert.strictEqual(result.id, "target");
108
+ }
109
+ finally {
110
+ cleanup();
111
+ }
112
+ });
113
+ it("returns undefined when not found", () => {
114
+ const { doc, cleanup } = createDoc();
115
+ try {
116
+ const result = querySelector(doc, "#nonexistent");
117
+ assert.strictEqual(result, undefined);
118
+ }
119
+ finally {
120
+ cleanup();
121
+ }
122
+ });
123
+ });
124
+ describe("requireElement", () => {
125
+ it("returns element when found", () => {
126
+ const { doc, cleanup } = createDoc();
127
+ try {
128
+ const el = doc.createElement("div");
129
+ el.id = "required";
130
+ doc.body.appendChild(el);
131
+ const result = requireElement(doc, "#required");
132
+ assert.strictEqual(result.id, "required");
133
+ }
134
+ finally {
135
+ cleanup();
136
+ }
137
+ });
138
+ it("throws when element not found", () => {
139
+ const { doc, cleanup } = createDoc();
140
+ try {
141
+ assert.throws(() => requireElement(doc, "#missing"), /Required element not found/);
142
+ }
143
+ finally {
144
+ cleanup();
145
+ }
146
+ });
147
+ });
148
+ });
149
+ //# sourceMappingURL=dom.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.unit.test.js","sourceRoot":"","sources":["../../../../../../src/bridges/user/web/frontend/test/dom.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for input.ts — command parsing.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=input.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.unit.test.d.ts","sourceRoot":"","sources":["../../../../../../src/bridges/user/web/frontend/test/input.unit.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}