network-ai 5.13.4 → 5.14.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/INTEGRATION_GUIDE.md +6 -3
- package/QUICKSTART.md +9 -4
- package/README.md +64 -14
- package/SKILL.md +1 -1
- package/bin/cli.ts +73 -0
- package/bin/mcp-server.ts +15 -1
- package/dist/adapters/claude-agent-sdk-adapter.d.ts +100 -0
- package/dist/adapters/claude-agent-sdk-adapter.d.ts.map +1 -0
- package/dist/adapters/claude-agent-sdk-adapter.js +204 -0
- package/dist/adapters/claude-agent-sdk-adapter.js.map +1 -0
- package/dist/adapters/gemini-adapter.d.ts +124 -0
- package/dist/adapters/gemini-adapter.d.ts.map +1 -0
- package/dist/adapters/gemini-adapter.js +239 -0
- package/dist/adapters/gemini-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +10 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/openai-responses-adapter.d.ts +119 -0
- package/dist/adapters/openai-responses-adapter.d.ts.map +1 -0
- package/dist/adapters/openai-responses-adapter.js +235 -0
- package/dist/adapters/openai-responses-adapter.js.map +1 -0
- package/dist/bin/cli.js +72 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/mcp-server.js +14 -1
- package/dist/bin/mcp-server.js.map +1 -1
- package/dist/esm/adapters/claude-agent-sdk-adapter.js +204 -0
- package/dist/esm/adapters/claude-agent-sdk-adapter.js.map +1 -0
- package/dist/esm/adapters/gemini-adapter.js +239 -0
- package/dist/esm/adapters/gemini-adapter.js.map +1 -0
- package/dist/esm/adapters/index.js +10 -1
- package/dist/esm/adapters/index.js.map +1 -1
- package/dist/esm/adapters/openai-responses-adapter.js +235 -0
- package/dist/esm/adapters/openai-responses-adapter.js.map +1 -0
- package/dist/esm/index.js +13 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/a2a-server.js +293 -0
- package/dist/esm/lib/a2a-server.js.map +1 -0
- package/dist/esm/lib/claude-hooks.js +307 -0
- package/dist/esm/lib/claude-hooks.js.map +1 -0
- package/dist/esm/lib/mcp-elicitation.js +198 -0
- package/dist/esm/lib/mcp-elicitation.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/a2a-server.d.ts +120 -0
- package/dist/lib/a2a-server.d.ts.map +1 -0
- package/dist/lib/a2a-server.js +293 -0
- package/dist/lib/a2a-server.js.map +1 -0
- package/dist/lib/claude-hooks.d.ts +150 -0
- package/dist/lib/claude-hooks.d.ts.map +1 -0
- package/dist/lib/claude-hooks.js +307 -0
- package/dist/lib/claude-hooks.js.map +1 -0
- package/dist/lib/mcp-elicitation.d.ts +116 -0
- package/dist/lib/mcp-elicitation.d.ts.map +1 -0
- package/dist/lib/mcp-elicitation.js +198 -0
- package/dist/lib/mcp-elicitation.js.map +1 -0
- package/package.json +2 -2
- package/scripts/clawhub-publish.js +14 -1
- package/socket.json +1 -1
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A2A Server — expose Network-AI as a Google A2A (Agent2Agent) agent.
|
|
4
|
+
*
|
|
5
|
+
* The `A2AAdapter` (adapters/a2a-adapter.ts) lets this orchestrator *call*
|
|
6
|
+
* remote A2A agents. This module is the other direction: `A2AServer` serves
|
|
7
|
+
* an Agent Card at `/.well-known/agent.json` and accepts `tasks/send`
|
|
8
|
+
* JSON-RPC envelopes, so any A2A-speaking framework (Google ADK, Gemini
|
|
9
|
+
* agents, LangGraph A2A clients, …) can discover this orchestrator and hand
|
|
10
|
+
* it tasks.
|
|
11
|
+
*
|
|
12
|
+
* Incoming task text is delegated to a pluggable executor — typically a
|
|
13
|
+
* closure over `AdapterRegistry.executeAgent()` or
|
|
14
|
+
* `SwarmOrchestrator.delegateTask()`.
|
|
15
|
+
*
|
|
16
|
+
* Security posture mirrors `ApprovalInbox`:
|
|
17
|
+
* - binds to 127.0.0.1 by default;
|
|
18
|
+
* - optional Bearer `secret` gates the task routes (the Agent Card remains
|
|
19
|
+
* public — it is the A2A discovery document);
|
|
20
|
+
* - request bodies are size-capped; unknown methods are rejected.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const server = new A2AServer({
|
|
25
|
+
* name: 'Network-AI Orchestrator',
|
|
26
|
+
* description: 'Multi-agent swarm coordinator',
|
|
27
|
+
* secret: process.env.A2A_SECRET,
|
|
28
|
+
* executor: async (text) => {
|
|
29
|
+
* const result = await registry.executeAgent('custom:solver', {
|
|
30
|
+
* action: 'solve', params: { text },
|
|
31
|
+
* }, { agentId: 'a2a-server', taskId: 'a2a' });
|
|
32
|
+
* return { text: JSON.stringify(result.data) };
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* server.startServer(4310);
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @module A2AServer
|
|
39
|
+
* @version 1.0.0
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.A2AServer = void 0;
|
|
43
|
+
const http_1 = require("http");
|
|
44
|
+
const crypto_1 = require("crypto");
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// A2A SERVER
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Minimal, dependency-free A2A protocol server: Agent Card discovery plus
|
|
50
|
+
* `tasks/send`, `tasks/get`, and `tasks/cancel` over JSON-RPC 2.0.
|
|
51
|
+
*/
|
|
52
|
+
class A2AServer {
|
|
53
|
+
options;
|
|
54
|
+
tasks = new Map();
|
|
55
|
+
constructor(options) {
|
|
56
|
+
if (!options || typeof options.name !== 'string' || options.name.trim() === '') {
|
|
57
|
+
throw new Error('A2AServer: options.name is required');
|
|
58
|
+
}
|
|
59
|
+
if (typeof options.executor !== 'function') {
|
|
60
|
+
throw new Error('A2AServer: options.executor is required');
|
|
61
|
+
}
|
|
62
|
+
this.options = {
|
|
63
|
+
...options,
|
|
64
|
+
version: options.version ?? '1.0.0',
|
|
65
|
+
maxHistory: options.maxHistory ?? 1000,
|
|
66
|
+
maxBodyBytes: options.maxBodyBytes ?? 1024 * 1024,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Build the Agent Card served at /.well-known/agent.json */
|
|
70
|
+
agentCard() {
|
|
71
|
+
return {
|
|
72
|
+
name: this.options.name,
|
|
73
|
+
description: this.options.description ?? 'Network-AI multi-agent orchestrator (A2A server mode)',
|
|
74
|
+
version: this.options.version,
|
|
75
|
+
capabilities: {
|
|
76
|
+
streaming: false,
|
|
77
|
+
pushNotifications: false,
|
|
78
|
+
stateTransitionHistory: false,
|
|
79
|
+
},
|
|
80
|
+
...(this.options.url ? { url: this.options.url, taskEndpoint: `${this.options.url.replace(/\/+$/, '')}/tasks` } : { taskEndpoint: '/tasks' }),
|
|
81
|
+
authentication: this.options.secret ? { schemes: ['bearer'] } : { schemes: [] },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** Get a stored task by id */
|
|
85
|
+
getTask(id) {
|
|
86
|
+
return this.tasks.get(id);
|
|
87
|
+
}
|
|
88
|
+
/** Number of stored task records */
|
|
89
|
+
get taskCount() {
|
|
90
|
+
return this.tasks.size;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* HTTP handler — mount on any node http server.
|
|
94
|
+
* Routes: GET /.well-known/agent.json, POST /tasks.
|
|
95
|
+
*/
|
|
96
|
+
httpHandler() {
|
|
97
|
+
return (req, res) => {
|
|
98
|
+
void this.route(req, res);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Convenience: create and start an http.Server with the handler mounted.
|
|
103
|
+
* Binds to 127.0.0.1 by default — expose deliberately, not accidentally.
|
|
104
|
+
*/
|
|
105
|
+
startServer(port, hostname = '127.0.0.1') {
|
|
106
|
+
const server = (0, http_1.createServer)(this.httpHandler());
|
|
107
|
+
server.listen(port, hostname);
|
|
108
|
+
return server;
|
|
109
|
+
}
|
|
110
|
+
// --------------------------------------------------------------------------
|
|
111
|
+
// Routing
|
|
112
|
+
// --------------------------------------------------------------------------
|
|
113
|
+
async route(req, res) {
|
|
114
|
+
const url = (req.url ?? '/').split('?')[0];
|
|
115
|
+
// Agent Card — public discovery document
|
|
116
|
+
if (req.method === 'GET' && url === '/.well-known/agent.json') {
|
|
117
|
+
this.json(res, 200, this.agentCard());
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (req.method === 'POST' && (url === '/tasks' || url === '/')) {
|
|
121
|
+
// Auth gate (fail closed when a secret is configured)
|
|
122
|
+
if (this.options.secret) {
|
|
123
|
+
const header = req.headers['authorization'] ?? '';
|
|
124
|
+
const ok = typeof header === 'string' && header === `Bearer ${this.options.secret}`;
|
|
125
|
+
if (!ok) {
|
|
126
|
+
this.json(res, 401, { error: 'unauthorized' });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
let body;
|
|
131
|
+
try {
|
|
132
|
+
body = await this.readBody(req);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
this.json(res, 413, { error: err instanceof Error ? err.message : 'body too large' });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
let rpc;
|
|
139
|
+
try {
|
|
140
|
+
rpc = JSON.parse(body);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
this.rpcError(res, null, -32700, 'Parse error');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const rpcId = rpc.id ?? null;
|
|
147
|
+
switch (rpc.method) {
|
|
148
|
+
case 'tasks/send':
|
|
149
|
+
await this.handleSend(res, rpcId, rpc);
|
|
150
|
+
return;
|
|
151
|
+
case 'tasks/get':
|
|
152
|
+
this.handleGet(res, rpcId, rpc);
|
|
153
|
+
return;
|
|
154
|
+
case 'tasks/cancel':
|
|
155
|
+
this.handleCancel(res, rpcId, rpc);
|
|
156
|
+
return;
|
|
157
|
+
default:
|
|
158
|
+
this.rpcError(res, rpcId, -32601, `Method not found: ${rpc.method ?? '(none)'}`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
this.json(res, 404, { error: 'not found' });
|
|
163
|
+
}
|
|
164
|
+
// --------------------------------------------------------------------------
|
|
165
|
+
// JSON-RPC methods
|
|
166
|
+
// --------------------------------------------------------------------------
|
|
167
|
+
async handleSend(res, rpcId, rpc) {
|
|
168
|
+
const params = rpc.params;
|
|
169
|
+
const parts = params?.message?.parts ?? [];
|
|
170
|
+
const text = parts
|
|
171
|
+
.filter((p) => p.type === 'text' && typeof p.text === 'string')
|
|
172
|
+
.map((p) => p.text)
|
|
173
|
+
.join('\n');
|
|
174
|
+
if (!text) {
|
|
175
|
+
this.rpcError(res, rpcId, -32602, 'Invalid params: message must contain at least one text part');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const taskId = params?.id && typeof params.id === 'string' ? params.id : (0, crypto_1.randomUUID)();
|
|
179
|
+
const task = {
|
|
180
|
+
id: taskId,
|
|
181
|
+
state: 'working',
|
|
182
|
+
input: text.slice(0, 10_000),
|
|
183
|
+
createdAt: Date.now(),
|
|
184
|
+
};
|
|
185
|
+
this.store(task);
|
|
186
|
+
try {
|
|
187
|
+
const result = await this.options.executor(text, params?.metadata);
|
|
188
|
+
task.state = 'completed';
|
|
189
|
+
task.output = result.text ?? (result.data !== undefined ? JSON.stringify(result.data) : '');
|
|
190
|
+
task.resolvedAt = Date.now();
|
|
191
|
+
this.json(res, 200, {
|
|
192
|
+
jsonrpc: '2.0',
|
|
193
|
+
id: rpcId,
|
|
194
|
+
result: {
|
|
195
|
+
id: taskId,
|
|
196
|
+
status: { state: 'completed' },
|
|
197
|
+
artifacts: [{
|
|
198
|
+
name: 'result',
|
|
199
|
+
parts: [{ type: 'text', text: task.output }],
|
|
200
|
+
}],
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
task.state = 'failed';
|
|
206
|
+
task.message = err instanceof Error ? err.message : String(err);
|
|
207
|
+
task.resolvedAt = Date.now();
|
|
208
|
+
this.json(res, 200, {
|
|
209
|
+
jsonrpc: '2.0',
|
|
210
|
+
id: rpcId,
|
|
211
|
+
result: {
|
|
212
|
+
id: taskId,
|
|
213
|
+
status: { state: 'failed', message: task.message },
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
handleGet(res, rpcId, rpc) {
|
|
219
|
+
const id = rpc.params?.id;
|
|
220
|
+
const task = id ? this.tasks.get(id) : undefined;
|
|
221
|
+
if (!task) {
|
|
222
|
+
this.rpcError(res, rpcId, -32001, `Task not found: ${id ?? '(none)'}`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
this.json(res, 200, {
|
|
226
|
+
jsonrpc: '2.0',
|
|
227
|
+
id: rpcId,
|
|
228
|
+
result: {
|
|
229
|
+
id: task.id,
|
|
230
|
+
status: { state: task.state, ...(task.message ? { message: task.message } : {}) },
|
|
231
|
+
...(task.output !== undefined
|
|
232
|
+
? { artifacts: [{ name: 'result', parts: [{ type: 'text', text: task.output }] }] }
|
|
233
|
+
: {}),
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
handleCancel(res, rpcId, rpc) {
|
|
238
|
+
const id = rpc.params?.id;
|
|
239
|
+
const task = id ? this.tasks.get(id) : undefined;
|
|
240
|
+
if (!task) {
|
|
241
|
+
this.rpcError(res, rpcId, -32001, `Task not found: ${id ?? '(none)'}`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (task.state === 'submitted' || task.state === 'working') {
|
|
245
|
+
task.state = 'canceled';
|
|
246
|
+
task.resolvedAt = Date.now();
|
|
247
|
+
}
|
|
248
|
+
this.json(res, 200, {
|
|
249
|
+
jsonrpc: '2.0',
|
|
250
|
+
id: rpcId,
|
|
251
|
+
result: { id: task.id, status: { state: task.state } },
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// --------------------------------------------------------------------------
|
|
255
|
+
// Helpers
|
|
256
|
+
// --------------------------------------------------------------------------
|
|
257
|
+
store(task) {
|
|
258
|
+
this.tasks.set(task.id, task);
|
|
259
|
+
if (this.tasks.size > this.options.maxHistory) {
|
|
260
|
+
const oldest = this.tasks.keys().next().value;
|
|
261
|
+
if (oldest !== undefined)
|
|
262
|
+
this.tasks.delete(oldest);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
readBody(req) {
|
|
266
|
+
return new Promise((resolve, reject) => {
|
|
267
|
+
let size = 0;
|
|
268
|
+
const chunks = [];
|
|
269
|
+
req.on('data', (chunk) => {
|
|
270
|
+
size += chunk.length;
|
|
271
|
+
if (size > this.options.maxBodyBytes) {
|
|
272
|
+
reject(new Error(`request body exceeds ${this.options.maxBodyBytes} bytes`));
|
|
273
|
+
req.destroy();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
chunks.push(chunk);
|
|
277
|
+
});
|
|
278
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
279
|
+
req.on('error', reject);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
json(res, status, payload) {
|
|
283
|
+
if (res.writableEnded)
|
|
284
|
+
return;
|
|
285
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
286
|
+
res.end(JSON.stringify(payload));
|
|
287
|
+
}
|
|
288
|
+
rpcError(res, id, code, message) {
|
|
289
|
+
this.json(res, 200, { jsonrpc: '2.0', id, error: { code, message } });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
exports.A2AServer = A2AServer;
|
|
293
|
+
//# sourceMappingURL=a2a-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-server.js","sourceRoot":"","sources":["../../../lib/a2a-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code Hooks Bridge — AuthGuardian-gated tool calls for coding agents.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code (and other hook-capable agent CLIs) can call an external
|
|
6
|
+
* command on every tool use (PreToolUse / PostToolUse hooks). This module
|
|
7
|
+
* turns Network-AI into that command: every tool call an agent makes is
|
|
8
|
+
* audited — and optionally permission-gated — through the same
|
|
9
|
+
* `AuthGuardian` weighted scoring used for swarm agents (justification 40%,
|
|
10
|
+
* trust 30%, risk 30%).
|
|
11
|
+
*
|
|
12
|
+
* Two modes:
|
|
13
|
+
* - `'observe'` (default) — every tool call is audit-logged, nothing is
|
|
14
|
+
* blocked. Zero-risk visibility into what the agent is doing.
|
|
15
|
+
* - `'enforce'` — tool calls are mapped to Network-AI resource types
|
|
16
|
+
* (Bash → SHELL_EXEC, Write/Edit → FILE_SYSTEM, WebFetch →
|
|
17
|
+
* EXTERNAL_SERVICE, …) and must pass `AuthGuardian.requestPermission()`.
|
|
18
|
+
* Denied calls return `'ask'` (escalate to the human) or `'deny'`.
|
|
19
|
+
*
|
|
20
|
+
* Wire-up (Claude Code `settings.json`):
|
|
21
|
+
* ```json
|
|
22
|
+
* {
|
|
23
|
+
* "hooks": {
|
|
24
|
+
* "PreToolUse": [{
|
|
25
|
+
* "matcher": "Bash|Write|Edit|WebFetch",
|
|
26
|
+
* "hooks": [{ "type": "command",
|
|
27
|
+
* "command": "npx -y -p network-ai network-ai hook pre-tool-use --mode enforce" }]
|
|
28
|
+
* }]
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
* See `examples/claude-code-hooks.json` for a complete config.
|
|
33
|
+
*
|
|
34
|
+
* @module ClaudeHooks
|
|
35
|
+
* @version 1.0.0
|
|
36
|
+
*/
|
|
37
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
38
|
+
if (k2 === undefined) k2 = k;
|
|
39
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
40
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
41
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
42
|
+
}
|
|
43
|
+
Object.defineProperty(o, k2, desc);
|
|
44
|
+
}) : (function(o, m, k, k2) {
|
|
45
|
+
if (k2 === undefined) k2 = k;
|
|
46
|
+
o[k2] = m[k];
|
|
47
|
+
}));
|
|
48
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
49
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
50
|
+
}) : function(o, v) {
|
|
51
|
+
o["default"] = v;
|
|
52
|
+
});
|
|
53
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
54
|
+
var ownKeys = function(o) {
|
|
55
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
56
|
+
var ar = [];
|
|
57
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
58
|
+
return ar;
|
|
59
|
+
};
|
|
60
|
+
return ownKeys(o);
|
|
61
|
+
};
|
|
62
|
+
return function (mod) {
|
|
63
|
+
if (mod && mod.__esModule) return mod;
|
|
64
|
+
var result = {};
|
|
65
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
66
|
+
__setModuleDefault(result, mod);
|
|
67
|
+
return result;
|
|
68
|
+
};
|
|
69
|
+
})();
|
|
70
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
|
+
exports.ClaudeHookBridge = exports.DEFAULT_TOOL_RESOURCE_MAP = void 0;
|
|
72
|
+
const fs = __importStar(require("fs"));
|
|
73
|
+
const path = __importStar(require("path"));
|
|
74
|
+
const auth_guardian_1 = require("./auth-guardian");
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// DEFAULTS
|
|
77
|
+
// ============================================================================
|
|
78
|
+
/**
|
|
79
|
+
* Default mapping from Claude Code tool names to Network-AI resource types.
|
|
80
|
+
* MCP tools (`mcp__*`) and unknown tools map to EXTERNAL_SERVICE.
|
|
81
|
+
*/
|
|
82
|
+
exports.DEFAULT_TOOL_RESOURCE_MAP = {
|
|
83
|
+
Bash: 'SHELL_EXEC',
|
|
84
|
+
BashOutput: 'SHELL_EXEC',
|
|
85
|
+
KillShell: 'SHELL_EXEC',
|
|
86
|
+
Write: 'FILE_SYSTEM',
|
|
87
|
+
Edit: 'FILE_SYSTEM',
|
|
88
|
+
MultiEdit: 'FILE_SYSTEM',
|
|
89
|
+
NotebookEdit: 'FILE_SYSTEM',
|
|
90
|
+
Read: 'FILE_SYSTEM',
|
|
91
|
+
Glob: 'FILE_SYSTEM',
|
|
92
|
+
Grep: 'FILE_SYSTEM',
|
|
93
|
+
WebFetch: 'EXTERNAL_SERVICE',
|
|
94
|
+
WebSearch: 'EXTERNAL_SERVICE',
|
|
95
|
+
Task: 'EXTERNAL_SERVICE',
|
|
96
|
+
};
|
|
97
|
+
/** Justification templates per resource type — phrased to carry the
|
|
98
|
+
* resource-relevant context AuthGuardian's scorer checks for. */
|
|
99
|
+
const JUSTIFICATION_TEMPLATES = {
|
|
100
|
+
SHELL_EXEC: (tool, target) => `Execute shell command via ${tool} in order to complete the current coding task: ${target}`,
|
|
101
|
+
FILE_SYSTEM: (tool, target) => `Access workspace file via ${tool} in order to complete the current coding task: ${target}`,
|
|
102
|
+
GIT: (tool, target) => `Perform git repository operation via ${tool} in order to complete the current coding task: ${target}`,
|
|
103
|
+
EXTERNAL_SERVICE: (tool, target) => `Fetch external api endpoint via ${tool} in order to complete the current coding task: ${target}`,
|
|
104
|
+
};
|
|
105
|
+
// ============================================================================
|
|
106
|
+
// HELPERS
|
|
107
|
+
// ============================================================================
|
|
108
|
+
/** Extract the most meaningful target string from a tool input */
|
|
109
|
+
function extractTarget(toolName, toolInput) {
|
|
110
|
+
if (!toolInput)
|
|
111
|
+
return toolName;
|
|
112
|
+
const candidates = ['command', 'file_path', 'filePath', 'path', 'url', 'query', 'pattern', 'prompt'];
|
|
113
|
+
for (const key of candidates) {
|
|
114
|
+
const v = toolInput[key];
|
|
115
|
+
if (typeof v === 'string' && v.length > 0)
|
|
116
|
+
return v.slice(0, 500);
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
return JSON.stringify(toolInput).slice(0, 300);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return toolName;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** Test a tool name / target against a pattern list */
|
|
126
|
+
function matchesAny(patterns, toolName, target) {
|
|
127
|
+
if (!patterns || patterns.length === 0)
|
|
128
|
+
return false;
|
|
129
|
+
for (const p of patterns) {
|
|
130
|
+
const re = typeof p === 'string' ? new RegExp(p, 'i') : p;
|
|
131
|
+
if (re.test(toolName) || re.test(target))
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
// ============================================================================
|
|
137
|
+
// CLAUDE HOOK BRIDGE
|
|
138
|
+
// ============================================================================
|
|
139
|
+
/**
|
|
140
|
+
* Bridges coding-agent hook events (Claude Code PreToolUse / PostToolUse)
|
|
141
|
+
* into Network-AI's AuthGuardian permission system and audit trail.
|
|
142
|
+
*/
|
|
143
|
+
class ClaudeHookBridge {
|
|
144
|
+
guardian;
|
|
145
|
+
agentId;
|
|
146
|
+
mode;
|
|
147
|
+
denyPatterns;
|
|
148
|
+
allowPatterns;
|
|
149
|
+
toolResourceMap;
|
|
150
|
+
blockedDecision;
|
|
151
|
+
auditLogPath;
|
|
152
|
+
onAudit;
|
|
153
|
+
constructor(options = {}) {
|
|
154
|
+
this.agentId = options.agentId ?? 'claude-code';
|
|
155
|
+
this.mode = options.mode ?? 'observe';
|
|
156
|
+
this.denyPatterns = options.denyPatterns ?? [];
|
|
157
|
+
this.allowPatterns = options.allowPatterns ?? [];
|
|
158
|
+
this.toolResourceMap = { ...exports.DEFAULT_TOOL_RESOURCE_MAP, ...(options.toolResourceMap ?? {}) };
|
|
159
|
+
this.blockedDecision = options.blockedDecision ?? 'ask';
|
|
160
|
+
this.auditLogPath = options.auditLogPath ? path.resolve(options.auditLogPath) : null;
|
|
161
|
+
this.onAudit = options.onAudit ?? null;
|
|
162
|
+
if (options.guardian) {
|
|
163
|
+
this.guardian = options.guardian;
|
|
164
|
+
}
|
|
165
|
+
else if (this.mode === 'enforce') {
|
|
166
|
+
// Auto-create a guardian with a trust identity for this agent.
|
|
167
|
+
this.guardian = new auth_guardian_1.AuthGuardian({
|
|
168
|
+
trustLevels: [{
|
|
169
|
+
agentId: this.agentId,
|
|
170
|
+
trustLevel: options.trustLevel ?? 0.7,
|
|
171
|
+
allowedNamespaces: ['*'],
|
|
172
|
+
allowedResources: ['*'],
|
|
173
|
+
}],
|
|
174
|
+
...(options.guardianAuditLogPath ? { auditLogPath: options.guardianAuditLogPath } : {}),
|
|
175
|
+
...(options.trustConfigPath ? { trustConfigPath: options.trustConfigPath } : {}),
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.guardian = null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Parse a raw hook stdin payload. Tolerates a leading UTF-8 BOM (some
|
|
184
|
+
* shells prepend one when piping). Throws on malformed JSON or a payload
|
|
185
|
+
* that is not an object.
|
|
186
|
+
*/
|
|
187
|
+
static parseInput(raw) {
|
|
188
|
+
let parsed;
|
|
189
|
+
try {
|
|
190
|
+
parsed = JSON.parse(raw.replace(/^\uFEFF/, '').trim());
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
194
|
+
throw new Error(`ClaudeHookBridge: invalid hook input JSON — ${detail}`);
|
|
195
|
+
}
|
|
196
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
197
|
+
throw new Error('ClaudeHookBridge: hook input must be a JSON object');
|
|
198
|
+
}
|
|
199
|
+
const obj = parsed;
|
|
200
|
+
if (typeof obj['hook_event_name'] !== 'string') {
|
|
201
|
+
throw new Error('ClaudeHookBridge: hook input missing hook_event_name');
|
|
202
|
+
}
|
|
203
|
+
return obj;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Handle a PreToolUse event: decide allow / deny / ask.
|
|
207
|
+
*
|
|
208
|
+
* Decision order: denyPatterns → allowPatterns → observe-mode allow →
|
|
209
|
+
* AuthGuardian permission request (enforce mode).
|
|
210
|
+
*/
|
|
211
|
+
async handlePreToolUse(input) {
|
|
212
|
+
const toolName = input.tool_name ?? 'unknown';
|
|
213
|
+
const target = extractTarget(toolName, input.tool_input);
|
|
214
|
+
// 1. Hard deny list
|
|
215
|
+
if (matchesAny(this.denyPatterns, toolName, target)) {
|
|
216
|
+
return this.decide(input, toolName, target, 'deny', `Blocked by Network-AI deny pattern (tool: ${toolName})`);
|
|
217
|
+
}
|
|
218
|
+
// 2. Explicit allow list
|
|
219
|
+
if (matchesAny(this.allowPatterns, toolName, target)) {
|
|
220
|
+
return this.decide(input, toolName, target, 'allow', `Allowed by Network-AI allow pattern (tool: ${toolName})`);
|
|
221
|
+
}
|
|
222
|
+
// 3. Observe mode: audit, never block
|
|
223
|
+
if (this.mode === 'observe' || !this.guardian) {
|
|
224
|
+
return this.decide(input, toolName, target, 'allow', 'Network-AI observe mode — call audited, not gated');
|
|
225
|
+
}
|
|
226
|
+
// 4. Enforce mode: AuthGuardian weighted permission scoring
|
|
227
|
+
const resourceType = this.toolResourceMap[toolName]
|
|
228
|
+
?? (toolName.startsWith('mcp__') ? 'EXTERNAL_SERVICE' : 'EXTERNAL_SERVICE');
|
|
229
|
+
const template = JUSTIFICATION_TEMPLATES[resourceType] ?? JUSTIFICATION_TEMPLATES['EXTERNAL_SERVICE'];
|
|
230
|
+
const justification = template(toolName, target);
|
|
231
|
+
const grant = await this.guardian.requestPermission(this.agentId, resourceType, justification, toolName);
|
|
232
|
+
if (grant.granted) {
|
|
233
|
+
return this.decide(input, toolName, target, 'allow', `AuthGuardian granted ${resourceType} (restrictions: ${grant.restrictions.join(', ') || 'none'})`);
|
|
234
|
+
}
|
|
235
|
+
return this.decide(input, toolName, target, this.blockedDecision, `AuthGuardian denied ${resourceType}: ${grant.reason ?? 'permission not granted'}`);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Handle a PostToolUse event: audit the completed call. Never blocks.
|
|
239
|
+
* Returns an empty object (the hook-protocol no-op).
|
|
240
|
+
*/
|
|
241
|
+
async handlePostToolUse(input) {
|
|
242
|
+
const toolName = input.tool_name ?? 'unknown';
|
|
243
|
+
const target = extractTarget(toolName, input.tool_input);
|
|
244
|
+
this.audit({
|
|
245
|
+
timestamp: new Date().toISOString(),
|
|
246
|
+
event: 'PostToolUse',
|
|
247
|
+
toolName,
|
|
248
|
+
target,
|
|
249
|
+
sessionId: input.session_id,
|
|
250
|
+
agentId: this.agentId,
|
|
251
|
+
mode: this.mode,
|
|
252
|
+
});
|
|
253
|
+
return {};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Dispatch a hook input by its `hook_event_name`.
|
|
257
|
+
*/
|
|
258
|
+
async handle(input) {
|
|
259
|
+
if (input.hook_event_name === 'PreToolUse')
|
|
260
|
+
return this.handlePreToolUse(input);
|
|
261
|
+
if (input.hook_event_name === 'PostToolUse')
|
|
262
|
+
return this.handlePostToolUse(input);
|
|
263
|
+
throw new Error(`ClaudeHookBridge: unsupported hook event "${input.hook_event_name}"`);
|
|
264
|
+
}
|
|
265
|
+
// --------------------------------------------------------------------------
|
|
266
|
+
// Internals
|
|
267
|
+
// --------------------------------------------------------------------------
|
|
268
|
+
decide(input, toolName, target, decision, reason) {
|
|
269
|
+
this.audit({
|
|
270
|
+
timestamp: new Date().toISOString(),
|
|
271
|
+
event: 'PreToolUse',
|
|
272
|
+
toolName,
|
|
273
|
+
target,
|
|
274
|
+
decision,
|
|
275
|
+
reason,
|
|
276
|
+
sessionId: input.session_id,
|
|
277
|
+
agentId: this.agentId,
|
|
278
|
+
mode: this.mode,
|
|
279
|
+
});
|
|
280
|
+
return {
|
|
281
|
+
hookSpecificOutput: {
|
|
282
|
+
hookEventName: 'PreToolUse',
|
|
283
|
+
permissionDecision: decision,
|
|
284
|
+
permissionDecisionReason: reason,
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
audit(entry) {
|
|
289
|
+
try {
|
|
290
|
+
this.onAudit?.(entry);
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
/* observer errors must never break the hook */
|
|
294
|
+
}
|
|
295
|
+
if (this.auditLogPath) {
|
|
296
|
+
try {
|
|
297
|
+
fs.mkdirSync(path.dirname(this.auditLogPath), { recursive: true });
|
|
298
|
+
fs.appendFileSync(this.auditLogPath, JSON.stringify(entry) + '\n', 'utf8');
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
/* audit-write failures must never break the hook */
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
exports.ClaudeHookBridge = ClaudeHookBridge;
|
|
307
|
+
//# sourceMappingURL=claude-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-hooks.js","sourceRoot":"","sources":["../../../lib/claude-hooks.ts"],"names":[],"mappings":"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"}
|