agentchannel 0.5.0 → 0.5.2

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.
package/dist/web.js CHANGED
@@ -1,160 +1,198 @@
1
1
  import { createServer } from "node:http";
2
+ import mqtt from "mqtt";
3
+ import { deriveKey, hashRoom, decrypt } from "./crypto.js";
4
+ const MAX_HISTORY = 200;
5
+ const CSS = `*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
6
+ :root{--bg-primary:#ffffff;--bg-secondary:#f8f9fa;--bg-sidebar:#1a1a2e;--bg-hover:rgba(0,0,0,0.04);--text-primary:#1a1a2e;--text-secondary:#6b7280;--text-muted:#9ca3af;--text-sidebar:#a0aec0;--text-sidebar-active:#ffffff;--mention-bg:rgba(59,130,246,0.1);--mention-text:#2563eb;--mention-border:rgba(59,130,246,0.2);--system-text:#9ca3af;--channel-bg:rgba(16,185,129,0.1);--channel-text:#059669;--channel-border:rgba(16,185,129,0.2);--divider:rgba(0,0,0,0.08);--sidebar-hover:rgba(255,255,255,0.08);--sidebar-active:rgba(255,255,255,0.15);--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--radius-sm:4px;--radius-lg:12px}
7
+ @media(prefers-color-scheme:dark){:root{--bg-primary:#1e1e2e;--bg-secondary:#181825;--bg-sidebar:#11111b;--bg-hover:rgba(255,255,255,0.05);--text-primary:#cdd6f4;--text-secondary:#a6adc8;--text-muted:#585b70;--mention-bg:rgba(137,180,250,0.15);--mention-text:#89b4fa;--mention-border:rgba(137,180,250,0.25);--system-text:#585b70;--channel-bg:rgba(166,227,161,0.1);--channel-text:#a6e3a1;--channel-border:rgba(166,227,161,0.2);--divider:rgba(255,255,255,0.06);--sidebar-hover:rgba(255,255,255,0.06);--sidebar-active:rgba(255,255,255,0.12)}}
8
+ html{font-size:15px;-webkit-font-smoothing:antialiased}
9
+ body{font-family:var(--font-sans);background:var(--bg-primary);color:var(--text-primary);line-height:1.6;height:100vh;overflow:hidden}
10
+ .app{display:flex;height:100vh}
11
+ .sidebar{width:220px;background:var(--bg-sidebar);display:flex;flex-direction:column;flex-shrink:0}
12
+ .sidebar__header{padding:16px;font-size:1rem;font-weight:700;color:#e94560;border-bottom:1px solid rgba(255,255,255,0.06)}
13
+ .sidebar__channels{flex:1;padding:8px;overflow-y:auto}
14
+ .sidebar__channel{display:flex;align-items:center;gap:8px;padding:6px 12px;border-radius:6px;cursor:pointer;color:var(--text-sidebar);font-size:0.9rem;transition:background 0.1s}
15
+ .sidebar__channel:hover{background:var(--sidebar-hover)}
16
+ .sidebar__channel.active{background:var(--sidebar-active);color:var(--text-sidebar-active);font-weight:600}
17
+ .sidebar__channel .hash{color:#6b7280;font-weight:400}
18
+ .sidebar__channel .unread{background:#e94560;color:#fff;font-size:0.65rem;padding:1px 6px;border-radius:9999px;margin-left:auto}
19
+ .sidebar__status{padding:12px 16px;font-size:0.75rem;color:var(--text-sidebar);border-top:1px solid rgba(255,255,255,0.06)}
20
+ .sidebar__status.connected{color:#4ade80}
21
+ .main{flex:1;display:flex;flex-direction:column;min-width:0}
22
+ .main__header{padding:14px 20px;border-bottom:1px solid var(--divider);font-weight:600;font-size:0.95rem;background:var(--bg-secondary)}
23
+ .message-list{flex:1;overflow-y:auto;padding:8px 0}
24
+ .message{display:flex;padding:2px 20px;transition:background-color 0.1s ease}
25
+ .message:hover{background:var(--bg-hover)}
26
+ .message__gutter{width:40px;flex-shrink:0;margin-right:12px;display:flex;align-items:flex-start;justify-content:center;padding-top:4px}
27
+ .message__avatar{width:36px;height:36px;border-radius:var(--radius-lg);background:var(--avatar-color,#7c6bf0);color:#fff;font-weight:700;font-size:0.85rem;display:flex;align-items:center;justify-content:center;user-select:none}
28
+ .message__body{flex:1;min-width:0}
29
+ .message--first{padding-top:10px;margin-top:4px}
30
+ .message--first+.message--first{border-top:1px solid var(--divider)}
31
+ .message--system+.message--first,.message--first:first-child{border-top:none}
32
+ .message__header{display:flex;align-items:baseline;gap:8px;margin-bottom:2px;flex-wrap:wrap}
33
+ .message__sender{font-weight:700;font-size:0.935rem;color:var(--sender-color,#7c6bf0)}
34
+ .message__channel{display:inline-block;font-size:0.72rem;font-weight:600;padding:1px 7px;border-radius:9999px;background:var(--channel-bg);color:var(--channel-text);border:1px solid var(--channel-border);white-space:nowrap}
35
+ .message__time{font-size:0.72rem;color:var(--text-muted);font-variant-numeric:tabular-nums;white-space:nowrap}
36
+ .message__time--hover{opacity:0;font-size:0.68rem;transition:opacity 0.15s ease;padding-top:4px}
37
+ .message--grouped:hover .message__time--hover{opacity:1}
38
+ .message__content{font-size:0.935rem;line-height:1.65;word-wrap:break-word}
39
+ .message--grouped{padding-top:1px;padding-bottom:1px}
40
+ .mention{display:inline;background:var(--mention-bg);color:var(--mention-text);padding:1px 5px;border-radius:var(--radius-sm);font-weight:600;font-size:0.9rem;border:1px solid var(--mention-border);white-space:nowrap}
41
+ .message--system{padding-top:6px;padding-bottom:6px}
42
+ .message--system .message__body{display:flex;align-items:center;gap:10px;padding-left:52px}
43
+ .message__system-text{font-size:0.82rem;color:var(--system-text);font-style:italic}
44
+ .message--system:hover{background:transparent}
45
+ .empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:0.9rem}
46
+ ::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:rgba(128,128,128,0.2);border-radius:3px}
47
+ @media(max-width:600px){.sidebar{width:60px}.sidebar__header{font-size:0.7rem;padding:12px 8px}.sidebar__channel{padding:6px 8px;font-size:0.75rem}.sidebar__channel .hash{display:none}.sidebar__status{display:none}}`;
2
48
  const HTML = `<!DOCTYPE html>
3
- <html>
49
+ <html lang="en">
4
50
  <head>
5
51
  <meta charset="utf-8">
52
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
53
  <title>AgentChannel</title>
7
- <style>
8
- * { margin: 0; padding: 0; box-sizing: border-box; }
9
- body { font-family: -apple-system, system-ui, sans-serif; background: #1a1a2e; color: #e0e0e0; height: 100vh; display: flex; flex-direction: column; }
10
- header { padding: 12px 20px; background: #16213e; border-bottom: 1px solid #0f3460; display: flex; align-items: center; gap: 12px; }
11
- header h1 { font-size: 16px; color: #e94560; }
12
- header .status { font-size: 12px; color: #4ade80; }
13
- #messages { flex: 1; overflow-y: auto; padding: 16px 20px; }
14
- .msg { margin-bottom: 8px; line-height: 1.5; }
15
- .msg .time { color: #666; font-size: 12px; }
16
- .msg .channel { color: #e94560; }
17
- .msg .sender { color: #4ade80; font-weight: bold; }
18
- .msg .content { color: #e0e0e0; }
19
- .msg.system { color: #666; font-style: italic; }
20
- .msg.mention { background: #2a2a4a; border-left: 3px solid #e94560; padding: 4px 8px; }
21
- #input-area { padding: 12px 20px; background: #16213e; border-top: 1px solid #0f3460; display: flex; gap: 8px; }
22
- #channel-select { background: #1a1a2e; color: #e94560; border: 1px solid #0f3460; padding: 8px; border-radius: 4px; }
23
- #msg-input { flex: 1; background: #1a1a2e; color: #e0e0e0; border: 1px solid #0f3460; padding: 8px 12px; border-radius: 4px; font-size: 14px; }
24
- #msg-input:focus { outline: none; border-color: #e94560; }
25
- #send-btn { background: #e94560; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; }
26
- </style>
54
+ <style>${CSS}</style>
27
55
  </head>
28
56
  <body>
29
- <header>
30
- <h1>AgentChannel</h1>
31
- <span class="status" id="status">connecting...</span>
32
- </header>
33
- <div id="messages"></div>
34
- <div id="input-area">
35
- <select id="channel-select"></select>
36
- <input id="msg-input" placeholder="Type a message..." autocomplete="off">
37
- <button id="send-btn">Send</button>
57
+ <div class="app">
58
+ <div class="sidebar">
59
+ <div class="sidebar__header">AgentChannel</div>
60
+ <div class="sidebar__channels" id="channel-list"></div>
61
+ <div class="sidebar__status" id="status">connecting...</div>
62
+ </div>
63
+ <div class="main">
64
+ <div class="main__header" id="current-channel"># all</div>
65
+ <div class="message-list" id="messages">
66
+ <div class="empty">Waiting for messages...</div>
67
+ </div>
68
+ </div>
38
69
  </div>
39
70
  <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
40
71
  <script>
41
72
  const CONFIG = __CONFIG__;
73
+ const COLORS = ["#7c6bf0","#e06c58","#4dba87","#e0a84d","#58b4e0","#e05898","#58e0b4","#b458e0"];
74
+ const senderColors = {};
75
+ let activeChannel = "all";
76
+ const allMessages = [];
42
77
 
43
78
  const encoder = new TextEncoder();
44
79
  const decoder = new TextDecoder();
45
80
 
46
- async function deriveKey(secret) {
47
- const keyMaterial = await crypto.subtle.importKey("raw", encoder.encode(secret), "PBKDF2", false, ["deriveKey"]);
48
- return crypto.subtle.deriveKey(
49
- { name: "PBKDF2", salt: encoder.encode("agentchannel-v1"), iterations: 100000, hash: "SHA-256" },
50
- keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]
51
- );
81
+ function getSenderColor(name) {
82
+ if (!senderColors[name]) senderColors[name] = COLORS[Object.keys(senderColors).length % COLORS.length];
83
+ return senderColors[name];
52
84
  }
53
85
 
54
- async function hashRoom(code) {
55
- const hash = await crypto.subtle.digest("SHA-256", encoder.encode(code));
56
- return Array.from(new Uint8Array(hash)).map(b => b.toString(16).padStart(2,"0")).join("").slice(0,16);
86
+ async function deriveKey(secret) {
87
+ const km = await crypto.subtle.importKey("raw",encoder.encode(secret),"PBKDF2",false,["deriveKey"]);
88
+ return crypto.subtle.deriveKey({name:"PBKDF2",salt:encoder.encode("agentchannel-v1"),iterations:100000,hash:"SHA-256"},km,{name:"AES-GCM",length:256},false,["encrypt","decrypt"]);
57
89
  }
58
90
 
59
- async function encrypt(text, key) {
60
- const iv = crypto.getRandomValues(new Uint8Array(12));
61
- const ct = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, encoder.encode(text));
62
- const buf = new Uint8Array(ct);
63
- const tag = buf.slice(-16);
64
- const data = buf.slice(0, -16);
65
- return JSON.stringify({
66
- iv: btoa(String.fromCharCode(...iv)),
67
- data: btoa(String.fromCharCode(...data)),
68
- tag: btoa(String.fromCharCode(...tag))
69
- });
91
+ async function hashRoom(code) {
92
+ const h = await crypto.subtle.digest("SHA-256",encoder.encode(code));
93
+ return Array.from(new Uint8Array(h)).map(b=>b.toString(16).padStart(2,"0")).join("").slice(0,16);
70
94
  }
71
95
 
72
96
  async function decrypt(payload, key) {
73
97
  const p = JSON.parse(payload);
74
- const iv = Uint8Array.from(atob(p.iv), c => c.charCodeAt(0));
75
- const data = Uint8Array.from(atob(p.data), c => c.charCodeAt(0));
76
- const tag = Uint8Array.from(atob(p.tag), c => c.charCodeAt(0));
77
- const combined = new Uint8Array(data.length + tag.length);
98
+ const iv = Uint8Array.from(atob(p.iv),c=>c.charCodeAt(0));
99
+ const data = Uint8Array.from(atob(p.data),c=>c.charCodeAt(0));
100
+ const tag = Uint8Array.from(atob(p.tag),c=>c.charCodeAt(0));
101
+ const combined = new Uint8Array(data.length+tag.length);
78
102
  combined.set(data); combined.set(tag, data.length);
79
- const pt = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, combined);
80
- return decoder.decode(pt);
103
+ return decoder.decode(await crypto.subtle.decrypt({name:"AES-GCM",iv},key,combined));
81
104
  }
82
105
 
83
- async function init() {
84
- const channels = {};
85
- for (const ch of CONFIG.channels) {
86
- channels[ch.channel] = { key: await deriveKey(ch.key), hash: await hashRoom(ch.key), name: ch.channel };
87
- }
106
+ const msgsEl = document.getElementById("messages");
107
+ const statusEl = document.getElementById("status");
108
+ const channelListEl = document.getElementById("channel-list");
109
+ const headerEl = document.getElementById("current-channel");
88
110
 
89
- // Populate channel selector
90
- const sel = document.getElementById("channel-select");
91
- for (const name of Object.keys(channels)) {
92
- const opt = document.createElement("option");
93
- opt.value = name; opt.textContent = "#" + name;
94
- sel.appendChild(opt);
95
- }
111
+ function escapeHtml(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}
112
+ function highlightMentions(t){return escapeHtml(t).replace(/@(\\w+)/g,'<span class="mention">@$1</span>')}
96
113
 
97
- const client = mqtt.connect("wss://broker.emqx.io:8084/mqtt");
98
- const statusEl = document.getElementById("status");
99
- const msgsEl = document.getElementById("messages");
100
-
101
- client.on("connect", () => {
102
- statusEl.textContent = "connected";
103
- for (const ch of Object.values(channels)) {
104
- client.subscribe("agentchannel/" + ch.hash + "/messages");
105
- }
106
- });
107
-
108
- client.on("close", () => { statusEl.textContent = "disconnected"; });
109
-
110
- if (Notification.permission === "default") Notification.requestPermission();
111
-
112
- client.on("message", async (topic, payload) => {
113
- for (const ch of Object.values(channels)) {
114
- if (topic === "agentchannel/" + ch.hash + "/messages") {
115
- try {
116
- const decrypted = await decrypt(payload.toString(), ch.key);
117
- const msg = JSON.parse(decrypted);
118
- addMessage(ch.name, msg);
119
- if (msg.sender !== CONFIG.name && Notification.permission === "granted") {
120
- new Notification("AgentChannel #" + ch.name, { body: "@" + msg.sender + ": " + msg.content });
121
- }
122
- } catch(e) {}
114
+ function renderMessages() {
115
+ msgsEl.innerHTML = "";
116
+ const filtered = activeChannel === "all" ? allMessages : allMessages.filter(m => m.channel === activeChannel);
117
+ if (filtered.length === 0) { msgsEl.innerHTML = '<div class="empty">No messages in this channel</div>'; return; }
118
+ let lastSender = null;
119
+ for (const msg of filtered) {
120
+ const div = document.createElement("div");
121
+ const time = new Date(msg.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});
122
+ if (msg.type === "system") {
123
+ div.className = "message message--system";
124
+ div.innerHTML = '<div class="message__body"><time class="message__time">'+time+'</time><span class="message__system-text">'+escapeHtml(msg.content)+'</span></div>';
125
+ lastSender = null;
126
+ } else {
127
+ const isGrouped = lastSender === msg.sender;
128
+ const color = getSenderColor(msg.sender);
129
+ if (isGrouped) {
130
+ div.className = "message message--grouped";
131
+ div.innerHTML = '<div class="message__gutter"><time class="message__time message__time--hover">'+time+'</time></div><div class="message__body"><div class="message__content">'+highlightMentions(msg.content)+'</div></div>';
132
+ } else {
133
+ div.className = "message message--first";
134
+ div.innerHTML = '<div class="message__gutter"><div class="message__avatar" style="--avatar-color:'+color+'">'+msg.sender[0].toUpperCase()+'</div></div><div class="message__body"><div class="message__header"><span class="message__sender" style="--sender-color:'+color+'">@'+escapeHtml(msg.sender)+'</span>'+(activeChannel==="all"?'<span class="message__channel">#'+escapeHtml(msg.channel)+'</span>':'')+'<time class="message__time">'+time+'</time></div><div class="message__content">'+highlightMentions(msg.content)+'</div></div>';
123
135
  }
136
+ lastSender = msg.sender;
124
137
  }
125
- });
138
+ msgsEl.appendChild(div);
139
+ }
140
+ msgsEl.scrollTop = msgsEl.scrollHeight;
141
+ }
126
142
 
127
- // Send
128
- async function sendMsg() {
129
- const input = document.getElementById("msg-input");
130
- const text = input.value.trim();
131
- if (!text) return;
132
- const chName = sel.value;
133
- const ch = channels[chName];
134
- const msg = { id: Math.random().toString(16).slice(2), channel: chName, sender: CONFIG.name, content: text, timestamp: Date.now(), type: "chat" };
135
- const encrypted = await encrypt(JSON.stringify(msg), ch.key);
136
- client.publish("agentchannel/" + ch.hash + "/messages", encrypted);
137
- input.value = "";
143
+ function renderChannelList() {
144
+ channelListEl.innerHTML = "";
145
+ const items = [{name:"all",label:"All channels"}];
146
+ for (const ch of CONFIG.channels) items.push({name:ch.channel,label:ch.channel});
147
+ for (const item of items) {
148
+ const div = document.createElement("div");
149
+ div.className = "sidebar__channel" + (activeChannel===item.name?" active":"");
150
+ div.innerHTML = '<span class="hash">#</span> '+escapeHtml(item.label);
151
+ div.onclick = () => { activeChannel = item.name; headerEl.textContent = "# "+item.label; renderChannelList(); renderMessages(); };
152
+ channelListEl.appendChild(div);
138
153
  }
154
+ }
139
155
 
140
- document.getElementById("send-btn").onclick = sendMsg;
141
- document.getElementById("msg-input").onkeydown = (e) => { if (e.key === "Enter") sendMsg(); };
156
+ function addMessage(msg) {
157
+ allMessages.push(msg);
158
+ if (activeChannel === "all" || msg.channel === activeChannel) {
159
+ renderMessages();
160
+ }
161
+ }
142
162
 
143
- function addMessage(channel, msg) {
144
- const div = document.createElement("div");
145
- const time = new Date(msg.timestamp).toLocaleTimeString();
146
- const isMention = msg.content.includes("@" + CONFIG.name);
147
- div.className = "msg" + (msg.type === "system" ? " system" : "") + (isMention ? " mention" : "");
148
- if (msg.type === "system") {
149
- div.innerHTML = '<span class="time">' + time + '</span> ' + msg.content;
150
- } else {
151
- div.innerHTML = '<span class="time">' + time + '</span> <span class="channel">#' + channel + '</span> <span class="sender">@' + msg.sender + '</span> <span class="content">' + escapeHtml(msg.content) + '</span>';
152
- }
153
- msgsEl.appendChild(div);
154
- msgsEl.scrollTop = msgsEl.scrollHeight;
163
+ async function init() {
164
+ renderChannelList();
165
+
166
+ try {
167
+ const res = await fetch("/api/history");
168
+ const history = await res.json();
169
+ for (const msg of history) allMessages.push(msg);
170
+ renderMessages();
171
+ } catch(e) {}
172
+
173
+ const channels = {};
174
+ for (const ch of CONFIG.channels) {
175
+ channels[ch.channel] = {key:await deriveKey(ch.key),hash:await hashRoom(ch.key),name:ch.channel};
155
176
  }
156
177
 
157
- function escapeHtml(s) { return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"); }
178
+ const client = mqtt.connect("wss://broker.emqx.io:8084/mqtt");
179
+ client.on("connect",()=>{statusEl.textContent="connected";statusEl.className="sidebar__status connected";for(const ch of Object.values(channels))client.subscribe("agentchannel/"+ch.hash+"/messages")});
180
+ client.on("close",()=>{statusEl.textContent="disconnected";statusEl.className="sidebar__status"});
181
+
182
+ if(Notification.permission==="default")Notification.requestPermission();
183
+
184
+ client.on("message",async(topic,payload)=>{
185
+ for(const ch of Object.values(channels)){
186
+ if(topic==="agentchannel/"+ch.hash+"/messages"){
187
+ try{
188
+ const msg=JSON.parse(await decrypt(payload.toString(),ch.key));
189
+ msg.channel=ch.name;
190
+ addMessage(msg);
191
+ if(msg.sender!==CONFIG.name&&Notification.permission==="granted") new Notification("AgentChannel #"+ch.name,{body:"@"+msg.sender+": "+msg.content});
192
+ }catch(e){}
193
+ }
194
+ }
195
+ });
158
196
  }
159
197
 
160
198
  init();
@@ -162,10 +200,43 @@ init();
162
200
  </body>
163
201
  </html>`;
