agentchannel 0.6.0 → 0.7.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.
- package/dist/cli.js +114 -18
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +16 -3
- package/dist/config.js +44 -9
- package/dist/config.js.map +1 -1
- package/dist/crypto.d.ts +26 -2
- package/dist/crypto.js +63 -8
- package/dist/crypto.js.map +1 -1
- package/dist/identity.d.ts +10 -0
- package/dist/identity.js +48 -0
- package/dist/identity.js.map +1 -0
- package/dist/mqtt-client.d.ts +14 -2
- package/dist/mqtt-client.js +148 -28
- package/dist/mqtt-client.js.map +1 -1
- package/dist/persistence.d.ts +7 -0
- package/dist/persistence.js +23 -0
- package/dist/persistence.js.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +2 -1
- package/dist/store.js +10 -4
- package/dist/store.js.map +1 -1
- package/dist/tools/channel.js +18 -11
- package/dist/tools/channel.js.map +1 -1
- package/dist/tools/get-message.d.ts +3 -0
- package/dist/tools/get-message.js +27 -0
- package/dist/tools/get-message.js.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/members.js +10 -5
- package/dist/tools/members.js.map +1 -1
- package/dist/tools/read.js +17 -4
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/send.js +8 -5
- package/dist/tools/send.js.map +1 -1
- package/dist/trust-store.d.ts +14 -0
- package/dist/trust-store.js +56 -0
- package/dist/trust-store.js.map +1 -0
- package/dist/types.d.ts +17 -1
- package/dist/web.js +351 -38
- package/dist/web.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerGetMessageTool(server, getClient) {
|
|
3
|
+
server.registerTool("get_message", {
|
|
4
|
+
title: "Get Message",
|
|
5
|
+
description: "Get the full content of a single message by ID. Use read_messages(preview=true) first to get message IDs.",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
id: z.string().describe("Message ID from read_messages preview"),
|
|
8
|
+
},
|
|
9
|
+
}, async ({ id }) => {
|
|
10
|
+
const client = getClient();
|
|
11
|
+
const msg = client.store.getMessageById(id);
|
|
12
|
+
if (!msg) {
|
|
13
|
+
return {
|
|
14
|
+
content: [{ type: "text", text: `Message ${id} not found.` }],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const time = new Date(msg.timestamp).toLocaleTimeString();
|
|
18
|
+
const trust = msg.trustLevel ? ` [${msg.trustLevel.toUpperCase()}]` : "";
|
|
19
|
+
const fp = msg.senderKey ? `:${msg.senderKey.slice(0, 4)}` : "";
|
|
20
|
+
const label = msg.subchannel ? `#${msg.channel} ##${msg.subchannel}` : `#${msg.channel}`;
|
|
21
|
+
const text = `[${time}] ${label} | @${msg.sender}${fp}${trust}:\n\n${msg.content}`;
|
|
22
|
+
return {
|
|
23
|
+
content: [{ type: "text", text }],
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=get-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-message.js","sourceRoot":"","sources":["../../src/tools/get-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,SAAgC;IACxF,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,2GAA2G;QACxH,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;SACjE;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAE5C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;aACvE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACzF,MAAM,IAAI,GAAG,IAAI,IAAI,KAAK,KAAK,OAAO,GAAG,CAAC,MAAM,GAAG,EAAE,GAAG,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,CAAC;QAEnF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;SAC3C,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -5,9 +5,11 @@ import { registerNameTool } from "./name.js";
|
|
|
5
5
|
import { registerChannelTools } from "./channel.js";
|
|
6
6
|
import { registerUnreadTool } from "./unread.js";
|
|
7
7
|
import { registerMuteTools } from "./mute.js";
|
|
8
|
+
import { registerGetMessageTool } from "./get-message.js";
|
|
8
9
|
export function registerAllTools(server, getClient) {
|
|
9
10
|
registerSendTool(server, getClient);
|
|
10
11
|
registerReadTool(server, getClient);
|
|
12
|
+
registerGetMessageTool(server, getClient);
|
|
11
13
|
registerMembersTool(server, getClient);
|
|
12
14
|
registerNameTool(server, getClient);
|
|
13
15
|
registerChannelTools(server, getClient);
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAAgC;IAClF,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,sBAAsB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC1C,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC"}
|
package/dist/tools/members.js
CHANGED
|
@@ -2,22 +2,27 @@ import { z } from "zod";
|
|
|
2
2
|
export function registerMembersTool(server, getClient) {
|
|
3
3
|
server.registerTool("list_members", {
|
|
4
4
|
title: "List Members",
|
|
5
|
-
description: "List members in a channel with last active time.",
|
|
5
|
+
description: "List members in a #channel or ##subchannel with last active time and fingerprint.",
|
|
6
6
|
inputSchema: {
|
|
7
7
|
channel: z.string().optional().describe("Channel name (optional, shows all if omitted)"),
|
|
8
|
+
subchannel: z.string().optional().describe("Subchannel name"),
|
|
8
9
|
},
|
|
9
|
-
}, async ({ channel }) => {
|
|
10
|
+
}, async ({ channel, subchannel }) => {
|
|
10
11
|
const client = getClient();
|
|
11
|
-
const
|
|
12
|
+
const key = subchannel && channel ? `${channel}/${subchannel}` : channel;
|
|
13
|
+
const members = client.store.getMembers(key);
|
|
12
14
|
if (members.length === 0) {
|
|
15
|
+
const label = subchannel ? `#${channel} ##${subchannel}` : channel ? `#${channel}` : "any channel";
|
|
13
16
|
return {
|
|
14
|
-
content: [{ type: "text", text:
|
|
17
|
+
content: [{ type: "text", text: `No members in ${label}.` }],
|
|
15
18
|
};
|
|
16
19
|
}
|
|
17
20
|
const formatted = members
|
|
18
21
|
.map((m) => {
|
|
19
22
|
const active = client.store.formatLastActive(m.lastActive);
|
|
20
|
-
|
|
23
|
+
const label = m.subchannel ? `#${m.channel} ##${m.subchannel}` : `#${m.channel}`;
|
|
24
|
+
const fp = m.fingerprint ? `:${m.fingerprint.slice(0, 4)}` : "";
|
|
25
|
+
return `- @${m.name}${fp} in ${label} (active ${active})`;
|
|
21
26
|
})
|
|
22
27
|
.join("\n");
|
|
23
28
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"members.js","sourceRoot":"","sources":["../../src/tools/members.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,SAAgC;IACrF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"members.js","sourceRoot":"","sources":["../../src/tools/members.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,SAAgC;IACrF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,mFAAmF;QAChG,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;YACxF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;SAC9D;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACzE,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAE7C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,OAAO,MAAM,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;YACnG,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iBAAiB,KAAK,GAAG,EAAE,CAAC;aACtE,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACjF,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,OAAO,MAAM,CAAC,CAAC,IAAI,GAAG,EAAE,OAAO,KAAK,YAAY,MAAM,GAAG,CAAC;QAC5D,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,aAAa,SAAS,EAAE,EAAE,CAAC;SACrE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/tools/read.js
CHANGED
|
@@ -2,17 +2,22 @@ import { z } from "zod";
|
|
|
2
2
|
export function registerReadTool(server, getClient) {
|
|
3
3
|
server.registerTool("read_messages", {
|
|
4
4
|
title: "Read Messages",
|
|
5
|
-
description: "Read recent messages from channels.",
|
|
5
|
+
description: "Read recent messages from #channels or ##subchannels. Use preview=true to get a compact list (saves tokens), then get_message to read full content.",
|
|
6
6
|
inputSchema: {
|
|
7
7
|
limit: z.number().optional().default(20).describe("Number of recent messages to return (default 20, max 100)"),
|
|
8
|
-
channel: z.string().optional().describe("Filter by channel name
|
|
8
|
+
channel: z.string().optional().describe("Filter by channel name"),
|
|
9
|
+
subchannel: z.string().optional().describe("Filter by subchannel name"),
|
|
10
|
+
preview: z.boolean().optional().default(false).describe("If true, return compact preview (id + sender + first line only). Use get_message(id) to read full content."),
|
|
9
11
|
},
|
|
10
|
-
}, async ({ limit, channel }) => {
|
|
12
|
+
}, async ({ limit, channel, subchannel, preview }) => {
|
|
11
13
|
const client = getClient();
|
|
12
14
|
let messages = client.store.getMessages(Math.min(limit, 100));
|
|
13
15
|
if (channel) {
|
|
14
16
|
messages = messages.filter((m) => m.channel === channel);
|
|
15
17
|
}
|
|
18
|
+
if (subchannel) {
|
|
19
|
+
messages = messages.filter((m) => m.subchannel === subchannel);
|
|
20
|
+
}
|
|
16
21
|
if (messages.length === 0) {
|
|
17
22
|
return {
|
|
18
23
|
content: [{ type: "text", text: "No messages yet." }],
|
|
@@ -25,7 +30,15 @@ export function registerReadTool(server, getClient) {
|
|
|
25
30
|
const mention = m.content.includes(`@${myName}`) ? " [MENTION]" : "";
|
|
26
31
|
if (m.type === "system")
|
|
27
32
|
return `[${time}] ${m.content}`;
|
|
28
|
-
|
|
33
|
+
const label = m.subchannel ? `#${m.channel} ##${m.subchannel}` : `#${m.channel}`;
|
|
34
|
+
const fp = m.senderKey ? `:${m.senderKey.slice(0, 4)}` : "";
|
|
35
|
+
if (preview) {
|
|
36
|
+
const firstLine = m.content.split("\n").find((l) => l.trim()) || m.content;
|
|
37
|
+
const short = firstLine.length > 80 ? firstLine.slice(0, 80) + "..." : firstLine;
|
|
38
|
+
return `[${m.id}] [${time}] ${label} | @${m.sender}${fp}: ${short}${mention}`;
|
|
39
|
+
}
|
|
40
|
+
const trust = m.trustLevel ? ` [${m.trustLevel.toUpperCase()}]` : "";
|
|
41
|
+
return `[${time}] ${label} | @${m.sender}${fp}${trust}: ${m.content}${mention}`;
|
|
29
42
|
})
|
|
30
43
|
.join("\n");
|
|
31
44
|
client.store.markAsRead();
|
package/dist/tools/read.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAAgC;IAClF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/send.js
CHANGED
|
@@ -2,19 +2,22 @@ import { z } from "zod";
|
|
|
2
2
|
export function registerSendTool(server, getClient) {
|
|
3
3
|
server.registerTool("send_message", {
|
|
4
4
|
title: "Send Message",
|
|
5
|
-
description: "Send an encrypted message to a channel
|
|
5
|
+
description: "Send an encrypted message to a #channel or ##subchannel.",
|
|
6
6
|
inputSchema: {
|
|
7
7
|
message: z.string().describe("The message content to send"),
|
|
8
|
-
channel: z.string().describe("Target channel name (
|
|
8
|
+
channel: z.string().describe("Target channel name (e.g. 'agentchannel')"),
|
|
9
|
+
subchannel: z.string().optional().describe("Target subchannel name (e.g. 'product'). Omit to send to the main channel."),
|
|
9
10
|
},
|
|
10
|
-
}, async ({ message, channel }) => {
|
|
11
|
+
}, async ({ message, channel, subchannel }) => {
|
|
11
12
|
const client = getClient();
|
|
12
|
-
const
|
|
13
|
+
const target = subchannel ? `${channel}/${subchannel}` : channel;
|
|
14
|
+
const msg = await client.send(message, target);
|
|
15
|
+
const label = msg.subchannel ? `#${msg.channel} ##${msg.subchannel}` : `#${msg.channel}`;
|
|
13
16
|
return {
|
|
14
17
|
content: [
|
|
15
18
|
{
|
|
16
19
|
type: "text",
|
|
17
|
-
text: `Message sent to
|
|
20
|
+
text: `Message sent to ${label} by @${msg.sender} at ${new Date(msg.timestamp).toISOString()}`,
|
|
18
21
|
},
|
|
19
22
|
],
|
|
20
23
|
};
|
package/dist/tools/send.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAAgC;IAClF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAAgC;IAClF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,0DAA0D;QACvE,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACzE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;SACzH;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACzF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,mBAAmB,KAAK,QAAQ,GAAG,CAAC,MAAM,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;iBAC/F;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type TrustLevel = "tofu" | "verified" | "revoked" | "new";
|
|
2
|
+
export interface KnownKey {
|
|
3
|
+
publicKeyPem: string;
|
|
4
|
+
fingerprint: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
firstSeen: number;
|
|
7
|
+
lastSeen: number;
|
|
8
|
+
trustLevel: TrustLevel;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkTrust(fingerprint: string, publicKeyPem: string, displayName: string): {
|
|
11
|
+
level: TrustLevel;
|
|
12
|
+
warning?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function getTrustLevel(fingerprint: string): TrustLevel;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const TRUST_FILE = join(homedir(), ".agentchannel", "known_keys.json");
|
|
5
|
+
let cache = null;
|
|
6
|
+
function load() {
|
|
7
|
+
if (cache)
|
|
8
|
+
return cache;
|
|
9
|
+
try {
|
|
10
|
+
cache = JSON.parse(readFileSync(TRUST_FILE, "utf-8"));
|
|
11
|
+
return cache;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
cache = {};
|
|
15
|
+
return cache;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function save() {
|
|
19
|
+
mkdirSync(join(homedir(), ".agentchannel"), { recursive: true });
|
|
20
|
+
writeFileSync(TRUST_FILE, JSON.stringify(cache, null, 2));
|
|
21
|
+
}
|
|
22
|
+
export function checkTrust(fingerprint, publicKeyPem, displayName) {
|
|
23
|
+
const store = load();
|
|
24
|
+
const existing = store[fingerprint];
|
|
25
|
+
if (!existing) {
|
|
26
|
+
// First time seeing this key — TOFU
|
|
27
|
+
store[fingerprint] = {
|
|
28
|
+
publicKeyPem,
|
|
29
|
+
fingerprint,
|
|
30
|
+
displayName,
|
|
31
|
+
firstSeen: Date.now(),
|
|
32
|
+
lastSeen: Date.now(),
|
|
33
|
+
trustLevel: "tofu",
|
|
34
|
+
};
|
|
35
|
+
save();
|
|
36
|
+
return { level: "tofu" };
|
|
37
|
+
}
|
|
38
|
+
if (existing.trustLevel === "revoked") {
|
|
39
|
+
return { level: "revoked", warning: `Key ${fingerprint} has been revoked` };
|
|
40
|
+
}
|
|
41
|
+
// Update last seen
|
|
42
|
+
existing.lastSeen = Date.now();
|
|
43
|
+
// Check if display name changed
|
|
44
|
+
let warning;
|
|
45
|
+
if (existing.displayName !== displayName) {
|
|
46
|
+
warning = `Display name changed: "${existing.displayName}" → "${displayName}"`;
|
|
47
|
+
existing.displayName = displayName;
|
|
48
|
+
}
|
|
49
|
+
save();
|
|
50
|
+
return { level: existing.trustLevel, warning };
|
|
51
|
+
}
|
|
52
|
+
export function getTrustLevel(fingerprint) {
|
|
53
|
+
const store = load();
|
|
54
|
+
return store[fingerprint]?.trustLevel ?? "new";
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=trust-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-store.js","sourceRoot":"","sources":["../src/trust-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;AAavE,IAAI,KAAK,GAAoC,IAAI,CAAC;AAElD,SAAS,IAAI;IACX,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QACtD,OAAO,KAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,IAAI;IACX,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,YAAoB,EAAE,WAAmB;IACvF,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;IACrB,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;IAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,oCAAoC;QACpC,KAAK,CAAC,WAAW,CAAC,GAAG;YACnB,YAAY;YACZ,WAAW;YACX,WAAW;YACX,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;YACpB,UAAU,EAAE,MAAM;SACnB,CAAC;QACF,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,WAAW,mBAAmB,EAAE,CAAC;IAC9E,CAAC;IAED,mBAAmB;IACnB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE/B,gCAAgC;IAChC,IAAI,OAA2B,CAAC;IAChC,IAAI,QAAQ,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;QACzC,OAAO,GAAG,0BAA0B,QAAQ,CAAC,WAAW,QAAQ,WAAW,GAAG,CAAC;QAC/E,QAAQ,CAAC,WAAW,GAAG,WAAW,CAAC;IACrC,CAAC;IAED,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;IACrB,OAAO,KAAK,CAAC,WAAW,CAAC,EAAE,UAAU,IAAI,KAAK,CAAC;AACjD,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,31 +1,47 @@
|
|
|
1
1
|
export interface Message {
|
|
2
2
|
id: string;
|
|
3
3
|
channel: string;
|
|
4
|
+
subchannel?: string;
|
|
4
5
|
sender: string;
|
|
5
6
|
content: string;
|
|
6
7
|
timestamp: number;
|
|
7
|
-
type?: "chat" | "system" | "action_request";
|
|
8
|
+
type?: "chat" | "system" | "action_request" | "channel_meta";
|
|
9
|
+
senderKey?: string;
|
|
10
|
+
signature?: string;
|
|
11
|
+
trustLevel?: string;
|
|
8
12
|
}
|
|
9
13
|
export interface Member {
|
|
10
14
|
name: string;
|
|
11
15
|
channel: string;
|
|
16
|
+
subchannel?: string;
|
|
12
17
|
joinedAt: number;
|
|
13
18
|
lastActive: number;
|
|
19
|
+
fingerprint?: string;
|
|
14
20
|
}
|
|
15
21
|
export interface ChannelConfig {
|
|
16
22
|
channel: string;
|
|
23
|
+
subchannel?: string;
|
|
17
24
|
key: string;
|
|
18
25
|
}
|
|
19
26
|
export interface ChatConfig {
|
|
20
27
|
channels: ChannelConfig[];
|
|
21
28
|
name: string;
|
|
22
29
|
broker?: string;
|
|
30
|
+
silent?: boolean;
|
|
23
31
|
}
|
|
24
32
|
export interface SingleChannelConfig {
|
|
25
33
|
channel: string;
|
|
34
|
+
subchannel?: string;
|
|
26
35
|
name: string;
|
|
27
36
|
key: string;
|
|
28
37
|
broker?: string;
|
|
38
|
+
silent?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface ChannelMeta {
|
|
41
|
+
name: string;
|
|
42
|
+
subchannels: string[];
|
|
43
|
+
owners: string[];
|
|
44
|
+
created: number;
|
|
29
45
|
}
|
|
30
46
|
export interface EncryptedPayload {
|
|
31
47
|
iv: string;
|