@agent-relay/daemon 0.1.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 (109) hide show
  1. package/dist/agent-manager.d.ts +134 -0
  2. package/dist/agent-manager.d.ts.map +1 -0
  3. package/dist/agent-manager.js +578 -0
  4. package/dist/agent-manager.js.map +1 -0
  5. package/dist/agent-registry.d.ts +99 -0
  6. package/dist/agent-registry.d.ts.map +1 -0
  7. package/dist/agent-registry.js +213 -0
  8. package/dist/agent-registry.js.map +1 -0
  9. package/dist/agent-signing.d.ts +158 -0
  10. package/dist/agent-signing.d.ts.map +1 -0
  11. package/dist/agent-signing.js +523 -0
  12. package/dist/agent-signing.js.map +1 -0
  13. package/dist/api.d.ts +106 -0
  14. package/dist/api.d.ts.map +1 -0
  15. package/dist/api.js +876 -0
  16. package/dist/api.js.map +1 -0
  17. package/dist/auth.d.ts +94 -0
  18. package/dist/auth.d.ts.map +1 -0
  19. package/dist/auth.js +197 -0
  20. package/dist/auth.js.map +1 -0
  21. package/dist/channel-membership-store.d.ts +55 -0
  22. package/dist/channel-membership-store.d.ts.map +1 -0
  23. package/dist/channel-membership-store.js +176 -0
  24. package/dist/channel-membership-store.js.map +1 -0
  25. package/dist/cli-auth.d.ts +89 -0
  26. package/dist/cli-auth.d.ts.map +1 -0
  27. package/dist/cli-auth.js +792 -0
  28. package/dist/cli-auth.js.map +1 -0
  29. package/dist/cloud-sync.d.ts +150 -0
  30. package/dist/cloud-sync.d.ts.map +1 -0
  31. package/dist/cloud-sync.js +446 -0
  32. package/dist/cloud-sync.js.map +1 -0
  33. package/dist/connection.d.ts +130 -0
  34. package/dist/connection.d.ts.map +1 -0
  35. package/dist/connection.js +438 -0
  36. package/dist/connection.js.map +1 -0
  37. package/dist/consensus-integration.d.ts +167 -0
  38. package/dist/consensus-integration.d.ts.map +1 -0
  39. package/dist/consensus-integration.js +371 -0
  40. package/dist/consensus-integration.js.map +1 -0
  41. package/dist/consensus.d.ts +271 -0
  42. package/dist/consensus.d.ts.map +1 -0
  43. package/dist/consensus.js +632 -0
  44. package/dist/consensus.js.map +1 -0
  45. package/dist/delivery-tracker.d.ts +34 -0
  46. package/dist/delivery-tracker.d.ts.map +1 -0
  47. package/dist/delivery-tracker.js +104 -0
  48. package/dist/delivery-tracker.js.map +1 -0
  49. package/dist/enhanced-features.d.ts +118 -0
  50. package/dist/enhanced-features.d.ts.map +1 -0
  51. package/dist/enhanced-features.js +176 -0
  52. package/dist/enhanced-features.js.map +1 -0
  53. package/dist/index.d.ts +31 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +37 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/migrations/index.d.ts +73 -0
  58. package/dist/migrations/index.d.ts.map +1 -0
  59. package/dist/migrations/index.js +241 -0
  60. package/dist/migrations/index.js.map +1 -0
  61. package/dist/orchestrator.d.ts +217 -0
  62. package/dist/orchestrator.d.ts.map +1 -0
  63. package/dist/orchestrator.js +1143 -0
  64. package/dist/orchestrator.js.map +1 -0
  65. package/dist/rate-limiter.d.ts +68 -0
  66. package/dist/rate-limiter.d.ts.map +1 -0
  67. package/dist/rate-limiter.js +130 -0
  68. package/dist/rate-limiter.js.map +1 -0
  69. package/dist/registry.d.ts +9 -0
  70. package/dist/registry.d.ts.map +1 -0
  71. package/dist/registry.js +9 -0
  72. package/dist/registry.js.map +1 -0
  73. package/dist/relay-ledger.d.ts +261 -0
  74. package/dist/relay-ledger.d.ts.map +1 -0
  75. package/dist/relay-ledger.js +532 -0
  76. package/dist/relay-ledger.js.map +1 -0
  77. package/dist/relay-watchdog.d.ts +125 -0
  78. package/dist/relay-watchdog.d.ts.map +1 -0
  79. package/dist/relay-watchdog.js +611 -0
  80. package/dist/relay-watchdog.js.map +1 -0
  81. package/dist/repo-manager.d.ts +116 -0
  82. package/dist/repo-manager.d.ts.map +1 -0
  83. package/dist/repo-manager.js +384 -0
  84. package/dist/repo-manager.js.map +1 -0
  85. package/dist/router.d.ts +370 -0
  86. package/dist/router.d.ts.map +1 -0
  87. package/dist/router.js +1437 -0
  88. package/dist/router.js.map +1 -0
  89. package/dist/server.d.ts +174 -0
  90. package/dist/server.d.ts.map +1 -0
  91. package/dist/server.js +1001 -0
  92. package/dist/server.js.map +1 -0
  93. package/dist/spawn-manager.d.ts +78 -0
  94. package/dist/spawn-manager.d.ts.map +1 -0
  95. package/dist/spawn-manager.js +165 -0
  96. package/dist/spawn-manager.js.map +1 -0
  97. package/dist/sync-queue.d.ts +116 -0
  98. package/dist/sync-queue.d.ts.map +1 -0
  99. package/dist/sync-queue.js +361 -0
  100. package/dist/sync-queue.js.map +1 -0
  101. package/dist/types.d.ts +133 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +6 -0
  104. package/dist/types.js.map +1 -0
  105. package/dist/workspace-manager.d.ts +80 -0
  106. package/dist/workspace-manager.d.ts.map +1 -0
  107. package/dist/workspace-manager.js +314 -0
  108. package/dist/workspace-manager.js.map +1 -0
  109. package/package.json +52 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Agent Registry