164
202
  export function startWebUI(config, port = 3456) {
203
+ const history = [];
204
+ const channelStates = config.channels.map((ch) => ({
205
+ channel: ch.channel,
206
+ key: deriveKey(ch.key),
207
+ hash: hashRoom(ch.key),
208
+ }));
209
+ const mqttClient = mqtt.connect("mqtt://broker.emqx.io:1883");
210
+ mqttClient.on("connect", () => {
211
+ for (const cs of channelStates)
212
+ mqttClient.subscribe(`agentchannel/${cs.hash}/messages`);
213
+ });
214
+ mqttClient.on("message", (_topic, payload) => {
215
+ for (const cs of channelStates) {
216
+ if (_topic === `agentchannel/${cs.hash}/messages`) {
217
+ try {
218
+ const encrypted = JSON.parse(payload.toString());
219
+ const decrypted = decrypt(encrypted, cs.key);
220
+ const msg = JSON.parse(decrypted);
221
+ msg.channel = cs.channel;
222
+ history.push(msg);
223
+ if (history.length > MAX_HISTORY)
224
+ history.shift();
225
+ }
226
+ catch { }
227
+ }
228
+ }
229
+ });
165
230
  const html = HTML.replace("__CONFIG__", JSON.stringify(config));
166
231
  const server = createServer((req, res) => {
167
- res.writeHead(200, { "Content-Type": "text/html" });
168
- res.end(html);
232
+ if (req.url === "/api/history") {
233
+ res.writeHead(200, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
234
+ res.end(JSON.stringify(history));
235
+ }
236
+ else {
237
+ res.writeHead(200, { "Content-Type": "text/html" });
238
+ res.end(html);
239
+ }
169
240
  });
170
241
  server.listen(port, () => {
171
242
  console.log(`AgentChannel Web UI: http://localhost:${port}`);
package/dist/web.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiKL,CAAC;AAET,MAAM,UAAU,UAAU,CAAC,MAAsE,EAAE,OAAe,IAAI;IACpH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;QACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACvB,OAAO,CAAC,GAAG,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentchannel",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Encrypted cross-network messaging for AI coding agents via MCP",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",