network-ai 4.15.2 → 5.0.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 (204) hide show
  1. package/INTEGRATION_GUIDE.md +11 -4
  2. package/QUICKSTART.md +31 -4
  3. package/README.md +37 -15
  4. package/bin/dashboard.ts +146 -0
  5. package/bin/mcp-server.ts +3 -2
  6. package/dist/adapters/adapter-registry.d.ts +33 -1
  7. package/dist/adapters/adapter-registry.d.ts.map +1 -1
  8. package/dist/adapters/adapter-registry.js +49 -0
  9. package/dist/adapters/adapter-registry.js.map +1 -1
  10. package/dist/adapters/anthropic-computer-use-adapter.d.ts +132 -0
  11. package/dist/adapters/anthropic-computer-use-adapter.d.ts.map +1 -0
  12. package/dist/adapters/anthropic-computer-use-adapter.js +180 -0
  13. package/dist/adapters/anthropic-computer-use-adapter.js.map +1 -0
  14. package/dist/adapters/browser-agent-adapter.d.ts +121 -0
  15. package/dist/adapters/browser-agent-adapter.d.ts.map +1 -0
  16. package/dist/adapters/browser-agent-adapter.js +219 -0
  17. package/dist/adapters/browser-agent-adapter.js.map +1 -0
  18. package/dist/adapters/copilot-adapter.d.ts +59 -0
  19. package/dist/adapters/copilot-adapter.d.ts.map +1 -0
  20. package/dist/adapters/copilot-adapter.js +132 -0
  21. package/dist/adapters/copilot-adapter.js.map +1 -0
  22. package/dist/adapters/index.d.ts +15 -1
  23. package/dist/adapters/index.d.ts.map +1 -1
  24. package/dist/adapters/index.js +22 -1
  25. package/dist/adapters/index.js.map +1 -1
  26. package/dist/adapters/langgraph-adapter.d.ts +70 -0
  27. package/dist/adapters/langgraph-adapter.d.ts.map +1 -0
  28. package/dist/adapters/langgraph-adapter.js +119 -0
  29. package/dist/adapters/langgraph-adapter.js.map +1 -0
  30. package/dist/adapters/openai-agents-adapter.d.ts +100 -0
  31. package/dist/adapters/openai-agents-adapter.d.ts.map +1 -0
  32. package/dist/adapters/openai-agents-adapter.js +118 -0
  33. package/dist/adapters/openai-agents-adapter.js.map +1 -0
  34. package/dist/adapters/pydantic-ai-adapter.d.ts +104 -0
  35. package/dist/adapters/pydantic-ai-adapter.d.ts.map +1 -0
  36. package/dist/adapters/pydantic-ai-adapter.js +163 -0
  37. package/dist/adapters/pydantic-ai-adapter.js.map +1 -0
  38. package/dist/adapters/vertex-ai-adapter.d.ts +122 -0
  39. package/dist/adapters/vertex-ai-adapter.d.ts.map +1 -0
  40. package/dist/adapters/vertex-ai-adapter.js +166 -0
  41. package/dist/adapters/vertex-ai-adapter.js.map +1 -0
  42. package/dist/bin/dashboard.d.ts +11 -0
  43. package/dist/bin/dashboard.d.ts.map +1 -0
  44. package/dist/bin/dashboard.js +135 -0
  45. package/dist/bin/dashboard.js.map +1 -0
  46. package/dist/bin/mcp-server.js +3 -2
  47. package/dist/bin/mcp-server.js.map +1 -1
  48. package/dist/index.d.ts +103 -559
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +295 -1074
  51. package/dist/index.js.map +1 -1
  52. package/dist/lib/adapter-test-harness.d.ts +88 -0
  53. package/dist/lib/adapter-test-harness.d.ts.map +1 -0
  54. package/dist/lib/adapter-test-harness.js +118 -0
  55. package/dist/lib/adapter-test-harness.js.map +1 -0
  56. package/dist/lib/agent-conversation.d.ts +115 -0
  57. package/dist/lib/agent-conversation.d.ts.map +1 -0
  58. package/dist/lib/agent-conversation.js +155 -0
  59. package/dist/lib/agent-conversation.js.map +1 -0
  60. package/dist/lib/agent-debate.d.ts +115 -0
  61. package/dist/lib/agent-debate.d.ts.map +1 -0
  62. package/dist/lib/agent-debate.js +146 -0
  63. package/dist/lib/agent-debate.js.map +1 -0
  64. package/dist/lib/agent-memory.d.ts +157 -0
  65. package/dist/lib/agent-memory.d.ts.map +1 -0
  66. package/dist/lib/agent-memory.js +336 -0
  67. package/dist/lib/agent-memory.js.map +1 -0
  68. package/dist/lib/agent-vcr.d.ts +133 -0
  69. package/dist/lib/agent-vcr.d.ts.map +1 -0
  70. package/dist/lib/agent-vcr.js +218 -0
  71. package/dist/lib/agent-vcr.js.map +1 -0
  72. package/dist/lib/anomaly-detector.d.ts +112 -0
  73. package/dist/lib/anomaly-detector.d.ts.map +1 -0
  74. package/dist/lib/anomaly-detector.js +178 -0
  75. package/dist/lib/anomaly-detector.js.map +1 -0
  76. package/dist/lib/approval-inbox.d.ts +147 -0
  77. package/dist/lib/approval-inbox.d.ts.map +1 -0
  78. package/dist/lib/approval-inbox.js +385 -0
  79. package/dist/lib/approval-inbox.js.map +1 -0
  80. package/dist/lib/auth-guardian.d.ts +170 -0
  81. package/dist/lib/auth-guardian.d.ts.map +1 -0
  82. package/dist/lib/auth-guardian.js +604 -0
  83. package/dist/lib/auth-guardian.js.map +1 -0
  84. package/dist/lib/auth-validator.d.ts +70 -0
  85. package/dist/lib/auth-validator.d.ts.map +1 -0
  86. package/dist/lib/auth-validator.js +32 -0
  87. package/dist/lib/auth-validator.js.map +1 -0
  88. package/dist/lib/blackboard-validator.d.ts +56 -0
  89. package/dist/lib/blackboard-validator.d.ts.map +1 -1
  90. package/dist/lib/blackboard-validator.js +181 -4
  91. package/dist/lib/blackboard-validator.js.map +1 -1
  92. package/dist/lib/comparison-runner.d.ts +99 -0
  93. package/dist/lib/comparison-runner.d.ts.map +1 -0
  94. package/dist/lib/comparison-runner.js +138 -0
  95. package/dist/lib/comparison-runner.js.map +1 -0
  96. package/dist/lib/config-watcher.d.ts +109 -0
  97. package/dist/lib/config-watcher.d.ts.map +1 -0
  98. package/dist/lib/config-watcher.js +215 -0
  99. package/dist/lib/config-watcher.js.map +1 -0
  100. package/dist/lib/cost-governor.d.ts +105 -0
  101. package/dist/lib/cost-governor.d.ts.map +1 -0
  102. package/dist/lib/cost-governor.js +128 -0
  103. package/dist/lib/cost-governor.js.map +1 -0
  104. package/dist/lib/cost-heatmap.d.ts +104 -0
  105. package/dist/lib/cost-heatmap.d.ts.map +1 -0
  106. package/dist/lib/cost-heatmap.js +161 -0
  107. package/dist/lib/cost-heatmap.js.map +1 -0
  108. package/dist/lib/coverage-reporter.d.ts +92 -0
  109. package/dist/lib/coverage-reporter.d.ts.map +1 -0
  110. package/dist/lib/coverage-reporter.js +177 -0
  111. package/dist/lib/coverage-reporter.js.map +1 -0
  112. package/dist/lib/dashboard-server.d.ts +71 -0
  113. package/dist/lib/dashboard-server.d.ts.map +1 -0
  114. package/dist/lib/dashboard-server.js +403 -0
  115. package/dist/lib/dashboard-server.js.map +1 -0
  116. package/dist/lib/dry-run.d.ts +73 -0
  117. package/dist/lib/dry-run.d.ts.map +1 -0
  118. package/dist/lib/dry-run.js +130 -0
  119. package/dist/lib/dry-run.js.map +1 -0
  120. package/dist/lib/errors.d.ts +15 -0
  121. package/dist/lib/errors.d.ts.map +1 -1
  122. package/dist/lib/errors.js +38 -0
  123. package/dist/lib/errors.js.map +1 -1
  124. package/dist/lib/event-bus.d.ts +167 -0
  125. package/dist/lib/event-bus.d.ts.map +1 -0
  126. package/dist/lib/event-bus.js +229 -0
  127. package/dist/lib/event-bus.js.map +1 -0
  128. package/dist/lib/explainability.d.ts +85 -0
  129. package/dist/lib/explainability.d.ts.map +1 -0
  130. package/dist/lib/explainability.js +102 -0
  131. package/dist/lib/explainability.js.map +1 -0
  132. package/dist/lib/goal-dsl.d.ts +157 -0
  133. package/dist/lib/goal-dsl.d.ts.map +1 -0
  134. package/dist/lib/goal-dsl.js +392 -0
  135. package/dist/lib/goal-dsl.js.map +1 -0
  136. package/dist/lib/job-queue.d.ts +183 -0
  137. package/dist/lib/job-queue.d.ts.map +1 -0
  138. package/dist/lib/job-queue.js +310 -0
  139. package/dist/lib/job-queue.js.map +1 -0
  140. package/dist/lib/learning-loop.d.ts +113 -0
  141. package/dist/lib/learning-loop.d.ts.map +1 -0
  142. package/dist/lib/learning-loop.js +181 -0
  143. package/dist/lib/learning-loop.js.map +1 -0
  144. package/dist/lib/lifecycle-hooks.d.ts +116 -0
  145. package/dist/lib/lifecycle-hooks.d.ts.map +1 -0
  146. package/dist/lib/lifecycle-hooks.js +148 -0
  147. package/dist/lib/lifecycle-hooks.js.map +1 -0
  148. package/dist/lib/locked-blackboard.d.ts.map +1 -1
  149. package/dist/lib/locked-blackboard.js +9 -5
  150. package/dist/lib/locked-blackboard.js.map +1 -1
  151. package/dist/lib/mcp-tool-consumer.d.ts +153 -0
  152. package/dist/lib/mcp-tool-consumer.d.ts.map +1 -0
  153. package/dist/lib/mcp-tool-consumer.js +320 -0
  154. package/dist/lib/mcp-tool-consumer.js.map +1 -0
  155. package/dist/lib/metrics.d.ts +119 -0
  156. package/dist/lib/metrics.d.ts.map +1 -0
  157. package/dist/lib/metrics.js +284 -0
  158. package/dist/lib/metrics.js.map +1 -0
  159. package/dist/lib/orchestrator-types.d.ts +309 -0
  160. package/dist/lib/orchestrator-types.d.ts.map +1 -0
  161. package/dist/lib/orchestrator-types.js +61 -0
  162. package/dist/lib/orchestrator-types.js.map +1 -0
  163. package/dist/lib/otel-bridge.d.ts +74 -0
  164. package/dist/lib/otel-bridge.d.ts.map +1 -0
  165. package/dist/lib/otel-bridge.js +167 -0
  166. package/dist/lib/otel-bridge.js.map +1 -0
  167. package/dist/lib/playground.d.ts +76 -0
  168. package/dist/lib/playground.d.ts.map +1 -0
  169. package/dist/lib/playground.js +224 -0
  170. package/dist/lib/playground.js.map +1 -0
  171. package/dist/lib/quadtree.d.ts +114 -0
  172. package/dist/lib/quadtree.d.ts.map +1 -0
  173. package/dist/lib/quadtree.js +259 -0
  174. package/dist/lib/quadtree.js.map +1 -0
  175. package/dist/lib/shared-blackboard.d.ts +101 -0
  176. package/dist/lib/shared-blackboard.d.ts.map +1 -0
  177. package/dist/lib/shared-blackboard.js +249 -0
  178. package/dist/lib/shared-blackboard.js.map +1 -0
  179. package/dist/lib/speculative-executor.d.ts +89 -0
  180. package/dist/lib/speculative-executor.d.ts.map +1 -0
  181. package/dist/lib/speculative-executor.js +107 -0
  182. package/dist/lib/speculative-executor.js.map +1 -0
  183. package/dist/lib/swarm-transport.d.ts +150 -0
  184. package/dist/lib/swarm-transport.d.ts.map +1 -0
  185. package/dist/lib/swarm-transport.js +307 -0
  186. package/dist/lib/swarm-transport.js.map +1 -0
  187. package/dist/lib/task-decomposer.d.ts +41 -0
  188. package/dist/lib/task-decomposer.d.ts.map +1 -0
  189. package/dist/lib/task-decomposer.js +272 -0
  190. package/dist/lib/task-decomposer.js.map +1 -0
  191. package/dist/lib/timeline-scrubber.d.ts +84 -0
  192. package/dist/lib/timeline-scrubber.d.ts.map +1 -0
  193. package/dist/lib/timeline-scrubber.js +173 -0
  194. package/dist/lib/timeline-scrubber.js.map +1 -0
  195. package/dist/lib/topology.d.ts +361 -0
  196. package/dist/lib/topology.d.ts.map +1 -0
  197. package/dist/lib/topology.js +591 -0
  198. package/dist/lib/topology.js.map +1 -0
  199. package/dist/security.d.ts +95 -0
  200. package/dist/security.d.ts.map +1 -1
  201. package/dist/security.js +267 -5
  202. package/dist/security.js.map +1 -1
  203. package/package.json +7 -5
  204. package/types/agent-adapter.d.ts +5 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-inbox.d.ts","sourceRoot":"","sources":["../../lib/approval-inbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,385 @@
