@tjamescouch/agentchat 0.22.0 → 0.23.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 (135) hide show
  1. package/Dockerfile +1 -1
  2. package/dist/bin/agentchat.d.ts +7 -0
  3. package/dist/bin/agentchat.d.ts.map +1 -0
  4. package/dist/bin/agentchat.js +1511 -0
  5. package/dist/bin/agentchat.js.map +1 -0
  6. package/dist/lib/allowlist.d.ts +77 -0
  7. package/dist/lib/allowlist.d.ts.map +1 -0
  8. package/dist/lib/allowlist.js +151 -0
  9. package/dist/lib/allowlist.js.map +1 -0
  10. package/dist/lib/client.d.ts +147 -0
  11. package/dist/lib/client.d.ts.map +1 -0
  12. package/dist/lib/client.js +704 -0
  13. package/dist/lib/client.js.map +1 -0
  14. package/dist/lib/daemon.d.ts +122 -0
  15. package/dist/lib/daemon.d.ts.map +1 -0
  16. package/dist/lib/daemon.js +523 -0
  17. package/dist/lib/daemon.js.map +1 -0
  18. package/dist/lib/deploy/akash.d.ts +271 -0
  19. package/dist/lib/deploy/akash.d.ts.map +1 -0
  20. package/dist/lib/deploy/akash.js +671 -0
  21. package/dist/lib/deploy/akash.js.map +1 -0
  22. package/dist/lib/deploy/config.d.ts +62 -0
  23. package/dist/lib/deploy/config.d.ts.map +1 -0
  24. package/dist/lib/deploy/config.js +116 -0
  25. package/dist/lib/deploy/config.js.map +1 -0
  26. package/dist/lib/deploy/docker.d.ts +37 -0
  27. package/dist/lib/deploy/docker.d.ts.map +1 -0
  28. package/dist/lib/deploy/docker.js +122 -0
  29. package/dist/lib/deploy/docker.js.map +1 -0
  30. package/dist/lib/deploy/index.d.ts +11 -0
  31. package/dist/lib/deploy/index.d.ts.map +1 -0
  32. package/dist/lib/deploy/index.js +11 -0
  33. package/dist/lib/deploy/index.js.map +1 -0
  34. package/dist/lib/escrow-hooks.d.ts +199 -0
  35. package/dist/lib/escrow-hooks.d.ts.map +1 -0
  36. package/dist/lib/escrow-hooks.js +221 -0
  37. package/dist/lib/escrow-hooks.js.map +1 -0
  38. package/dist/lib/identity.d.ts +134 -0
  39. package/dist/lib/identity.d.ts.map +1 -0
  40. package/dist/lib/identity.js +334 -0
  41. package/dist/lib/identity.js.map +1 -0
  42. package/dist/lib/jitter.d.ts +42 -0
  43. package/dist/lib/jitter.d.ts.map +1 -0
  44. package/{lib → dist/lib}/jitter.js +16 -19
  45. package/dist/lib/jitter.js.map +1 -0
  46. package/dist/lib/proposals.d.ts +223 -0
  47. package/dist/lib/proposals.d.ts.map +1 -0
  48. package/dist/lib/proposals.js +379 -0
  49. package/dist/lib/proposals.js.map +1 -0
  50. package/dist/lib/protocol.d.ts +220 -0
  51. package/dist/lib/protocol.d.ts.map +1 -0
  52. package/dist/lib/protocol.js +507 -0
  53. package/dist/lib/protocol.js.map +1 -0
  54. package/dist/lib/receipts.d.ts +134 -0
  55. package/dist/lib/receipts.d.ts.map +1 -0
  56. package/dist/lib/receipts.js +270 -0
  57. package/dist/lib/receipts.js.map +1 -0
  58. package/dist/lib/reputation.d.ts +250 -0
  59. package/dist/lib/reputation.d.ts.map +1 -0
  60. package/dist/lib/reputation.js +586 -0
  61. package/dist/lib/reputation.js.map +1 -0
  62. package/dist/lib/security.d.ts +27 -0
  63. package/dist/lib/security.d.ts.map +1 -0
  64. package/dist/lib/security.js +150 -0
  65. package/dist/lib/security.js.map +1 -0
  66. package/dist/lib/server/handlers/admin.d.ts +26 -0
  67. package/dist/lib/server/handlers/admin.d.ts.map +1 -0
  68. package/dist/lib/server/handlers/admin.js +76 -0
  69. package/dist/lib/server/handlers/admin.js.map +1 -0
  70. package/dist/lib/server/handlers/identity.d.ts +36 -0
  71. package/dist/lib/server/handlers/identity.d.ts.map +1 -0
  72. package/dist/lib/server/handlers/identity.js +330 -0
  73. package/dist/lib/server/handlers/identity.js.map +1 -0
  74. package/dist/lib/server/handlers/index.d.ts +10 -0
  75. package/dist/lib/server/handlers/index.d.ts.map +1 -0
  76. package/dist/lib/server/handlers/index.js +15 -0
  77. package/dist/lib/server/handlers/index.js.map +1 -0
  78. package/dist/lib/server/handlers/message.d.ts +47 -0
  79. package/dist/lib/server/handlers/message.d.ts.map +1 -0
  80. package/dist/lib/server/handlers/message.js +265 -0
  81. package/dist/lib/server/handlers/message.js.map +1 -0
  82. package/dist/lib/server/handlers/presence.d.ts +18 -0
  83. package/dist/lib/server/handlers/presence.d.ts.map +1 -0
  84. package/dist/lib/server/handlers/presence.js +35 -0
  85. package/dist/lib/server/handlers/presence.js.map +1 -0
  86. package/dist/lib/server/handlers/proposal.d.ts +38 -0
  87. package/dist/lib/server/handlers/proposal.d.ts.map +1 -0
  88. package/dist/lib/server/handlers/proposal.js +273 -0
  89. package/dist/lib/server/handlers/proposal.js.map +1 -0
  90. package/dist/lib/server/handlers/skills.d.ts +22 -0
  91. package/dist/lib/server/handlers/skills.d.ts.map +1 -0
  92. package/dist/lib/server/handlers/skills.js +119 -0
  93. package/dist/lib/server/handlers/skills.js.map +1 -0
  94. package/dist/lib/server-directory.d.ts +85 -0
  95. package/dist/lib/server-directory.d.ts.map +1 -0
  96. package/dist/lib/server-directory.js +177 -0
  97. package/dist/lib/server-directory.js.map +1 -0
  98. package/dist/lib/server.d.ts +162 -0
  99. package/dist/lib/server.d.ts.map +1 -0
  100. package/dist/lib/server.js +602 -0
  101. package/dist/lib/server.js.map +1 -0
  102. package/dist/lib/types.d.ts +461 -0
  103. package/dist/lib/types.d.ts.map +1 -0
  104. package/dist/lib/types.js +98 -0
  105. package/dist/lib/types.js.map +1 -0
  106. package/package.json +22 -13
  107. package/bin/agentchat.js +0 -1617
  108. package/lib/chat.py +0 -241
  109. package/lib/client.js +0 -821
  110. package/lib/daemon.js +0 -562
  111. package/lib/deploy/akash.js +0 -811
  112. package/lib/deploy/config.js +0 -128
  113. package/lib/deploy/docker.js +0 -132
  114. package/lib/deploy/index.js +0 -24
  115. package/lib/elo_swarm.py +0 -569
  116. package/lib/escrow-hooks.js +0 -237
  117. package/lib/identity.js +0 -376
  118. package/lib/proposals.js +0 -426
  119. package/lib/protocol.js +0 -484
  120. package/lib/receipts.js +0 -294
  121. package/lib/reputation.js +0 -664
  122. package/lib/security.js +0 -183
  123. package/lib/server/handlers/identity.js +0 -242
  124. package/lib/server/handlers/index.js +0 -42
  125. package/lib/server/handlers/message.js +0 -306
  126. package/lib/server/handlers/presence.js +0 -44
  127. package/lib/server/handlers/proposal.js +0 -358
  128. package/lib/server/handlers/skills.js +0 -141
  129. package/lib/server-directory.js +0 -181
  130. package/lib/server.js +0 -528
  131. package/lib/supervisor/USAGE.md +0 -110
  132. package/lib/supervisor/agent-supervisor.sh +0 -135
  133. package/lib/supervisor/agentctl.sh +0 -250
  134. package/lib/supervisor/killswitch.sh +0 -36
  135. package/lib/supervisor/notify.sh +0 -19
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Security utilities for AgentChat
3
+ * Prevents running agents in dangerous directories
4
+ */
5
+ import path from 'path';
6
+ import os from 'os';
7
+ // Directories that are absolutely forbidden (system roots)
8
+ const FORBIDDEN_DIRECTORIES = new Set([
9
+ '/',
10
+ '/root',
11
+ '/home',
12
+ '/Users',
13
+ '/var',
14
+ '/etc',
15
+ '/usr',
16
+ '/bin',
17
+ '/sbin',
18
+ '/lib',
19
+ '/opt',
20
+ '/tmp',
21
+ '/System',
22
+ '/Applications',
23
+ '/Library',
24
+ '/private',
25
+ '/private/var',
26
+ '/private/tmp',
27
+ 'C:\\',
28
+ 'C:\\Windows',
29
+ 'C:\\Program Files',
30
+ 'C:\\Program Files (x86)',
31
+ 'C:\\Users',
32
+ ]);
33
+ // Minimum depth from root required for a "project" directory
34
+ // e.g., /Users/name/projects/myproject = depth 4 (minimum required)
35
+ const MIN_SAFE_DEPTH = 3;
36
+ /**
37
+ * Get the depth of a path from root
38
+ */
39
+ function getPathDepth(dirPath) {
40
+ const normalized = path.normalize(dirPath);
41
+ const parts = normalized.split(path.sep).filter(p => p && p !== '.');
42
+ return parts.length;
43
+ }
44
+ /**
45
+ * Check if directory is a user's home directory
46
+ */
47
+ function isHomeDirectory(dirPath) {
48
+ const normalized = path.normalize(dirPath);
49
+ const homeDir = os.homedir();
50
+ // Check exact match with home directory
51
+ if (normalized === homeDir || normalized === homeDir + path.sep) {
52
+ return true;
53
+ }
54
+ // Check common home directory patterns
55
+ const homePatterns = [
56
+ /^\/Users\/[^/]+$/, // macOS: /Users/username
57
+ /^\/home\/[^/]+$/, // Linux: /home/username
58
+ /^C:\\Users\\[^\\]+$/i, // Windows: C:\Users\username
59
+ ];
60
+ return homePatterns.some(pattern => pattern.test(normalized));
61
+ }
62
+ /**
63
+ * Check if a directory is safe for running agentchat
64
+ */
65
+ export function checkDirectorySafety(dirPath = process.cwd()) {
66
+ const normalized = path.normalize(path.resolve(dirPath));
67
+ // Check forbidden directories
68
+ if (FORBIDDEN_DIRECTORIES.has(normalized)) {
69
+ return {
70
+ safe: false,
71
+ level: 'error',
72
+ error: `Cannot run agentchat in system directory: ${normalized}\n` +
73
+ `Please run from a project directory instead.`
74
+ };
75
+ }
76
+ // Check if it's a home directory BEFORE depth check
77
+ // Home directories are allowed but warn (they're at depth 2 which would fail depth check)
78
+ if (isHomeDirectory(normalized)) {
79
+ return {
80
+ safe: true,
81
+ level: 'warning',
82
+ warning: `Running agentchat in home directory: ${normalized}\n` +
83
+ `Consider running from a specific project directory instead.`
84
+ };
85
+ }
86
+ // Check path depth (too shallow = too close to root)
87
+ const depth = getPathDepth(normalized);
88
+ if (depth < MIN_SAFE_DEPTH) {
89
+ return {
90
+ safe: false,
91
+ level: 'error',
92
+ error: `Cannot run agentchat in root-level directory: ${normalized}\n` +
93
+ `This directory is too close to the filesystem root.\n` +
94
+ `Please run from a project directory (at least ${MIN_SAFE_DEPTH} levels deep).`
95
+ };
96
+ }
97
+ // All checks passed
98
+ return {
99
+ safe: true,
100
+ level: 'ok'
101
+ };
102
+ }
103
+ /**
104
+ * Enforce directory safety check - throws if unsafe
105
+ */
106
+ export function enforceDirectorySafety(dirPath = process.cwd(), options = {}) {
107
+ const { allowWarnings = true, silent = false } = options;
108
+ const result = checkDirectorySafety(dirPath);
109
+ if (result.level === 'error') {
110
+ throw new Error(result.error);
111
+ }
112
+ if (result.level === 'warning') {
113
+ if (!silent) {
114
+ console.error(`\n⚠️ WARNING: ${result.warning}\n`);
115
+ }
116
+ if (!allowWarnings) {
117
+ throw new Error(result.warning);
118
+ }
119
+ }
120
+ return result;
121
+ }
122
+ /**
123
+ * Check if running in a project directory (has common project indicators)
124
+ */
125
+ export function looksLikeProjectDirectory(dirPath = process.cwd()) {
126
+ const projectIndicators = [
127
+ 'package.json',
128
+ 'Cargo.toml',
129
+ 'go.mod',
130
+ 'pyproject.toml',
131
+ 'setup.py',
132
+ 'requirements.txt',
133
+ 'Gemfile',
134
+ 'pom.xml',
135
+ 'build.gradle',
136
+ 'Makefile',
137
+ 'CMakeLists.txt',
138
+ '.git',
139
+ '.gitignore',
140
+ 'README.md',
141
+ 'README',
142
+ ];
143
+ // This is a heuristic check - doesn't actually verify files exist
144
+ // Just checks if the path looks reasonable
145
+ const normalized = path.normalize(path.resolve(dirPath));
146
+ const depth = getPathDepth(normalized);
147
+ // If it's deep enough and not a system directory, it probably looks like a project
148
+ return depth >= MIN_SAFE_DEPTH && !FORBIDDEN_DIRECTORIES.has(normalized);
149
+ }
150
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../lib/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Admin Handlers
3
+ * Handles allowlist administration commands
4
+ */
5
+ import type { WebSocket } from 'ws';
6
+ import type { AgentChatServer } from '../../server.js';
7
+ import type { AdminApproveMessage, AdminRevokeMessage, AdminListMessage } from '../../types.js';
8
+ interface ExtendedWebSocket extends WebSocket {
9
+ _connectedAt?: number;
10
+ _realIp?: string;
11
+ _userAgent?: string;
12
+ }
13
+ /**
14
+ * Handle ADMIN_APPROVE command - add a pubkey to the allowlist
15
+ */
16
+ export declare function handleAdminApprove(server: AgentChatServer, ws: ExtendedWebSocket, msg: AdminApproveMessage): void;
17
+ /**
18
+ * Handle ADMIN_REVOKE command - remove a pubkey from the allowlist
19
+ */
20
+ export declare function handleAdminRevoke(server: AgentChatServer, ws: ExtendedWebSocket, msg: AdminRevokeMessage): void;
21
+ /**
22
+ * Handle ADMIN_LIST command - list all approved entries
23
+ */
24
+ export declare function handleAdminList(server: AgentChatServer, ws: ExtendedWebSocket, msg: AdminListMessage): void;
25
+ export {};
26
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../../lib/server/handlers/admin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AASxB,UAAU,iBAAkB,SAAQ,SAAS;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAwBjH;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAyB/G;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAmB3G"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Admin Handlers
3
+ * Handles allowlist administration commands
4
+ */
5
+ import { ServerMessageType, ErrorCode, createMessage, createError, } from '../../protocol.js';
6
+ /**
7
+ * Handle ADMIN_APPROVE command - add a pubkey to the allowlist
8
+ */
9
+ export function handleAdminApprove(server, ws, msg) {
10
+ if (!server.allowlist) {
11
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Allowlist not configured'));
12
+ return;
13
+ }
14
+ if (!msg.pubkey) {
15
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Missing pubkey'));
16
+ return;
17
+ }
18
+ const result = server.allowlist.approve(msg.pubkey, msg.admin_key, msg.note || '');
19
+ if (!result.success) {
20
+ server._send(ws, createError(ErrorCode.AUTH_REQUIRED, result.error));
21
+ return;
22
+ }
23
+ server._log('admin_approve', { agentId: result.agentId });
24
+ server._send(ws, createMessage(ServerMessageType.ADMIN_RESULT, {
25
+ action: 'approve',
26
+ success: true,
27
+ agentId: `@${result.agentId}`,
28
+ }));
29
+ }
30
+ /**
31
+ * Handle ADMIN_REVOKE command - remove a pubkey from the allowlist
32
+ */
33
+ export function handleAdminRevoke(server, ws, msg) {
34
+ if (!server.allowlist) {
35
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Allowlist not configured'));
36
+ return;
37
+ }
38
+ const identifier = msg.pubkey || msg.agent_id;
39
+ if (!identifier) {
40
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Missing pubkey or agent_id'));
41
+ return;
42
+ }
43
+ const result = server.allowlist.revoke(identifier, msg.admin_key);
44
+ if (!result.success) {
45
+ const code = result.error === 'invalid admin key' ? ErrorCode.AUTH_REQUIRED : ErrorCode.AGENT_NOT_FOUND;
46
+ server._send(ws, createError(code, result.error));
47
+ return;
48
+ }
49
+ server._log('admin_revoke', { identifier });
50
+ server._send(ws, createMessage(ServerMessageType.ADMIN_RESULT, {
51
+ action: 'revoke',
52
+ success: true,
53
+ }));
54
+ }
55
+ /**
56
+ * Handle ADMIN_LIST command - list all approved entries
57
+ */
58
+ export function handleAdminList(server, ws, msg) {
59
+ if (!server.allowlist) {
60
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Allowlist not configured'));
61
+ return;
62
+ }
63
+ // Validate admin key
64
+ if (!server.allowlist._validateAdminKey(msg.admin_key)) {
65
+ server._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Invalid admin key'));
66
+ return;
67
+ }
68
+ const entries = server.allowlist.list();
69
+ server._send(ws, createMessage(ServerMessageType.ADMIN_RESULT, {
70
+ action: 'list',
71
+ entries,
72
+ enabled: server.allowlist.enabled,
73
+ strict: server.allowlist.strict,
74
+ }));
75
+ }
76
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../lib/server/handlers/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Identity Handlers
3
+ * Handles identify, verification request/response
4
+ */
5
+ import type { WebSocket } from 'ws';
6
+ import type { AgentChatServer } from '../../server.js';
7
+ import type { IdentifyMessage, VerifyIdentityMessage, VerifyRequestMessage, VerifyResponseMessage } from '../../types.js';
8
+ interface ExtendedWebSocket extends WebSocket {
9
+ _connectedAt?: number;
10
+ _realIp?: string;
11
+ _userAgent?: string;
12
+ }
13
+ /**
14
+ * Handle IDENTIFY command
15
+ *
16
+ * For ephemeral agents (no pubkey): immediately create agent state and send WELCOME.
17
+ * For pubkey agents: send CHALLENGE, wait for VERIFY_IDENTITY before creating state.
18
+ */
19
+ export declare function handleIdentify(server: AgentChatServer, ws: ExtendedWebSocket, msg: IdentifyMessage): void;
20
+ /**
21
+ * Handle VERIFY_IDENTITY command
22
+ *
23
+ * Verifies the challenge-response signature. On success, creates agent state
24
+ * and sends WELCOME. On failure, sends error.
25
+ */
26
+ export declare function handleVerifyIdentity(server: AgentChatServer, ws: ExtendedWebSocket, msg: VerifyIdentityMessage): void;
27
+ /**
28
+ * Handle VERIFY_REQUEST command
29
+ */
30
+ export declare function handleVerifyRequest(server: AgentChatServer, ws: ExtendedWebSocket, msg: VerifyRequestMessage): void;
31
+ /**
32
+ * Handle VERIFY_RESPONSE command
33
+ */
34
+ export declare function handleVerifyResponse(server: AgentChatServer, ws: ExtendedWebSocket, msg: VerifyResponseMessage): void;
35
+ export {};
36
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../../lib/server/handlers/identity.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAgBxB,UAAU,iBAAkB,SAAQ,SAAS;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAqGzG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,qBAAqB,GAAG,IAAI,CAiGrH;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,oBAAoB,GAAG,IAAI,CAsEnH;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,qBAAqB,GAAG,IAAI,CA6ErH"}
@@ -0,0 +1,330 @@
1
+ /**
2
+ * Identity Handlers
3
+ * Handles identify, verification request/response
4
+ */
5
+ import crypto from 'crypto';
6
+ import { ServerMessageType, ErrorCode, createMessage, createError, generateAgentId, generateVerifyId, generateChallengeId, generateNonce, generateAuthSigningContent, pubkeyToAgentId, } from '../../protocol.js';
7
+ import { Identity } from '../../identity.js';
8
+ /**
9
+ * Handle IDENTIFY command
10
+ *
11
+ * For ephemeral agents (no pubkey): immediately create agent state and send WELCOME.
12
+ * For pubkey agents: send CHALLENGE, wait for VERIFY_IDENTITY before creating state.
13
+ */
14
+ export function handleIdentify(server, ws, msg) {
15
+ // Check if already identified
16
+ if (server.agents.has(ws)) {
17
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Already identified'));
18
+ return;
19
+ }
20
+ // Check if this ws already has a pending challenge
21
+ for (const [, challenge] of server.pendingChallenges) {
22
+ if (challenge.ws === ws) {
23
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Challenge already pending'));
24
+ return;
25
+ }
26
+ }
27
+ // Allowlist check (before any state changes)
28
+ if (server.allowlist && server.allowlist.enabled) {
29
+ const check = server.allowlist.check(msg.pubkey || null);
30
+ if (!check.allowed) {
31
+ server._log('allowlist_rejected', {
32
+ ip: ws._realIp,
33
+ name: msg.name,
34
+ hasPubkey: !!msg.pubkey,
35
+ reason: check.reason
36
+ });
37
+ server._send(ws, createError(ErrorCode.NOT_ALLOWED, check.reason));
38
+ return;
39
+ }
40
+ }
41
+ if (msg.pubkey) {
42
+ // Pubkey agent: send challenge, do NOT create agent state yet
43
+ const challengeId = generateChallengeId();
44
+ const nonce = generateNonce();
45
+ const expiresAt = Date.now() + server.challengeTimeoutMs;
46
+ server.pendingChallenges.set(challengeId, {
47
+ ws,
48
+ name: msg.name,
49
+ pubkey: msg.pubkey,
50
+ nonce,
51
+ challengeId,
52
+ expires: expiresAt
53
+ });
54
+ // Set timeout to clean up expired challenges
55
+ setTimeout(() => {
56
+ const challenge = server.pendingChallenges.get(challengeId);
57
+ if (challenge) {
58
+ server.pendingChallenges.delete(challengeId);
59
+ if (challenge.ws.readyState === 1) {
60
+ server._send(challenge.ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Challenge expired'));
61
+ challenge.ws.close(1000, 'Challenge expired');
62
+ }
63
+ }
64
+ }, server.challengeTimeoutMs);
65
+ server._log('challenge_sent', {
66
+ challengeId,
67
+ name: msg.name,
68
+ ip: ws._realIp
69
+ });
70
+ server._send(ws, createMessage(ServerMessageType.CHALLENGE, {
71
+ challenge_id: challengeId,
72
+ nonce,
73
+ expires_at: expiresAt
74
+ }));
75
+ }
76
+ else {
77
+ // Ephemeral agent: create state immediately
78
+ const id = generateAgentId();
79
+ const agent = {
80
+ id,
81
+ name: msg.name,
82
+ pubkey: null,
83
+ channels: new Set(),
84
+ connectedAt: Date.now(),
85
+ presence: 'online',
86
+ status_text: null,
87
+ verified: false
88
+ };
89
+ server.agents.set(ws, agent);
90
+ server.agentById.set(id, ws);
91
+ server._log('identify', {
92
+ id,
93
+ name: msg.name,
94
+ hasPubkey: false,
95
+ ephemeral: true,
96
+ ip: ws._realIp,
97
+ user_agent: ws._userAgent
98
+ });
99
+ server._send(ws, createMessage(ServerMessageType.WELCOME, {
100
+ agent_id: `@${id}`,
101
+ name: msg.name,
102
+ server: server.serverName
103
+ }));
104
+ }
105
+ }
106
+ /**
107
+ * Handle VERIFY_IDENTITY command
108
+ *
109
+ * Verifies the challenge-response signature. On success, creates agent state
110
+ * and sends WELCOME. On failure, sends error.
111
+ */
112
+ export function handleVerifyIdentity(server, ws, msg) {
113
+ // Check if already identified
114
+ if (server.agents.has(ws)) {
115
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Already identified'));
116
+ return;
117
+ }
118
+ // Look up the pending challenge
119
+ const challenge = server.pendingChallenges.get(msg.challenge_id);
120
+ if (!challenge) {
121
+ server._send(ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Challenge not found or expired'));
122
+ return;
123
+ }
124
+ // Verify this is the same websocket that initiated the challenge
125
+ if (challenge.ws !== ws) {
126
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Challenge belongs to a different connection'));
127
+ return;
128
+ }
129
+ // Check expiration
130
+ if (Date.now() > challenge.expires) {
131
+ server.pendingChallenges.delete(msg.challenge_id);
132
+ server._send(ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Challenge expired'));
133
+ return;
134
+ }
135
+ // Verify the signature
136
+ const expectedContent = generateAuthSigningContent(challenge.nonce, msg.challenge_id, msg.timestamp);
137
+ const verified = Identity.verify(expectedContent, msg.signature, challenge.pubkey);
138
+ if (!verified) {
139
+ server.pendingChallenges.delete(msg.challenge_id);
140
+ server._log('challenge_failed', {
141
+ challengeId: msg.challenge_id,
142
+ name: challenge.name,
143
+ ip: ws._realIp
144
+ });
145
+ server._send(ws, createError(ErrorCode.VERIFICATION_FAILED, 'Invalid signature'));
146
+ return;
147
+ }
148
+ // Challenge passed — clean up pending challenge
149
+ server.pendingChallenges.delete(msg.challenge_id);
150
+ // Derive stable agent ID from pubkey
151
+ const existingId = server.pubkeyToId.get(challenge.pubkey);
152
+ let id;
153
+ if (existingId) {
154
+ id = existingId;
155
+ }
156
+ else {
157
+ id = pubkeyToAgentId(challenge.pubkey);
158
+ server.pubkeyToId.set(challenge.pubkey, id);
159
+ }
160
+ // Check if this ID is currently in use by another connection
161
+ if (server.agentById.has(id)) {
162
+ const oldWs = server.agentById.get(id);
163
+ server._log('identity-takeover', { id, reason: 'Verified connection replacing existing' });
164
+ server._send(oldWs, createError(ErrorCode.INVALID_MSG, 'Disconnected: Another connection verified this identity'));
165
+ server._handleDisconnect(oldWs);
166
+ oldWs.close(1000, 'Identity claimed by verified connection');
167
+ }
168
+ // Create agent state with verified = true
169
+ const agent = {
170
+ id,
171
+ name: challenge.name,
172
+ pubkey: challenge.pubkey,
173
+ channels: new Set(),
174
+ connectedAt: Date.now(),
175
+ presence: 'online',
176
+ status_text: null,
177
+ verified: true
178
+ };
179
+ server.agents.set(ws, agent);
180
+ server.agentById.set(id, ws);
181
+ const isReturning = !!existingId;
182
+ server._log('identify', {
183
+ id,
184
+ name: challenge.name,
185
+ hasPubkey: true,
186
+ verified: true,
187
+ returning: isReturning,
188
+ ip: ws._realIp,
189
+ user_agent: ws._userAgent
190
+ });
191
+ server._send(ws, createMessage(ServerMessageType.WELCOME, {
192
+ agent_id: `@${id}`,
193
+ name: challenge.name,
194
+ server: server.serverName,
195
+ verified: true
196
+ }));
197
+ }
198
+ /**
199
+ * Handle VERIFY_REQUEST command
200
+ */
201
+ export function handleVerifyRequest(server, ws, msg) {
202
+ const agent = server.agents.get(ws);
203
+ if (!agent) {
204
+ server._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
205
+ return;
206
+ }
207
+ // Find target agent
208
+ const targetId = msg.target.slice(1);
209
+ const targetWs = server.agentById.get(targetId);
210
+ if (!targetWs) {
211
+ server._send(ws, createError(ErrorCode.AGENT_NOT_FOUND, `Agent ${msg.target} not found`));
212
+ return;
213
+ }
214
+ const targetAgent = server.agents.get(targetWs);
215
+ // Target must have a pubkey for verification
216
+ if (!targetAgent?.pubkey) {
217
+ server._send(ws, createError(ErrorCode.NO_PUBKEY, `Agent ${msg.target} has no persistent identity`));
218
+ return;
219
+ }
220
+ // Create verification request
221
+ const requestId = generateVerifyId();
222
+ const expires = Date.now() + server.verificationTimeoutMs;
223
+ const pendingVerification = {
224
+ from: `@${agent.id}`,
225
+ fromWs: ws,
226
+ target: msg.target,
227
+ targetPubkey: targetAgent.pubkey,
228
+ nonce: msg.nonce,
229
+ expires
230
+ };
231
+ server.pendingVerifications.set(requestId, pendingVerification);
232
+ // Set timeout to clean up expired requests
233
+ setTimeout(() => {
234
+ const request = server.pendingVerifications.get(requestId);
235
+ if (request) {
236
+ server.pendingVerifications.delete(requestId);
237
+ // Notify requester of timeout
238
+ if (request.fromWs.readyState === 1) {
239
+ server._send(request.fromWs, createMessage(ServerMessageType.VERIFY_FAILED, {
240
+ request_id: requestId,
241
+ target: request.target,
242
+ reason: 'Verification timed out'
243
+ }));
244
+ }
245
+ }
246
+ }, server.verificationTimeoutMs);
247
+ server._log('verify_request', { id: requestId, from: agent.id, target: targetId });
248
+ // Forward to target agent
249
+ server._send(targetWs, createMessage(ServerMessageType.VERIFY_REQUEST, {
250
+ request_id: requestId,
251
+ from: `@${agent.id}`,
252
+ nonce: msg.nonce
253
+ }));
254
+ // Acknowledge to requester
255
+ server._send(ws, createMessage(ServerMessageType.VERIFY_REQUEST, {
256
+ request_id: requestId,
257
+ target: msg.target,
258
+ status: 'pending'
259
+ }));
260
+ }
261
+ /**
262
+ * Handle VERIFY_RESPONSE command
263
+ */
264
+ export function handleVerifyResponse(server, ws, msg) {
265
+ const agent = server.agents.get(ws);
266
+ if (!agent) {
267
+ server._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
268
+ return;
269
+ }
270
+ // Must have identity to respond to verification
271
+ if (!agent.pubkey) {
272
+ server._send(ws, createError(ErrorCode.SIGNATURE_REQUIRED, 'Responding to verification requires persistent identity'));
273
+ return;
274
+ }
275
+ // Find the pending verification
276
+ const request = server.pendingVerifications.get(msg.request_id);
277
+ if (!request) {
278
+ server._send(ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Verification request not found or expired'));
279
+ return;
280
+ }
281
+ // Verify the responder is the target
282
+ if (request.target !== `@${agent.id}`) {
283
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'You are not the target of this verification'));
284
+ return;
285
+ }
286
+ // Verify the nonce matches
287
+ if (msg.nonce !== request.nonce) {
288
+ server._send(ws, createError(ErrorCode.INVALID_MSG, 'Nonce mismatch'));
289
+ return;
290
+ }
291
+ // Verify the signature
292
+ let verified = false;
293
+ try {
294
+ const keyObj = crypto.createPublicKey(request.targetPubkey);
295
+ verified = crypto.verify(null, Buffer.from(msg.nonce), keyObj, Buffer.from(msg.sig, 'base64'));
296
+ }
297
+ catch (err) {
298
+ server._log('verify_error', { request_id: msg.request_id, error: err.message });
299
+ }
300
+ // Clean up the pending request
301
+ server.pendingVerifications.delete(msg.request_id);
302
+ server._log('verify_response', {
303
+ request_id: msg.request_id,
304
+ from: agent.id,
305
+ verified
306
+ });
307
+ // Notify the original requester
308
+ if (request.fromWs.readyState === 1) {
309
+ if (verified) {
310
+ server._send(request.fromWs, createMessage(ServerMessageType.VERIFY_SUCCESS, {
311
+ request_id: msg.request_id,
312
+ agent: request.target,
313
+ pubkey: request.targetPubkey
314
+ }));
315
+ }
316
+ else {
317
+ server._send(request.fromWs, createMessage(ServerMessageType.VERIFY_FAILED, {
318
+ request_id: msg.request_id,
319
+ target: request.target,
320
+ reason: 'Signature verification failed'
321
+ }));
322
+ }
323
+ }
324
+ // Notify the responder
325
+ server._send(ws, createMessage(verified ? ServerMessageType.VERIFY_SUCCESS : ServerMessageType.VERIFY_FAILED, {
326
+ request_id: msg.request_id,
327
+ verified
328
+ }));
329
+ }
330
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../../lib/server/handlers/identity.ts"],"names":[],"mappings":"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"}