3
+ * Persists agent metadata across daemon restarts.
4
+ */
5
+ /**
6
+ * Agent profile information for display and understanding agent behavior
7
+ */
8
+ export interface AgentProfileRecord {
9
+ /** Display title/role (e.g., "Lead Developer", "Code Reviewer") */
10
+ title?: string;
11
+ /** Short description of what this agent does */
12
+ description?: string;
13
+ /** The prompt/task the agent was spawned with */
14
+ spawnPrompt?: string;
15
+ /** Agent profile/persona prompt (e.g., lead agent instructions) */
16
+ personaPrompt?: string;
17
+ /** Name of the persona preset used (e.g., "lead", "reviewer", "shadow-auditor") */
18
+ personaName?: string;
19
+ /** Capabilities or tools available to the agent */
20
+ capabilities?: string[];
21
+ /** Tags for categorization */
22
+ tags?: string[];
23
+ }
24
+ export interface AgentRecord {
25
+ id: string;
26
+ name: string;
27
+ cli?: string;
28
+ program?: string;
29
+ model?: string;
30
+ task?: string;
31
+ workingDirectory?: string;
32
+ team?: string;
33
+ firstSeen: string;
34
+ lastSeen: string;
35
+ messagesSent: number;
36
+ messagesReceived: number;
37
+ /** Profile information for understanding agent behavior */
38
+ profile?: AgentProfileRecord;
39
+ }
40
+ type AgentInput = {
41
+ name: string;
42
+ cli?: string;
43
+ program?: string;
44
+ model?: string;
45
+ task?: string;
46
+ workingDirectory?: string;
47
+ team?: string;
48
+ profile?: AgentProfileRecord;
49
+ };
50
+ export declare class AgentRegistry {
51
+ private registryPath;
52
+ private agents;
53
+ constructor(teamDir: string);
54
+ /**
55
+ * Register or update an agent (public alias for registerOrUpdate to match docs).
56
+ */
57
+ register(agent: AgentInput): AgentRecord;
58
+ /**
59
+ * Register or update an agent, refreshing lastSeen and metadata.
60
+ */
61
+ registerOrUpdate(agent: AgentInput): AgentRecord;
62
+ /**
63
+ * Increment sent counter for an agent.
64
+ */
65
+ recordSend(agentName: string): void;
66
+ /**
67
+ * Increment received counter for an agent.
68
+ */
69
+ recordReceive(agentName: string): void;
70
+ /**
71
+ * Touch lastSeen for an agent (e.g., on disconnect).
72
+ */
73
+ touch(agentName: string): void;
74
+ /**
75
+ * Get a snapshot of all agents.
76
+ */
77
+ getAgents(): AgentRecord[];
78
+ /**
79
+ * Check if an agent exists in the registry (has connected before).
80
+ * Used by the router to determine if messages should be queued for offline agents.
81
+ */
82
+ has(agentName: string): boolean;
83
+ /**
84
+ * Remove an agent from the registry.
85
+ */
86
+ remove(agentName: string): boolean;
87
+ /**
88
+ * Remove agents that haven't been seen for longer than the threshold.
89
+ * @param thresholdMs - Time in milliseconds (default: 24 hours)
90
+ * @returns Number of agents removed
91
+ */
92
+ pruneStale(thresholdMs?: number): number;
93
+ private ensureRecord;
94
+ private ensureDir;
95
+ load(): void;
96
+ save(): void;
97
+ }
98
+ export {};
99
+ //# sourceMappingURL=agent-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAuC;gBAEzC,OAAO,EAAE,MAAM;IAM3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW;IAIxC;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW;IA+ChD;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQnC;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQtC;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAO9B;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAQlC;;;;OAIG;IACH,UAAU,CAAC,WAAW,GAAE,MAA4B,GAAG,MAAM;IAoB7D,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,SAAS;IAMjB,IAAI,IAAI,IAAI;IAqCZ,IAAI,IAAI,IAAI;CAYb"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Agent Registry
3
+ * Persists agent metadata across daemon restarts.
4
+ */
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { generateId } from '@agent-relay/wrapper';
8
+ import { createLogger } from '@agent-relay/utils/logger';
9
+ const log = createLogger('registry');
10
+ export class AgentRegistry {
11
+ registryPath;
12
+ agents = new Map(); // name -> record
13
+ constructor(teamDir) {
14
+ this.registryPath = path.join(teamDir, 'agents.json');
15
+ this.ensureDir(teamDir);
16
+ this.load();
17
+ }
18
+ /**
19
+ * Register or update an agent (public alias for registerOrUpdate to match docs).
20
+ */
21
+ register(agent) {
22
+ return this.registerOrUpdate(agent);
23
+ }
24
+ /**
25
+ * Register or update an agent, refreshing lastSeen and metadata.
26
+ */
27
+ registerOrUpdate(agent) {
28
+ const now = new Date().toISOString();
29
+ const existing = this.agents.get(agent.name);
30
+ if (existing) {
31
+ // Merge profile data if provided
32
+ const mergedProfile = agent.profile
33
+ ? { ...existing.profile, ...agent.profile }
34
+ : existing.profile;
35
+ const updated = {
36
+ ...existing,
37
+ cli: agent.cli ?? existing.cli,
38
+ program: agent.program ?? existing.program,
39
+ model: agent.model ?? existing.model,
40
+ task: agent.task ?? existing.task,
41
+ workingDirectory: agent.workingDirectory ?? existing.workingDirectory,
42
+ team: agent.team ?? existing.team,
43
+ profile: mergedProfile,
44
+ lastSeen: now,
45
+ };
46
+ this.agents.set(agent.name, updated);
47
+ this.save();
48
+ return updated;
49
+ }
50
+ const record = {
51
+ id: `agent-${generateId()}`,
52
+ name: agent.name,
53
+ cli: agent.cli,
54
+ program: agent.program,
55
+ model: agent.model,
56
+ task: agent.task,
57
+ workingDirectory: agent.workingDirectory,
58
+ team: agent.team,
59
+ profile: agent.profile,
60
+ firstSeen: now,
61
+ lastSeen: now,
62
+ messagesSent: 0,
63
+ messagesReceived: 0,
64
+ };
65
+ this.agents.set(agent.name, record);
66
+ this.save();
67
+ return record;
68
+ }
69
+ /**
70
+ * Increment sent counter for an agent.
71
+ */
72
+ recordSend(agentName) {
73
+ const record = this.ensureRecord(agentName);
74
+ record.messagesSent += 1;
75
+ record.lastSeen = new Date().toISOString();
76
+ this.agents.set(agentName, record);
77
+ this.save();
78
+ }
79
+ /**
80
+ * Increment received counter for an agent.
81
+ */
82
+ recordReceive(agentName) {
83
+ const record = this.ensureRecord(agentName);
84
+ record.messagesReceived += 1;
85
+ record.lastSeen = new Date().toISOString();
86
+ this.agents.set(agentName, record);
87
+ this.save();
88
+ }
89
+ /**
90
+ * Touch lastSeen for an agent (e.g., on disconnect).
91
+ */
92
+ touch(agentName) {
93
+ const record = this.ensureRecord(agentName);
94
+ record.lastSeen = new Date().toISOString();
95
+ this.agents.set(agentName, record);
96
+ this.save();
97
+ }
98
+ /**
99
+ * Get a snapshot of all agents.
100
+ */
101
+ getAgents() {
102
+ return Array.from(this.agents.values());
103
+ }
104
+ /**
105
+ * Check if an agent exists in the registry (has connected before).
106
+ * Used by the router to determine if messages should be queued for offline agents.
107
+ */
108
+ has(agentName) {
109
+ return this.agents.has(agentName);
110
+ }
111
+ /**
112
+ * Remove an agent from the registry.
113
+ */
114
+ remove(agentName) {
115
+ const deleted = this.agents.delete(agentName);
116
+ if (deleted) {
117
+ this.save();
118
+ }
119
+ return deleted;
120
+ }
121
+ /**
122
+ * Remove agents that haven't been seen for longer than the threshold.
123
+ * @param thresholdMs - Time in milliseconds (default: 24 hours)
124
+ * @returns Number of agents removed
125
+ */
126
+ pruneStale(thresholdMs = 24 * 60 * 60 * 1000) {
127
+ const cutoff = Date.now() - thresholdMs;
128
+ let removed = 0;
129
+ for (const [name, record] of this.agents) {
130
+ const lastSeenTime = new Date(record.lastSeen).getTime();
131
+ if (lastSeenTime < cutoff) {
132
+ this.agents.delete(name);
133
+ removed++;
134
+ log.info('Pruned stale agent', { name, lastSeen: record.lastSeen });
135
+ }
136
+ }
137
+ if (removed > 0) {
138
+ this.save();
139
+ }
140
+ return removed;
141
+ }
142
+ ensureRecord(agentName) {
143
+ const existing = this.agents.get(agentName);
144
+ if (existing)
145
+ return existing;
146
+ const now = new Date().toISOString();
147
+ const record = {
148
+ id: `agent-${generateId()}`,
149
+ name: agentName,
150
+ firstSeen: now,
151
+ lastSeen: now,
152
+ messagesSent: 0,
153
+ messagesReceived: 0,
154
+ };
155
+ this.agents.set(agentName, record);
156
+ return record;
157
+ }
158
+ ensureDir(dir) {
159
+ if (!fs.existsSync(dir)) {
160
+ fs.mkdirSync(dir, { recursive: true });
161
+ }
162
+ }
163
+ load() {
164
+ if (!fs.existsSync(this.registryPath)) {
165
+ return;
166
+ }
167
+ try {
168
+ const data = JSON.parse(fs.readFileSync(this.registryPath, 'utf-8'));
169
+ const rawAgents = Array.isArray(data?.agents)
170
+ ? data.agents
171
+ : typeof data?.agents === 'object' && data?.agents !== null
172
+ ? Object.values(data.agents)
173
+ : [];
174
+ for (const raw of rawAgents) {
175
+ if (!raw?.name)
176
+ continue;
177
+ const record = {
178
+ id: raw.id ?? `agent-${generateId()}`,
179
+ name: raw.name,
180
+ cli: raw.cli,
181
+ program: raw.program,
182
+ model: raw.model,
183
+ task: raw.task,
184
+ workingDirectory: raw.workingDirectory,
185
+ team: raw.team,
186
+ profile: raw.profile,
187
+ firstSeen: raw.firstSeen ?? new Date().toISOString(),
188
+ lastSeen: raw.lastSeen ?? new Date().toISOString(),
189
+ messagesSent: typeof raw.messagesSent === 'number' ? raw.messagesSent : 0,
190
+ messagesReceived: typeof raw.messagesReceived === 'number' ? raw.messagesReceived : 0,
191
+ };
192
+ this.agents.set(record.name, record);
193
+ }
194
+ }
195
+ catch (err) {
196
+ log.error('Failed to load agents.json', { error: String(err) });
197
+ }
198
+ }
199
+ save() {
200
+ try {
201
+ const data = JSON.stringify({ agents: this.getAgents() }, null, 2);
202
+ // Write atomically: write to temp file first, then rename
203
+ // This prevents race conditions where readers see partial/empty data
204
+ const tempPath = `${this.registryPath}.tmp`;
205
+ fs.writeFileSync(tempPath, data, 'utf-8');
206
+ fs.renameSync(tempPath, this.registryPath);
207
+ }
208
+ catch (err) {
209
+ log.error('Failed to write agents.json', { error: String(err) });
210
+ }
211
+ }
212
+ }
213
+ //# sourceMappingURL=agent-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;AAkDrC,MAAM,OAAO,aAAa;IAChB,YAAY,CAAS;IACrB,MAAM,GAA6B,IAAI,GAAG,EAAE,CAAC,CAAC,iBAAiB;IAEvE,YAAY,OAAe;QACzB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAiB;QACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,KAAiB;QAChC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,QAAQ,EAAE,CAAC;YACb,iCAAiC;YACjC,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO;gBACjC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE;gBAC3C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YAErB,MAAM,OAAO,GAAgB;gBAC3B,GAAG,QAAQ;gBACX,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG;gBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;gBAC1C,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;gBACpC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI;gBACjC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,QAAQ,CAAC,gBAAgB;gBACrE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI;gBACjC,OAAO,EAAE,aAAa;gBACtB,QAAQ,EAAE,GAAG;aACd,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAgB;YAC1B,EAAE,EAAE,SAAS,UAAU,EAAE,EAAE;YAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,GAAG;YACb,YAAY,EAAE,CAAC;YACf,gBAAgB,EAAE,CAAC;SACpB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,SAAiB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;QACzB,MAAM,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,SAAiB;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAiB;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,SAAiB;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,cAAsB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;QACxC,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YACzD,IAAI,YAAY,GAAG,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzB,OAAO,EAAE,CAAC;gBACV,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,YAAY,CAAC,SAAiB;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,MAAM,GAAgB;YAC1B,EAAE,EAAE,SAAS,UAAU,EAAE,EAAE;YAC3B,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,GAAG;YACb,YAAY,EAAE,CAAC;YACf,gBAAgB,EAAE,CAAC;SACpB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,SAAS,CAAC,GAAW;QAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;gBAC3C,CAAC,CAAC,IAAI,CAAC,MAAM;gBACb,CAAC,CAAC,OAAO,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,IAAI,EAAE,MAAM,KAAK,IAAI;oBACzD,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC5B,CAAC,CAAC,EAAE,CAAC;YAET,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC5B,IAAI,CAAC,GAAG,EAAE,IAAI;oBAAE,SAAS;gBACzB,MAAM,MAAM,GAAgB;oBAC1B,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,SAAS,UAAU,EAAE,EAAE;oBACrC,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;oBACtC,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACpD,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAClD,YAAY,EAAE,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBACzE,gBAAgB,EAAE,OAAO,GAAG,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;iBACtF,CAAC;gBACF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACnE,0DAA0D;YAC1D,qEAAqE;YACrE,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,YAAY,MAAM,CAAC;YAC5C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1C,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Agent Authentication via Cryptographic Signing
3
+ *
4
+ * Provides agent identity verification through message signing.
5
+ * Extends the existing UID/GID-based auth with cryptographic guarantees.
6
+ *
7
+ * Features:
8
+ * - HMAC-SHA256 for shared-secret signing (simpler deployment)
9
+ * - Ed25519 for asymmetric signing (zero-trust mode)
10
+ * - Message signature verification
11
+ * - Key rotation support
12
+ * - Agent identity attestation
13
+ */
14
+ export interface AgentKeyPair {
15
+ /** Agent identifier */
16
+ agentName: string;
17
+ /** Public key (hex) for asymmetric, or key ID for HMAC */
18
+ publicKey: string;
19
+ /** Private/secret key (hex) - never transmitted */
20
+ privateKey: string;
21
+ /** Key creation timestamp */
22
+ createdAt: number;
23
+ /** Optional expiry timestamp */
24
+ expiresAt?: number;
25
+ /** Signing algorithm */
26
+ algorithm: 'hmac-sha256' | 'ed25519';
27
+ }
28
+ export interface SignedMessage {
29
+ /** Original message content */
30
+ content: string;
31
+ /** Signature (hex) */
32
+ signature: string;
33
+ /** Signing agent */
34
+ signer: string;
35
+ /** Timestamp of signing */
36
+ signedAt: number;
37
+ /** Key ID used (for rotation support) */
38
+ keyId: string;
39
+ /** Algorithm used */
40
+ algorithm: 'hmac-sha256' | 'ed25519';
41
+ }
42
+ export interface VerificationResult {
43
+ valid: boolean;
44
+ error?: string;
45
+ signer?: string;
46
+ signedAt?: number;
47
+ }
48
+ export interface AgentSigningConfig {
49
+ /** Enable message signing (default: false) */
50
+ enabled: boolean;
51
+ /** Signing algorithm */
52
+ algorithm: 'hmac-sha256' | 'ed25519';
53
+ /** Require signatures on all messages */
54
+ requireSignatures: boolean;
55
+ /** Allow unsigned messages from specific agents */
56
+ allowUnsignedFrom?: string[];
57
+ /** Key directory path */
58
+ keyDir?: string;
59
+ /** Shared secret for HMAC mode (all agents share) */
60
+ sharedSecret?: string;
61
+ /** Key rotation interval in hours (0 = no rotation) */
62
+ keyRotationHours?: number;
63
+ }
64
+ /**
65
+ * Generate a new agent key pair.
66
+ */
67
+ export declare function generateAgentKey(agentName: string, algorithm?: 'hmac-sha256' | 'ed25519', expiresInHours?: number): AgentKeyPair;
68
+ /**
69
+ * Save agent key to disk (private key file).
70
+ */
71
+ export declare function saveAgentKey(key: AgentKeyPair, keyDir?: string): void;
72
+ /**
73
+ * Load agent key from disk.
74
+ */
75
+ export declare function loadAgentKey(agentName: string, keyDir?: string): AgentKeyPair | null;
76
+ /**
77
+ * Load or generate agent key.
78
+ */
79
+ export declare function getOrCreateAgentKey(agentName: string, config: AgentSigningConfig, keyDir?: string): AgentKeyPair;
80
+ /**
81
+ * Sign a message using the agent's private key.
82
+ */
83
+ export declare function signMessage(content: string, key: AgentKeyPair): SignedMessage;
84
+ /**
85
+ * Sign with shared secret (HMAC mode where all agents share a secret).
86
+ */
87
+ export declare function signWithSharedSecret(content: string, agentName: string, sharedSecret: string): SignedMessage;
88
+ /**
89
+ * Verify a signed message using the agent's public key.
90
+ */
91
+ export declare function verifyMessage(signed: SignedMessage, key: AgentKeyPair): VerificationResult;
92
+ /**
93
+ * Verify an Ed25519 signed message using only the public key.
94
+ * This is the key advantage of asymmetric signing - verifiers don't need the private key.
95
+ */
96
+ export declare function verifyEd25519WithPublicKey(signed: SignedMessage, publicKeyPem: string, expectedSigner: string): VerificationResult;
97
+ /**
98
+ * Verify with shared secret.
99
+ */
100
+ export declare function verifyWithSharedSecret(signed: SignedMessage, sharedSecret: string): VerificationResult;
101
+ /**
102
+ * Manages agent signing keys and verification.
103
+ */
104
+ export declare class AgentSigningManager {
105
+ private config;
106
+ private keyDir;
107
+ private keys;
108
+ constructor(config?: Partial<AgentSigningConfig>, keyDir?: string);
109
+ /**
110
+ * Check if signing is enabled.
111
+ */
112
+ get enabled(): boolean;
113
+ /**
114
+ * Get or load key for an agent.
115
+ */
116
+ getKey(agentName: string): AgentKeyPair | null;
117
+ /**
118
+ * Register a new agent (generate and save key).
119
+ */
120
+ registerAgent(agentName: string): AgentKeyPair;
121
+ /**
122
+ * Sign a message for an agent.
123
+ */
124
+ sign(agentName: string, content: string): SignedMessage | null;
125
+ /**
126
+ * Verify a signed message.
127
+ */
128
+ verify(signed: SignedMessage): VerificationResult;
129
+ /**
130
+ * Check if a message requires verification.
131
+ */
132
+ requiresVerification(agentName: string): boolean;
133
+ /**
134
+ * Rotate key for an agent.
135
+ */
136
+ rotateKey(agentName: string): AgentKeyPair;
137
+ /**
138
+ * Export public key for an agent (for sharing with other systems).
139
+ */
140
+ exportPublicKey(agentName: string): {
141
+ agentName: string;
142
+ publicKey: string;
143
+ algorithm: string;
144
+ } | null;
145
+ }
146
+ /**
147
+ * Attach signature to protocol envelope.
148
+ */
149
+ export declare function attachSignature(envelope: Record<string, unknown>, signed: SignedMessage): Record<string, unknown>;
150
+ /**
151
+ * Extract signature from protocol envelope.
152
+ */
153
+ export declare function extractSignature(envelope: Record<string, unknown>): SignedMessage | null;
154
+ /**
155
+ * Load signing configuration from file.
156
+ */
157
+ export declare function loadSigningConfig(configPath?: string): AgentSigningConfig;
158
+ //# sourceMappingURL=agent-signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-signing.d.ts","sourceRoot":"","sources":["../src/agent-signing.ts"],"names":[],"mappings":"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"}