1
+ "use strict";
2
+ /**
3
+ * ApprovalInbox — Web-accessible human-in-the-loop approval system
4
+ *
5
+ * Provides an HTTP API and SSE streaming for managing approval requests
6
+ * from AI agents. Designed to work as an ApprovalCallback for ApprovalGate
7
+ * while also exposing a REST-like HTTP interface.
8
+ *
9
+ * Features:
10
+ * - Queues approval requests with unique IDs and optional timeouts
11
+ * - REST API: list, get, approve, deny, stats
12
+ * - SSE stream for real-time notifications
13
+ * - Auto-expiry for stale requests
14
+ * - Standalone HTTP server or mountable handler
15
+ *
16
+ * @module ApprovalInbox
17
+ * @version 1.0.0
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.ApprovalInbox = void 0;
21
+ const events_1 = require("events");
22
+ const http_1 = require("http");
23
+ const crypto_1 = require("crypto");
24
+ // ============================================================================
25
+ // APPROVAL INBOX
26
+ // ============================================================================
27
+ /**
28
+ * Web-accessible approval inbox for human-in-the-loop agent workflows.
29
+ *
30
+ * Use `inbox.callback()` to get an ApprovalCallback for ApprovalGate,
31
+ * and `inbox.httpHandler()` to mount the HTTP API on a server.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const inbox = new ApprovalInbox();
36
+ * const gate = new ApprovalGate(inbox.callback());
37
+ * const server = inbox.createServer(3002);
38
+ * ```
39
+ */
40
+ class ApprovalInbox extends events_1.EventEmitter {
41
+ pending = new Map();
42
+ history = [];
43
+ sseClients = new Set();
44
+ defaultTimeoutMs;
45
+ maxPending;
46
+ maxHistory;
47
+ pathPrefix;
48
+ // Counters for stats (history may be truncated)
49
+ approvedCount = 0;
50
+ deniedCount = 0;
51
+ expiredCount = 0;
52
+ constructor(options = {}) {
53
+ super();
54
+ this.defaultTimeoutMs = options.defaultTimeoutMs ?? 300_000;
55
+ this.maxPending = options.maxPending ?? 100;
56
+ this.maxHistory = options.maxHistory ?? 1000;
57
+ this.pathPrefix = (options.pathPrefix ?? '/approvals').replace(/\/$/, '');
58
+ }
59
+ // --------------------------------------------------------------------------
60
+ // CORE API
61
+ // --------------------------------------------------------------------------
62
+ /**
63
+ * Returns an ApprovalCallback suitable for ApprovalGate.
64
+ * Each call enqueues a pending approval and waits for resolution.
65
+ */
66
+ callback() {
67
+ return (request) => {
68
+ return this.enqueue(request);
69
+ };
70
+ }
71
+ /**
72
+ * Enqueue an approval request. Returns a promise that resolves when
73
+ * the request is approved, denied, or expires.
74
+ */
75
+ enqueue(request, timeoutMs) {
76
+ if (this.pending.size >= this.maxPending) {
77
+ return Promise.resolve({ approved: false, reason: 'Approval queue is full' });
78
+ }
79
+ const id = (0, crypto_1.randomBytes)(8).toString('hex');
80
+ const timeout = timeoutMs ?? this.defaultTimeoutMs;
81
+ const entry = {
82
+ id,
83
+ request,
84
+ status: 'pending',
85
+ createdAt: Date.now(),
86
+ timeoutMs: timeout,
87
+ };
88
+ return new Promise((resolve) => {
89
+ const timer = timeout > 0
90
+ ? setTimeout(() => this.expire(id), timeout)
91
+ : null;
92
+ this.pending.set(id, { entry, resolve, timer });
93
+ this.broadcastSSE({ type: 'new', entry });
94
+ this.emit('new', entry);
95
+ });
96
+ }
97
+ /**
98
+ * Approve a pending request.
99
+ * @returns The resolved entry, or undefined if not found/already resolved.
100
+ */
101
+ approve(id, approvedBy, reason) {
102
+ const record = this.pending.get(id);
103
+ if (!record)
104
+ return undefined;
105
+ const decision = {
106
+ approved: true,
107
+ approvedBy,
108
+ reason,
109
+ };
110
+ return this.resolve(id, 'approved', decision);
111
+ }
112
+ /**
113
+ * Deny a pending request.
114
+ * @returns The resolved entry, or undefined if not found/already resolved.
115
+ */
116
+ deny(id, deniedBy, reason) {
117
+ const record = this.pending.get(id);
118
+ if (!record)
119
+ return undefined;
120
+ const decision = {
121
+ approved: false,
122
+ approvedBy: deniedBy,
123
+ reason,
124
+ };
125
+ return this.resolve(id, 'denied', decision);
126
+ }
127
+ /** Get a single entry by ID (pending or historical) */
128
+ get(id) {
129
+ const record = this.pending.get(id);
130
+ if (record)
131
+ return { ...record.entry };
132
+ return this.history.find((e) => e.id === id);
133
+ }
134
+ /** List entries by status (default: 'pending') */
135
+ list(status = 'pending') {
136
+ if (status === 'pending' || status === 'all') {
137
+ const pendingEntries = Array.from(this.pending.values()).map((r) => ({ ...r.entry }));
138
+ if (status === 'pending')
139
+ return pendingEntries;
140
+ return [...pendingEntries, ...this.history];
141
+ }
142
+ return this.history.filter((e) => e.status === status);
143
+ }
144
+ /** Get aggregate stats */
145
+ stats() {
146
+ return {
147
+ pending: this.pending.size,
148
+ approved: this.approvedCount,
149
+ denied: this.deniedCount,
150
+ expired: this.expiredCount,
151
+ total: this.approvedCount + this.deniedCount + this.expiredCount + this.pending.size,
152
+ };
153
+ }
154
+ /** Number of pending approvals */
155
+ get pendingCount() {
156
+ return this.pending.size;
157
+ }
158
+ // --------------------------------------------------------------------------
159
+ // HTTP HANDLER
160
+ // --------------------------------------------------------------------------
161
+ /**
162
+ * Returns an HTTP request handler for the approval inbox API.
163
+ *
164
+ * Routes (relative to pathPrefix):
165
+ * GET / — List approvals (?status=pending|approved|denied|expired|all)
166
+ * GET /stats — Aggregate stats
167
+ * GET /sse — SSE event stream
168
+ * GET /:id — Get single entry
169
+ * POST /:id/approve — Approve (body: { approvedBy, reason? })
170
+ * POST /:id/deny — Deny (body: { deniedBy?, reason? })
171
+ */
172
+ httpHandler() {
173
+ return (req, res) => {
174
+ const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
175
+ const path = url.pathname;
176
+ // CORS headers
177
+ res.setHeader('Access-Control-Allow-Origin', '*');
178
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
179
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
180
+ if (req.method === 'OPTIONS') {
181
+ res.writeHead(204);
182
+ res.end();
183
+ return;
184
+ }
185
+ // Strip prefix
186
+ if (!path.startsWith(this.pathPrefix)) {
187
+ this.sendJson(res, 404, { error: 'Not found' });
188
+ return;
189
+ }
190
+ const subPath = path.slice(this.pathPrefix.length) || '/';
191
+ this.routeRequest(req, res, subPath, url);
192
+ };
193
+ }
194
+ /**
195
+ * Create a standalone HTTP server for the inbox.
196
+ * @returns The HTTP server instance (already listening).
197
+ */
198
+ startServer(port, hostname = '127.0.0.1') {
199
+ const handler = this.httpHandler();
200
+ const server = (0, http_1.createServer)(handler);
201
+ server.listen(port, hostname);
202
+ return server;
203
+ }
204
+ // --------------------------------------------------------------------------
205
+ // SSE
206
+ // --------------------------------------------------------------------------
207
+ /** Broadcast an event to all connected SSE clients */
208
+ broadcastSSE(event) {
209
+ const data = JSON.stringify(event);
210
+ const message = `event: ${event.type}\ndata: ${data}\n\n`;
211
+ for (const client of this.sseClients) {
212
+ try {
213
+ client.write(message);
214
+ }
215
+ catch {
216
+ this.sseClients.delete(client);
217
+ }
218
+ }
219
+ }
220
+ /** Register an SSE client */
221
+ addSSEClient(res) {
222
+ res.writeHead(200, {
223
+ 'Content-Type': 'text/event-stream',
224
+ 'Cache-Control': 'no-cache',
225
+ Connection: 'keep-alive',
226
+ 'Access-Control-Allow-Origin': '*',
227
+ });
228
+ res.write(`event: connected\ndata: ${JSON.stringify({ pending: this.pending.size })}\n\n`);
229
+ this.sseClients.add(res);
230
+ const onClose = () => {
231
+ this.sseClients.delete(res);
232
+ };
233
+ res.on('close', onClose);
234
+ res.on('error', onClose);
235
+ }
236
+ // --------------------------------------------------------------------------
237
+ // INTERNAL
238
+ // --------------------------------------------------------------------------
239
+ resolve(id, status, decision) {
240
+ const record = this.pending.get(id);
241
+ if (record.timer)
242
+ clearTimeout(record.timer);
243
+ record.entry.status = status;
244
+ record.entry.decision = decision;
245
+ record.entry.resolvedAt = Date.now();
246
+ this.pending.delete(id);
247
+ this.addToHistory(record.entry);
248
+ if (status === 'approved')
249
+ this.approvedCount++;
250
+ else if (status === 'denied')
251
+ this.deniedCount++;
252
+ else
253
+ this.expiredCount++;
254
+ const eventType = status;
255
+ this.broadcastSSE({ type: eventType, entry: record.entry });
256
+ this.emit(status, record.entry);
257
+ record.resolve(decision);
258
+ return { ...record.entry };
259
+ }
260
+ expire(id) {
261
+ const record = this.pending.get(id);
262
+ if (!record)
263
+ return;
264
+ const decision = {
265
+ approved: false,
266
+ reason: `Approval request expired after ${record.entry.timeoutMs}ms`,
267
+ };
268
+ this.resolve(id, 'expired', decision);
269
+ }
270
+ addToHistory(entry) {
271
+ this.history.push(entry);
272
+ if (this.history.length > this.maxHistory) {
273
+ this.history.splice(0, this.history.length - this.maxHistory);
274
+ }
275
+ }
276
+ routeRequest(req, res, subPath, url) {
277
+ // GET / — list
278
+ if (subPath === '/' && req.method === 'GET') {
279
+ const status = (url.searchParams.get('status') ?? 'pending');
280
+ this.sendJson(res, 200, this.list(status));
281
+ return;
282
+ }
283
+ // GET /stats
284
+ if (subPath === '/stats' && req.method === 'GET') {
285
+ this.sendJson(res, 200, this.stats());
286
+ return;
287
+ }
288
+ // GET /sse
289
+ if (subPath === '/sse' && req.method === 'GET') {
290
+ this.addSSEClient(res);
291
+ return;
292
+ }
293
+ // POST /:id/approve
294
+ const approveMatch = subPath.match(/^\/([a-f0-9]+)\/approve$/);
295
+ if (approveMatch && req.method === 'POST') {
296
+ this.readBody(req).then((body) => {
297
+ const approvedBy = typeof body.approvedBy === 'string' ? body.approvedBy : 'anonymous';
298
+ const reason = typeof body.reason === 'string' ? body.reason : undefined;
299
+ const entry = this.approve(approveMatch[1], approvedBy, reason);
300
+ if (!entry) {
301
+ this.sendJson(res, 404, { error: 'Approval not found or already resolved' });
302
+ }
303
+ else {
304
+ this.sendJson(res, 200, entry);
305
+ }
306
+ }).catch(() => {
307
+ this.sendJson(res, 400, { error: 'Invalid request body' });
308
+ });
309
+ return;
310
+ }
311
+ // POST /:id/deny
312
+ const denyMatch = subPath.match(/^\/([a-f0-9]+)\/deny$/);
313
+ if (denyMatch && req.method === 'POST') {
314
+ this.readBody(req).then((body) => {
315
+ const deniedBy = typeof body.deniedBy === 'string' ? body.deniedBy : undefined;
316
+ const reason = typeof body.reason === 'string' ? body.reason : undefined;
317
+ const entry = this.deny(denyMatch[1], deniedBy, reason);
318
+ if (!entry) {
319
+ this.sendJson(res, 404, { error: 'Approval not found or already resolved' });
320
+ }
321
+ else {
322
+ this.sendJson(res, 200, entry);
323
+ }
324
+ }).catch(() => {
325
+ this.sendJson(res, 400, { error: 'Invalid request body' });
326
+ });
327
+ return;
328
+ }
329
+ // GET /:id
330
+ const idMatch = subPath.match(/^\/([a-f0-9]+)$/);
331
+ if (idMatch && req.method === 'GET') {
332
+ const entry = this.get(idMatch[1]);
333
+ if (!entry) {
334
+ this.sendJson(res, 404, { error: 'Approval not found' });
335
+ }
336
+ else {
337
+ this.sendJson(res, 200, entry);
338
+ }
339
+ return;
340
+ }
341
+ this.sendJson(res, 404, { error: 'Not found' });
342
+ }
343
+ sendJson(res, status, data) {
344
+ const body = JSON.stringify(data);
345
+ res.writeHead(status, {
346
+ 'Content-Type': 'application/json',
347
+ 'Content-Length': Buffer.byteLength(body),
348
+ });
349
+ res.end(body);
350
+ }
351
+ readBody(req) {
352
+ return new Promise((resolve, reject) => {
353
+ const chunks = [];
354
+ let size = 0;
355
+ const maxSize = 16_384; // 16KB max
356
+ req.on('data', (chunk) => {
357
+ size += chunk.length;
358
+ if (size > maxSize) {
359
+ req.destroy();
360
+ reject(new Error('Request body too large'));
361
+ return;
362
+ }
363
+ chunks.push(chunk);
364
+ });
365
+ req.on('end', () => {
366
+ try {
367
+ const raw = Buffer.concat(chunks).toString('utf-8');
368
+ const parsed = raw.length > 0 ? JSON.parse(raw) : {};
369
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
370
+ reject(new Error('Body must be a JSON object'));
371
+ }
372
+ else {
373
+ resolve(parsed);
374
+ }
375
+ }
376
+ catch {
377
+ reject(new Error('Invalid JSON'));
378
+ }
379
+ });
380
+ req.on('error', reject);
381
+ });
382
+ }
383
+ }
384
+ exports.ApprovalInbox = ApprovalInbox;
385
+ //# sourceMappingURL=approval-inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-inbox.js","sourceRoot":"","sources":["../../lib/approval-inbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Universal permission wall for multi-agent systems.
3
+ *
4
+ * Evaluates permission requests using a weighted formula of justification
5
+ * quality (40%), agent trust level (30%), and risk score (30%).
6
+ * Resource types, risk profiles, trust levels, and restrictions are all
7
+ * configurable — works for coding, finance, DevOps, or any domain.
8
+ *
9
+ * @module AuthGuardian
10
+ */
11
+ import type { ActiveGrant, PermissionGrant, ResourceProfile, AgentTrustConfig } from './orchestrator-types';
12
+ /**
13
+ * Universal permission wall for multi-agent systems.
14
+ *
15
+ * Evaluates permission requests using a weighted formula of justification
16
+ * quality (40%), agent trust level (30%), and risk score (30%).
17
+ * Resource types, risk profiles, trust levels, and restrictions are all
18
+ * configurable — works for coding, finance, DevOps, or any domain.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const guardian = new AuthGuardian({
23
+ * trustLevels: [{ agentId: 'analyst', trustLevel: 0.8 }],
24
+ * resourceProfiles: { CUSTOM_API: { baseRisk: 0.5, defaultRestrictions: ['audit_required'] } },
25
+ * });
26
+ *
27
+ * const grant = await guardian.requestPermission(
28
+ * 'analyst', 'CUSTOM_API', 'Need to fetch Q4 revenue data for report', 'read'
29
+ * );
30
+ * if (grant.granted) {
31
+ * // Use grant.grantToken to prove authorization
32
+ * }
33
+ * ```
34
+ */
35
+ export declare class AuthGuardian {
36
+ private activeGrants;
37
+ private agentTrustLevels;
38
+ private agentTrustConfigs;
39
+ private resourceProfiles;
40
+ private auditLog;
41
+ private auditLogPath;
42
+ private trustConfigPath;
43
+ private readonly signingAlgorithm;
44
+ private readonly hmacSecret;
45
+ private readonly ed25519PrivateKey;
46
+ private readonly ed25519PublicKey;
47
+ constructor(options?: {
48
+ trustLevels?: AgentTrustConfig[];
49
+ resourceProfiles?: Record<string, ResourceProfile>;
50
+ auditLogPath?: string;
51
+ trustConfigPath?: string;
52
+ /** Signing algorithm for grant tokens. Default: 'hmac-sha256'. */
53
+ algorithm?: 'hmac-sha256' | 'ed25519';
54
+ /** HMAC secret (only used when algorithm is 'hmac-sha256'). Auto-generated if omitted. */
55
+ hmacSecret?: string;
56
+ });
57
+ /**
58
+ * Register a new resource type at runtime.
59
+ * Makes the system extensible for any domain.
60
+ */
61
+ registerResourceType(name: string, profile: ResourceProfile): void;
62
+ /**
63
+ * Register or update an agent's trust configuration at runtime.
64
+ */
65
+ registerAgentTrust(config: AgentTrustConfig): void;
66
+ /**
67
+ * Request permission to access a resource.
68
+ * resourceType is now a free string -- validated against registered profiles.
69
+ */
70
+ requestPermission(agentId: string, resourceType: string, justification: string, scope?: string): Promise<PermissionGrant>;
71
+ /**
72
+ * Validate a grant token and return `true` if it is active and not expired.
73
+ *
74
+ * @param token - The grant token to validate
75
+ * @returns `true` if the token is valid, `false` otherwise
76
+ */
77
+ validateToken(token: string): boolean;
78
+ /**
79
+ * Validate a token and return the full grant object (including restrictions
80
+ * and scope) for point-of-use enforcement.
81
+ *
82
+ * @param token - The grant token to validate
83
+ * @returns The grant details, or `null` if invalid/expired
84
+ */
85
+ validateTokenWithGrant(token: string): ActiveGrant | null;
86
+ /**
87
+ * Enforce restrictions on an operation. Returns an error string if
88
+ * the operation violates any restriction, or `null` if all restrictions pass.
89
+ *
90
+ * @param grantToken - The grant token authorizing the operation
91
+ * @param operation - Description of the operation to check against restrictions
92
+ * @returns Error message string if a restriction is violated, or `null` if allowed
93
+ */
94
+ enforceRestrictions(grantToken: string, operation: {
95
+ type?: string;
96
+ recordCount?: number;
97
+ hasAttachments?: boolean;
98
+ targetPath?: string;
99
+ command?: string;
100
+ }): string | null;
101
+ /**
102
+ * Revoke a grant token, immediately invalidating it.
103
+ * Silently no-ops if the token doesn't exist.
104
+ *
105
+ * @param token - The grant token to revoke
106
+ */
107
+ revokeToken(token: string): void;
108
+ private evaluateRequest;
109
+ /**
110
+ * Improved justification scoring with resource-relevance checking.
111
+ * Prevents trivial gaming by verifying the justification mentions
112
+ * concepts relevant to the requested resource.
113
+ */
114
+ private scoreJustification;
115
+ private assessRisk;
116
+ private generateGrantToken;
117
+ /**
118
+ * Verify a grant token's cryptographic signature.
119
+ * For Ed25519 tokens, this can be done by any party holding the public key.
120
+ * For HMAC tokens, only the issuing AuthGuardian can verify.
121
+ *
122
+ * @param token - The grant token to verify
123
+ * @returns `true` if the signature is valid
124
+ */
125
+ verifyTokenSignature(token: string): boolean;
126
+ /**
127
+ * Get the signing algorithm used by this AuthGuardian instance.
128
+ */
129
+ getSigningAlgorithm(): 'hmac-sha256' | 'ed25519';
130
+ /**
131
+ * Export the Ed25519 public key in PEM format for third-party verification.
132
+ * Returns `null` if the instance uses HMAC signing.
133
+ */
134
+ exportPublicKey(): string | null;
135
+ private log;
136
+ /**
137
+ * Get all active (non-expired) permission grants.
138
+ * Automatically cleans up expired grants before returning.
139
+ */
140
+ getActiveGrants(): ActiveGrant[];
141
+ /**
142
+ * Get the full audit log of permission decisions.
143
+ * Returns a defensive copy.
144
+ */
145
+ getAuditLog(): typeof this.auditLog;
146
+ /**
147
+ * Get all registered resource profiles.
148
+ */
149
+ getResourceProfiles(): Record<string, ResourceProfile>;
150
+ /**
151
+ * Get the allowed namespaces for an agent (used by blackboard scoping).
152
+ */
153
+ getAgentNamespaces(agentId: string): string[];
154
+ /** Path for the resource profiles policy file. */
155
+ private get resourceProfilesPath();
156
+ /**
157
+ * Load resource profiles from `data/resource-profiles.json` if it exists.
158
+ * Expected format: `{ "PROFILE_NAME": { baseRisk, defaultRestrictions, description? } }`
159
+ */
160
+ private loadResourceProfilesFromDisk;
161
+ /**
162
+ * Persist the current resource profiles to `data/resource-profiles.json`.
163
+ * Useful after calling registerResourceType() at runtime.
164
+ */
165
+ persistResourceProfiles(): void;
166
+ private loadTrustFromDisk;
167
+ private persistTrustToDisk;
168
+ private loadAuditFromDisk;
169
+ }
170
+ //# sourceMappingURL=auth-guardian.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-guardian.d.ts","sourceRoot":"","sources":["../../lib/auth-guardian.ts"],"names":[],"mappings":"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"}