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.
Files changed (61) hide show
  1. package/INTEGRATION_GUIDE.md +6 -3
  2. package/QUICKSTART.md +9 -4
  3. package/README.md +64 -14
  4. package/SKILL.md +1 -1
  5. package/bin/cli.ts +73 -0
  6. package/bin/mcp-server.ts +15 -1
  7. package/dist/adapters/claude-agent-sdk-adapter.d.ts +100 -0
  8. package/dist/adapters/claude-agent-sdk-adapter.d.ts.map +1 -0
  9. package/dist/adapters/claude-agent-sdk-adapter.js +204 -0
  10. package/dist/adapters/claude-agent-sdk-adapter.js.map +1 -0
  11. package/dist/adapters/gemini-adapter.d.ts +124 -0
  12. package/dist/adapters/gemini-adapter.d.ts.map +1 -0
  13. package/dist/adapters/gemini-adapter.js +239 -0
  14. package/dist/adapters/gemini-adapter.js.map +1 -0
  15. package/dist/adapters/index.d.ts +6 -0
  16. package/dist/adapters/index.d.ts.map +1 -1
  17. package/dist/adapters/index.js +10 -1
  18. package/dist/adapters/index.js.map +1 -1
  19. package/dist/adapters/openai-responses-adapter.d.ts +119 -0
  20. package/dist/adapters/openai-responses-adapter.d.ts.map +1 -0
  21. package/dist/adapters/openai-responses-adapter.js +235 -0
  22. package/dist/adapters/openai-responses-adapter.js.map +1 -0
  23. package/dist/bin/cli.js +72 -0
  24. package/dist/bin/cli.js.map +1 -1
  25. package/dist/bin/mcp-server.js +14 -1
  26. package/dist/bin/mcp-server.js.map +1 -1
  27. package/dist/esm/adapters/claude-agent-sdk-adapter.js +204 -0
  28. package/dist/esm/adapters/claude-agent-sdk-adapter.js.map +1 -0
  29. package/dist/esm/adapters/gemini-adapter.js +239 -0
  30. package/dist/esm/adapters/gemini-adapter.js.map +1 -0
  31. package/dist/esm/adapters/index.js +10 -1
  32. package/dist/esm/adapters/index.js.map +1 -1
  33. package/dist/esm/adapters/openai-responses-adapter.js +235 -0
  34. package/dist/esm/adapters/openai-responses-adapter.js.map +1 -0
  35. package/dist/esm/index.js +13 -5
  36. package/dist/esm/index.js.map +1 -1
  37. package/dist/esm/lib/a2a-server.js +293 -0
  38. package/dist/esm/lib/a2a-server.js.map +1 -0
  39. package/dist/esm/lib/claude-hooks.js +307 -0
  40. package/dist/esm/lib/claude-hooks.js.map +1 -0
  41. package/dist/esm/lib/mcp-elicitation.js +198 -0
  42. package/dist/esm/lib/mcp-elicitation.js.map +1 -0
  43. package/dist/index.d.ts +6 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +13 -5
  46. package/dist/index.js.map +1 -1
  47. package/dist/lib/a2a-server.d.ts +120 -0
  48. package/dist/lib/a2a-server.d.ts.map +1 -0
  49. package/dist/lib/a2a-server.js +293 -0
  50. package/dist/lib/a2a-server.js.map +1 -0
  51. package/dist/lib/claude-hooks.d.ts +150 -0
  52. package/dist/lib/claude-hooks.d.ts.map +1 -0
  53. package/dist/lib/claude-hooks.js +307 -0
  54. package/dist/lib/claude-hooks.js.map +1 -0
  55. package/dist/lib/mcp-elicitation.d.ts +116 -0
  56. package/dist/lib/mcp-elicitation.d.ts.map +1 -0
  57. package/dist/lib/mcp-elicitation.js +198 -0
  58. package/dist/lib/mcp-elicitation.js.map +1 -0
  59. package/package.json +2 -2
  60. package/scripts/clawhub-publish.js +14 -1
  61. package/socket.json +1 -1
@@ -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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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * MCP Elicitation — native in-client approval prompts.
3
+ *
4
+ * Implements the MCP elicitation capability (spec revision 2025-06-18):
5
+ * the server sends an `elicitation/create` JSON-RPC request *to the client*,
6
+ * the client renders it natively (Claude Code, Codex, Gemini CLI, Cursor…),
7
+ * and the user's answer comes back as the response.
8
+ *
9
+ * Network-AI uses this to surface `ApprovalGate` / `ApprovalInbox` decisions
10
+ * directly inside the MCP client instead of a separate HTTP inbox: wrap a
11
+ * request sender with {@link createElicitationApprovalCallback} and pass the
12
+ * resulting callback to `ApprovalGate`.
13
+ *
14
+ * Transport plumbing for stdio servers is provided by
15
+ * {@link StdioElicitationChannel}: it assigns request ids, writes
16
+ * newline-delimited JSON-RPC to the client, and resolves pending promises
17
+ * when responses arrive.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const channel = new StdioElicitationChannel((line) => process.stdout.write(line + '\n'));
22
+ * // in the stdin loop: if (channel.handleMessage(parsed)) return; // consumed a response
23
+ * const approvalCallback = createElicitationApprovalCallback(
24
+ * (params) => channel.request('elicitation/create', params),
25
+ * );
26
+ * const gate = new ApprovalGate(approvalCallback);
27
+ * ```
28
+ *
29
+ * @module McpElicitation
30
+ * @version 1.0.0
31
+ */
32
+ import type { ApprovalRequest, ApprovalDecision } from './agent-runtime';
33
+ /** Flat-primitive schema property allowed by MCP elicitation */
34
+ export interface ElicitationSchemaProperty {
35
+ type: 'string' | 'number' | 'integer' | 'boolean';
36
+ title?: string;
37
+ description?: string;
38
+ enum?: string[];
39
+ default?: string | number | boolean;
40
+ }
41
+ /** The restricted object schema MCP elicitation requests may carry */
42
+ export interface ElicitationRequestedSchema {
43
+ type: 'object';
44
+ properties: Record<string, ElicitationSchemaProperty>;
45
+ required?: string[];
46
+ }
47
+ /** Params for an `elicitation/create` request */
48
+ export interface ElicitationCreateParams {
49
+ /** Human-readable message presented to the user */
50
+ message: string;
51
+ /** Schema describing the structured content requested from the user */
52
+ requestedSchema: ElicitationRequestedSchema;
53
+ }
54
+ /** Result of an `elicitation/create` request */
55
+ export interface ElicitationResult {
56
+ /** 'accept' (user submitted), 'decline' (explicit no), 'cancel' (dismissed) */
57
+ action: 'accept' | 'decline' | 'cancel';
58
+ /** The user's structured answer — present only when action is 'accept' */
59
+ content?: Record<string, unknown>;
60
+ }
61
+ /**
62
+ * Sends an elicitation request to the connected client and resolves its
63
+ * result. Implementations own the transport (stdio, streamable HTTP, …).
64
+ */
65
+ export type ElicitationRequestSender = (params: ElicitationCreateParams) => Promise<ElicitationResult>;
66
+ /** Options for {@link createElicitationApprovalCallback} */
67
+ export interface ElicitationApprovalOptions {
68
+ /** Identity recorded on decisions approved via elicitation (default: 'mcp-client') */
69
+ approvedBy?: string;
70
+ /** Overall timeout for the elicitation round-trip in ms (default: 300000 = 5 min) */
71
+ timeoutMs?: number;
72
+ }
73
+ /**
74
+ * Build an `ApprovalCallback` (as used by `ApprovalGate` / `AgentRuntime`)
75
+ * that resolves approvals by asking the connected MCP client through
76
+ * elicitation. Fail-closed: timeouts, transport errors, declines, and
77
+ * cancellations all resolve to `approved: false`.
78
+ */
79
+ export declare function createElicitationApprovalCallback(send: ElicitationRequestSender, options?: ElicitationApprovalOptions): (request: ApprovalRequest) => Promise<ApprovalDecision>;
80
+ /**
81
+ * Server→client request channel for newline-delimited JSON-RPC transports
82
+ * (stdio). Assigns unique ids to outgoing requests and resolves the pending
83
+ * promise when the matching response arrives.
84
+ *
85
+ * Integration contract for the stdin loop: for every parsed inbound message,
86
+ * call {@link handleMessage} first — if it returns `true` the message was a
87
+ * response to a server-initiated request and must not be dispatched as a
88
+ * client request.
89
+ */
90
+ export declare class StdioElicitationChannel {
91
+ private readonly write;
92
+ private readonly pending;
93
+ private nextId;
94
+ private readonly defaultTimeoutMs;
95
+ /**
96
+ * @param write Writes one serialized JSON-RPC line to the client.
97
+ * @param defaultTimeoutMs Per-request timeout (default: 300000 = 5 min).
98
+ */
99
+ constructor(write: (line: string) => void, defaultTimeoutMs?: number);
100
+ /** Number of requests currently awaiting a client response */
101
+ get pendingCount(): number;
102
+ /**
103
+ * Send a server→client request and resolve its result.
104
+ * Rejects on timeout, client error response, or malformed result.
105
+ */
106
+ request(method: string, params: ElicitationCreateParams, timeoutMs?: number): Promise<ElicitationResult>;
107
+ /**
108
+ * Route an inbound message. Returns `true` when the message was a response
109
+ * to a pending server-initiated request (and was consumed); `false` when it
110
+ * is a client request the caller should dispatch normally.
111
+ */
112
+ handleMessage(message: unknown): boolean;
113
+ /** Reject every pending request (e.g. on shutdown or client disconnect). */
114
+ rejectAll(reason?: string): void;
115
+ }
116
+ //# sourceMappingURL=mcp-elicitation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-elicitation.d.ts","sourceRoot":"","sources":["../../lib/mcp-elicitation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMzE,gEAAgE;AAChE,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACrC;AAED,sEAAsE;AACtE,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,eAAe,EAAE,0BAA0B,CAAC;CAC7C;AAED,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvG,4DAA4D;AAC5D,MAAM,WAAW,0BAA0B;IACzC,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,wBAAwB,EAC9B,OAAO,GAAE,0BAA+B,GACvC,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,gBAAgB,CAAC,CA2DzD;AAgBD;;;;;;;;;GASG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAInB;IACL,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C;;;OAGG;gBACS,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,gBAAgB,SAAU;IAKrE,8DAA8D;IAC9D,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwBxG;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IA8BxC,4EAA4E;IAC5E,SAAS,CAAC,MAAM,SAAmB,GAAG,IAAI;CAO3C"}
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Elicitation — native in-client approval prompts.
4
+ *
5
+ * Implements the MCP elicitation capability (spec revision 2025-06-18):
6
+ * the server sends an `elicitation/create` JSON-RPC request *to the client*,
7
+ * the client renders it natively (Claude Code, Codex, Gemini CLI, Cursor…),
8
+ * and the user's answer comes back as the response.
9
+ *
10
+ * Network-AI uses this to surface `ApprovalGate` / `ApprovalInbox` decisions
11
+ * directly inside the MCP client instead of a separate HTTP inbox: wrap a
12
+ * request sender with {@link createElicitationApprovalCallback} and pass the
13
+ * resulting callback to `ApprovalGate`.
14
+ *
15
+ * Transport plumbing for stdio servers is provided by
16
+ * {@link StdioElicitationChannel}: it assigns request ids, writes
17
+ * newline-delimited JSON-RPC to the client, and resolves pending promises
18
+ * when responses arrive.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const channel = new StdioElicitationChannel((line) => process.stdout.write(line + '\n'));
23
+ * // in the stdin loop: if (channel.handleMessage(parsed)) return; // consumed a response
24
+ * const approvalCallback = createElicitationApprovalCallback(
25
+ * (params) => channel.request('elicitation/create', params),
26
+ * );
27
+ * const gate = new ApprovalGate(approvalCallback);
28
+ * ```
29
+ *
30
+ * @module McpElicitation
31
+ * @version 1.0.0
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.StdioElicitationChannel = void 0;
35
+ exports.createElicitationApprovalCallback = createElicitationApprovalCallback;
36
+ // ============================================================================
37
+ // APPROVAL CALLBACK FACTORY
38
+ // ============================================================================
39
+ /**
40
+ * Build an `ApprovalCallback` (as used by `ApprovalGate` / `AgentRuntime`)
41
+ * that resolves approvals by asking the connected MCP client through
42
+ * elicitation. Fail-closed: timeouts, transport errors, declines, and
43
+ * cancellations all resolve to `approved: false`.
44
+ */
45
+ function createElicitationApprovalCallback(send, options = {}) {
46
+ const approvedBy = options.approvedBy ?? 'mcp-client';
47
+ const timeoutMs = options.timeoutMs ?? 300_000;
48
+ return async (request) => {
49
+ const params = {
50
+ message: `Approval required — agent "${request.agentId}" requests ${request.type} ` +
51
+ `on "${request.target}" (risk: ${request.risk})` +
52
+ (request.justification ? `\nJustification: ${request.justification}` : ''),
53
+ requestedSchema: {
54
+ type: 'object',
55
+ properties: {
56
+ approve: {
57
+ type: 'boolean',
58
+ title: 'Approve this action?',
59
+ description: `Allow ${request.type} on ${request.target}`,
60
+ },
61
+ reason: {
62
+ type: 'string',
63
+ title: 'Reason (optional)',
64
+ description: 'Why you approved or denied this action',
65
+ },
66
+ },
67
+ required: ['approve'],
68
+ },
69
+ };
70
+ let timer = null;
71
+ try {
72
+ const result = await Promise.race([
73
+ send(params),
74
+ new Promise((_, reject) => {
75
+ timer = setTimeout(() => reject(new Error(`elicitation timed out after ${timeoutMs}ms`)), timeoutMs);
76
+ }),
77
+ ]);
78
+ if (result.action === 'accept' && result.content?.['approve'] === true) {
79
+ const reason = typeof result.content['reason'] === 'string'
80
+ ? result.content['reason']
81
+ : undefined;
82
+ return { approved: true, approvedBy, ...(reason ? { reason } : {}) };
83
+ }
84
+ const why = result.action === 'accept'
85
+ ? 'user answered no'
86
+ : `user ${result.action === 'decline' ? 'declined' : 'cancelled'} the prompt`;
87
+ return { approved: false, reason: `Denied via MCP elicitation — ${why}` };
88
+ }
89
+ catch (err) {
90
+ const message = err instanceof Error ? err.message : String(err);
91
+ // Fail closed: any transport failure is a denial, never an approval.
92
+ return { approved: false, reason: `Elicitation failed — ${message}` };
93
+ }
94
+ finally {
95
+ if (timer)
96
+ clearTimeout(timer);
97
+ }
98
+ };
99
+ }
100
+ /**
101
+ * Server→client request channel for newline-delimited JSON-RPC transports
102
+ * (stdio). Assigns unique ids to outgoing requests and resolves the pending
103
+ * promise when the matching response arrives.
104
+ *
105
+ * Integration contract for the stdin loop: for every parsed inbound message,
106
+ * call {@link handleMessage} first — if it returns `true` the message was a
107
+ * response to a server-initiated request and must not be dispatched as a
108
+ * client request.
109
+ */
110
+ class StdioElicitationChannel {
111
+ write;
112
+ pending = new Map();
113
+ nextId = 1_000_000; // high offset avoids collisions with client request ids
114
+ defaultTimeoutMs;
115
+ /**
116
+ * @param write Writes one serialized JSON-RPC line to the client.
117
+ * @param defaultTimeoutMs Per-request timeout (default: 300000 = 5 min).
118
+ */
119
+ constructor(write, defaultTimeoutMs = 300_000) {
120
+ this.write = write;
121
+ this.defaultTimeoutMs = defaultTimeoutMs;
122
+ }
123
+ /** Number of requests currently awaiting a client response */
124
+ get pendingCount() {
125
+ return this.pending.size;
126
+ }
127
+ /**
128
+ * Send a server→client request and resolve its result.
129
+ * Rejects on timeout, client error response, or malformed result.
130
+ */
131
+ request(method, params, timeoutMs) {
132
+ const id = this.nextId++;
133
+ const line = JSON.stringify({ jsonrpc: '2.0', id, method, params });
134
+ return new Promise((resolve, reject) => {
135
+ const effective = timeoutMs ?? this.defaultTimeoutMs;
136
+ const timer = effective > 0
137
+ ? setTimeout(() => {
138
+ this.pending.delete(id);
139
+ reject(new Error(`request ${id} (${method}) timed out after ${effective}ms`));
140
+ }, effective)
141
+ : null;
142
+ this.pending.set(id, { resolve, reject, timer });
143
+ try {
144
+ this.write(line);
145
+ }
146
+ catch (err) {
147
+ if (timer)
148
+ clearTimeout(timer);
149
+ this.pending.delete(id);
150
+ reject(err instanceof Error ? err : new Error(String(err)));
151
+ }
152
+ });
153
+ }
154
+ /**
155
+ * Route an inbound message. Returns `true` when the message was a response
156
+ * to a pending server-initiated request (and was consumed); `false` when it
157
+ * is a client request the caller should dispatch normally.
158
+ */
159
+ handleMessage(message) {
160
+ if (message === null || typeof message !== 'object')
161
+ return false;
162
+ const msg = message;
163
+ // Requests (and notifications) carry a method — not ours to consume.
164
+ if (typeof msg.method === 'string')
165
+ return false;
166
+ if (msg.id === null || msg.id === undefined)
167
+ return false;
168
+ const id = typeof msg.id === 'number' ? msg.id : Number(msg.id);
169
+ const entry = this.pending.get(id);
170
+ if (!entry)
171
+ return false;
172
+ this.pending.delete(id);
173
+ if (entry.timer)
174
+ clearTimeout(entry.timer);
175
+ if (msg.error) {
176
+ entry.reject(new Error(`client error ${msg.error.code}: ${msg.error.message}`));
177
+ return true;
178
+ }
179
+ const result = msg.result;
180
+ if (!result || (result.action !== 'accept' && result.action !== 'decline' && result.action !== 'cancel')) {
181
+ entry.reject(new Error('malformed elicitation result from client'));
182
+ return true;
183
+ }
184
+ entry.resolve(result);
185
+ return true;
186
+ }
187
+ /** Reject every pending request (e.g. on shutdown or client disconnect). */
188
+ rejectAll(reason = 'channel closed') {
189
+ for (const [id, entry] of this.pending) {
190
+ if (entry.timer)
191
+ clearTimeout(entry.timer);
192
+ entry.reject(new Error(`request ${id} aborted — ${reason}`));
193
+ }
194
+ this.pending.clear();
195
+ }
196
+ }
197
+ exports.StdioElicitationChannel = StdioElicitationChannel;
198
+ //# sourceMappingURL=mcp-elicitation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-elicitation.js","sourceRoot":"","sources":["../../lib/mcp-elicitation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "network-ai",
3
- "version": "5.13.4",
4
- "description": "AI agent orchestration framework for TypeScript/Node.js - 29 adapters (LangChain, AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw, A2A, Codex, MiniMax, NemoClaw, APS, Copilot, LangGraph, Anthropic Computer Use, OpenAI Agents SDK, Vertex AI, Pydantic AI, Browser Agent, Hermes, Orchestrator, RLM + streaming variants). Built-in CLI, security, swarm intelligence, real-time streaming, and agentic workflow patterns.",
3
+ "version": "5.14.0",
4
+ "description": "AI agent orchestration framework for TypeScript/Node.js - 32 adapters (LangChain, AutoGen, CrewAI, OpenAI Assistants, OpenAI Responses, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw, A2A, Codex, MiniMax, NemoClaw, APS, Copilot, LangGraph, Anthropic Computer Use, Claude Agent SDK, OpenAI Agents SDK, Vertex AI, Gemini, Pydantic AI, Browser Agent, Hermes, Orchestrator, RLM + streaming variants). Built-in CLI, security, swarm intelligence, real-time streaming, and agentic workflow patterns.",
5
5
  "homepage": "https://network-ai.org",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/esm/index.js",