@vinkius-core/mcp-fusion 2.7.0 → 2.8.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/dist/cli/fusion.d.ts +101 -0
- package/dist/cli/fusion.d.ts.map +1 -0
- package/dist/cli/fusion.js +333 -0
- package/dist/cli/fusion.js.map +1 -0
- package/dist/index.d.ts +41 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/introspection/BehaviorDigest.d.ts +112 -0
- package/dist/introspection/BehaviorDigest.d.ts.map +1 -0
- package/dist/introspection/BehaviorDigest.js +146 -0
- package/dist/introspection/BehaviorDigest.js.map +1 -0
- package/dist/introspection/CapabilityLockfile.d.ts +259 -0
- package/dist/introspection/CapabilityLockfile.d.ts.map +1 -0
- package/dist/introspection/CapabilityLockfile.js +391 -0
- package/dist/introspection/CapabilityLockfile.js.map +1 -0
- package/dist/introspection/ContractAwareSelfHealing.d.ts +90 -0
- package/dist/introspection/ContractAwareSelfHealing.d.ts.map +1 -0
- package/dist/introspection/ContractAwareSelfHealing.js +132 -0
- package/dist/introspection/ContractAwareSelfHealing.js.map +1 -0
- package/dist/introspection/ContractDiff.d.ts +91 -0
- package/dist/introspection/ContractDiff.d.ts.map +1 -0
- package/dist/introspection/ContractDiff.js +466 -0
- package/dist/introspection/ContractDiff.js.map +1 -0
- package/dist/introspection/CryptoAttestation.d.ts +143 -0
- package/dist/introspection/CryptoAttestation.d.ts.map +1 -0
- package/dist/introspection/CryptoAttestation.js +194 -0
- package/dist/introspection/CryptoAttestation.js.map +1 -0
- package/dist/introspection/EntitlementScanner.d.ts +124 -0
- package/dist/introspection/EntitlementScanner.d.ts.map +1 -0
- package/dist/introspection/EntitlementScanner.js +244 -0
- package/dist/introspection/EntitlementScanner.js.map +1 -0
- package/dist/introspection/GovernanceObserver.d.ts +88 -0
- package/dist/introspection/GovernanceObserver.d.ts.map +1 -0
- package/dist/introspection/GovernanceObserver.js +132 -0
- package/dist/introspection/GovernanceObserver.js.map +1 -0
- package/dist/introspection/SemanticProbe.d.ts +207 -0
- package/dist/introspection/SemanticProbe.d.ts.map +1 -0
- package/dist/introspection/SemanticProbe.js +255 -0
- package/dist/introspection/SemanticProbe.js.map +1 -0
- package/dist/introspection/TokenEconomics.d.ts +210 -0
- package/dist/introspection/TokenEconomics.d.ts.map +1 -0
- package/dist/introspection/TokenEconomics.js +286 -0
- package/dist/introspection/TokenEconomics.js.map +1 -0
- package/dist/introspection/ToolContract.d.ts +159 -0
- package/dist/introspection/ToolContract.d.ts.map +1 -0
- package/dist/introspection/ToolContract.js +191 -0
- package/dist/introspection/ToolContract.js.map +1 -0
- package/dist/introspection/canonicalize.d.ts +20 -0
- package/dist/introspection/canonicalize.d.ts.map +1 -0
- package/dist/introspection/canonicalize.js +51 -0
- package/dist/introspection/canonicalize.js.map +1 -0
- package/dist/introspection/index.d.ts +20 -0
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js +20 -0
- package/dist/introspection/index.js.map +1 -1
- package/dist/observability/DebugObserver.d.ts +26 -1
- package/dist/observability/DebugObserver.d.ts.map +1 -1
- package/dist/observability/DebugObserver.js +8 -1
- package/dist/observability/DebugObserver.js.map +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js.map +1 -1
- package/dist/server/ServerAttachment.d.ts +41 -0
- package/dist/server/ServerAttachment.d.ts.map +1 -1
- package/dist/server/ServerAttachment.js +25 -1
- package/dist/server/ServerAttachment.js.map +1 -1
- package/package.json +8 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entitlement detection patterns.
|
|
3
|
+
*
|
|
4
|
+
* Conservative: may over-report (false positives in comments/strings)
|
|
5
|
+
* but never under-report. This is intentional — security analysis
|
|
6
|
+
* should err on the side of caution.
|
|
7
|
+
*/
|
|
8
|
+
const PATTERNS = [
|
|
9
|
+
// ── Filesystem ──
|
|
10
|
+
{ category: 'filesystem', identifier: 'fs', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?fs(?:\/promises)?['"]/g },
|
|
11
|
+
{ category: 'filesystem', identifier: 'fs.*', regex: /\bfs\.\w+(?:Sync)?\s*\(/g },
|
|
12
|
+
{ category: 'filesystem', identifier: 'readFile', regex: /\breadFile(?:Sync)?\s*\(/g },
|
|
13
|
+
{ category: 'filesystem', identifier: 'writeFile', regex: /\bwriteFile(?:Sync)?\s*\(/g },
|
|
14
|
+
{ category: 'filesystem', identifier: 'appendFile', regex: /\bappendFile(?:Sync)?\s*\(/g },
|
|
15
|
+
{ category: 'filesystem', identifier: 'unlink', regex: /\bunlink(?:Sync)?\s*\(/g },
|
|
16
|
+
{ category: 'filesystem', identifier: 'rmdir', regex: /\brmdir(?:Sync)?\s*\(/g },
|
|
17
|
+
{ category: 'filesystem', identifier: 'mkdir', regex: /\bmkdir(?:Sync)?\s*\(/g },
|
|
18
|
+
{ category: 'filesystem', identifier: 'rename', regex: /\brename(?:Sync)?\s*\(/g },
|
|
19
|
+
{ category: 'filesystem', identifier: 'copyFile', regex: /\bcopyFile(?:Sync)?\s*\(/g },
|
|
20
|
+
{ category: 'filesystem', identifier: 'createReadStream', regex: /\bcreateReadStream\s*\(/g },
|
|
21
|
+
{ category: 'filesystem', identifier: 'createWriteStream', regex: /\bcreateWriteStream\s*\(/g },
|
|
22
|
+
// ── Network ──
|
|
23
|
+
{ category: 'network', identifier: 'fetch', regex: /\bfetch\s*\(/g },
|
|
24
|
+
{ category: 'network', identifier: 'http', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?https?['"]/g },
|
|
25
|
+
{ category: 'network', identifier: 'axios', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])axios['"]/g },
|
|
26
|
+
{ category: 'network', identifier: 'got', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])got['"]/g },
|
|
27
|
+
{ category: 'network', identifier: 'node-fetch', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])node-fetch['"]/g },
|
|
28
|
+
{ category: 'network', identifier: 'XMLHttpRequest', regex: /\bnew\s+XMLHttpRequest\s*\(/g },
|
|
29
|
+
{ category: 'network', identifier: 'WebSocket', regex: /\bnew\s+WebSocket\s*\(/g },
|
|
30
|
+
{ category: 'network', identifier: 'net', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?net['"]/g },
|
|
31
|
+
{ category: 'network', identifier: 'dgram', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?dgram['"]/g },
|
|
32
|
+
{ category: 'network', identifier: 'undici', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])undici['"]/g },
|
|
33
|
+
// ── Subprocess ──
|
|
34
|
+
{ category: 'subprocess', identifier: 'child_process', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?child_process['"]/g },
|
|
35
|
+
{ category: 'subprocess', identifier: 'exec', regex: /\bexec(?:Sync|File|FileSync)?\s*\(/g },
|
|
36
|
+
{ category: 'subprocess', identifier: 'spawn', regex: /\bspawn(?:Sync)?\s*\(/g },
|
|
37
|
+
{ category: 'subprocess', identifier: 'fork', regex: /\bfork\s*\(/g },
|
|
38
|
+
{ category: 'subprocess', identifier: 'worker_threads', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?worker_threads['"]/g },
|
|
39
|
+
{ category: 'subprocess', identifier: 'cluster', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?cluster['"]/g },
|
|
40
|
+
{ category: 'subprocess', identifier: 'Deno.run', regex: /\bDeno\.run\s*\(/g },
|
|
41
|
+
{ category: 'subprocess', identifier: 'Bun.spawn', regex: /\bBun\.spawn\s*\(/g },
|
|
42
|
+
// ── Crypto ──
|
|
43
|
+
{ category: 'crypto', identifier: 'crypto', regex: /(?:require\s*\(\s*['"]|import\s*\(\s*['"]|from\s+['"])(?:node:)?crypto['"]/g },
|
|
44
|
+
{ category: 'crypto', identifier: 'createSign', regex: /\bcreateSign\s*\(/g },
|
|
45
|
+
{ category: 'crypto', identifier: 'createVerify', regex: /\bcreateVerify\s*\(/g },
|
|
46
|
+
{ category: 'crypto', identifier: 'createCipher', regex: /\bcreateCipher(?:iv)?\s*\(/g },
|
|
47
|
+
{ category: 'crypto', identifier: 'createDecipher', regex: /\bcreateDecipher(?:iv)?\s*\(/g },
|
|
48
|
+
{ category: 'crypto', identifier: 'privateEncrypt', regex: /\bprivateEncrypt\s*\(/g },
|
|
49
|
+
{ category: 'crypto', identifier: 'privateDecrypt', regex: /\bprivateDecrypt\s*\(/g },
|
|
50
|
+
];
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Scanner
|
|
53
|
+
// ============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Scan source text for entitlement patterns.
|
|
56
|
+
*
|
|
57
|
+
* @param source - The source code text to scan
|
|
58
|
+
* @param fileName - File name for reporting (optional)
|
|
59
|
+
* @returns All entitlement matches found
|
|
60
|
+
*/
|
|
61
|
+
export function scanSource(source, fileName) {
|
|
62
|
+
const matches = [];
|
|
63
|
+
const lines = source.split('\n');
|
|
64
|
+
const lineOffsets = buildLineOffsets(source);
|
|
65
|
+
for (const pattern of PATTERNS) {
|
|
66
|
+
// Reset regex state (global flag)
|
|
67
|
+
const regex = new RegExp(pattern.regex.source, pattern.regex.flags);
|
|
68
|
+
let match;
|
|
69
|
+
while ((match = regex.exec(source)) !== null) {
|
|
70
|
+
const lineNumber = resolveLineNumber(lineOffsets, match.index);
|
|
71
|
+
const contextLine = lines[lineNumber - 1]?.trim() ?? '';
|
|
72
|
+
matches.push({
|
|
73
|
+
category: pattern.category,
|
|
74
|
+
identifier: pattern.identifier,
|
|
75
|
+
pattern: pattern.regex.source,
|
|
76
|
+
context: contextLine,
|
|
77
|
+
line: lineNumber,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return matches;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build `HandlerEntitlements` from detected matches.
|
|
85
|
+
*
|
|
86
|
+
* @param matches - Detected entitlement matches
|
|
87
|
+
* @returns Aggregated entitlements
|
|
88
|
+
*/
|
|
89
|
+
export function buildEntitlements(matches) {
|
|
90
|
+
const categories = new Set(matches.map(m => m.category));
|
|
91
|
+
const raw = [...new Set(matches.map(m => m.identifier))].sort();
|
|
92
|
+
return {
|
|
93
|
+
filesystem: categories.has('filesystem'),
|
|
94
|
+
network: categories.has('network'),
|
|
95
|
+
subprocess: categories.has('subprocess'),
|
|
96
|
+
crypto: categories.has('crypto'),
|
|
97
|
+
raw,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Filesystem identifiers that imply write operations */
|
|
101
|
+
const WRITE_OPS = /write|append|unlink|rmdir|mkdir|rename|copy|createWriteStream/i;
|
|
102
|
+
/** All entitlement categories for iteration */
|
|
103
|
+
const ALL_CATEGORIES = ['filesystem', 'network', 'subprocess', 'crypto'];
|
|
104
|
+
/** @internal */
|
|
105
|
+
const VIOLATION_RULES = [
|
|
106
|
+
// readOnly + filesystem writes → error
|
|
107
|
+
{
|
|
108
|
+
predicate: (cats, claims, allowed, matches) => !!claims.readOnly
|
|
109
|
+
&& cats.has('filesystem')
|
|
110
|
+
&& !allowed.has('filesystem')
|
|
111
|
+
&& matches.some(m => m.category === 'filesystem' && WRITE_OPS.test(m.identifier)),
|
|
112
|
+
produce: (_cats, _claims, matches) => {
|
|
113
|
+
const writeOps = matches.filter(m => m.category === 'filesystem' && WRITE_OPS.test(m.identifier));
|
|
114
|
+
const ids = writeOps.map(m => m.identifier).join(', ');
|
|
115
|
+
return {
|
|
116
|
+
category: 'filesystem',
|
|
117
|
+
declared: 'readOnly: true',
|
|
118
|
+
detected: `Filesystem write operations: ${ids}`,
|
|
119
|
+
severity: 'error',
|
|
120
|
+
description: `Tool declares readOnly but handler uses filesystem write APIs: ${ids}`,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
// readOnly + subprocess → error
|
|
125
|
+
{
|
|
126
|
+
predicate: (cats, claims, allowed) => !!claims.readOnly && cats.has('subprocess') && !allowed.has('subprocess'),
|
|
127
|
+
produce: () => ({
|
|
128
|
+
category: 'subprocess',
|
|
129
|
+
declared: 'readOnly: true',
|
|
130
|
+
detected: 'Subprocess APIs detected',
|
|
131
|
+
severity: 'error',
|
|
132
|
+
description: 'Tool declares readOnly but handler uses subprocess APIs',
|
|
133
|
+
}),
|
|
134
|
+
},
|
|
135
|
+
// non-destructive + subprocess → warning
|
|
136
|
+
{
|
|
137
|
+
predicate: (cats, claims, allowed) => !claims.destructive && cats.has('subprocess') && !allowed.has('subprocess'),
|
|
138
|
+
produce: () => ({
|
|
139
|
+
category: 'subprocess',
|
|
140
|
+
declared: 'destructive: false',
|
|
141
|
+
detected: 'Subprocess APIs detected',
|
|
142
|
+
severity: 'warning',
|
|
143
|
+
description: 'Tool is not marked destructive but handler uses subprocess APIs — consider marking as destructive',
|
|
144
|
+
}),
|
|
145
|
+
},
|
|
146
|
+
// readOnly + network → warning
|
|
147
|
+
{
|
|
148
|
+
predicate: (cats, claims, allowed) => !!claims.readOnly && cats.has('network') && !allowed.has('network'),
|
|
149
|
+
produce: () => ({
|
|
150
|
+
category: 'network',
|
|
151
|
+
declared: 'readOnly: true',
|
|
152
|
+
detected: 'Network APIs detected',
|
|
153
|
+
severity: 'warning',
|
|
154
|
+
description: 'Tool declares readOnly but handler makes network calls — side effects possible',
|
|
155
|
+
}),
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
/**
|
|
159
|
+
* Validate detected entitlements against declared claims.
|
|
160
|
+
*
|
|
161
|
+
* Uses a rule table instead of imperative branching.
|
|
162
|
+
* Each rule encodes a policy check as pure data.
|
|
163
|
+
*
|
|
164
|
+
* @param matches - Detected matches
|
|
165
|
+
* @param claims - Declared claims from action metadata
|
|
166
|
+
* @returns Violations found
|
|
167
|
+
*/
|
|
168
|
+
export function validateClaims(matches, claims) {
|
|
169
|
+
const categories = new Set(matches.map(m => m.category));
|
|
170
|
+
const allowed = new Set(claims.allowed ?? []);
|
|
171
|
+
return VIOLATION_RULES
|
|
172
|
+
.filter(rule => rule.predicate(categories, claims, allowed, matches))
|
|
173
|
+
.map(rule => rule.produce(categories, claims, matches));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Perform a complete entitlement scan and validation.
|
|
177
|
+
*
|
|
178
|
+
* @param source - Handler source code
|
|
179
|
+
* @param claims - Declared claims for validation
|
|
180
|
+
* @param fileName - Optional file name for reporting
|
|
181
|
+
* @returns Complete entitlement report
|
|
182
|
+
*/
|
|
183
|
+
export function scanAndValidate(source, claims = {}, fileName) {
|
|
184
|
+
const matches = scanSource(source, fileName);
|
|
185
|
+
const entitlements = buildEntitlements(matches);
|
|
186
|
+
const violations = validateClaims(matches, claims);
|
|
187
|
+
const safe = violations.every(v => v.severity !== 'error');
|
|
188
|
+
const summary = buildSummary(entitlements, violations, safe);
|
|
189
|
+
return {
|
|
190
|
+
entitlements,
|
|
191
|
+
matches,
|
|
192
|
+
violations,
|
|
193
|
+
safe,
|
|
194
|
+
summary,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
// ============================================================================
|
|
198
|
+
// Internals
|
|
199
|
+
// ============================================================================
|
|
200
|
+
/**
|
|
201
|
+
* Precompute line start offsets for O(log n) line-number resolution.
|
|
202
|
+
* @internal
|
|
203
|
+
*/
|
|
204
|
+
function buildLineOffsets(source) {
|
|
205
|
+
const offsets = [0]; // Line 1 starts at offset 0
|
|
206
|
+
for (let i = 0; i < source.length; i++) {
|
|
207
|
+
if (source[i] === '\n')
|
|
208
|
+
offsets.push(i + 1);
|
|
209
|
+
}
|
|
210
|
+
return offsets;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Binary search for the line number at a given character offset.
|
|
214
|
+
* O(log n) per lookup vs O(n) for naive iteration.
|
|
215
|
+
* @internal
|
|
216
|
+
*/
|
|
217
|
+
function resolveLineNumber(offsets, offset) {
|
|
218
|
+
let lo = 0;
|
|
219
|
+
let hi = offsets.length - 1;
|
|
220
|
+
while (lo < hi) {
|
|
221
|
+
const mid = (lo + hi + 1) >>> 1;
|
|
222
|
+
if (offsets[mid] <= offset)
|
|
223
|
+
lo = mid;
|
|
224
|
+
else
|
|
225
|
+
hi = mid - 1;
|
|
226
|
+
}
|
|
227
|
+
return lo + 1; // 1-based
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Build a human-readable summary.
|
|
231
|
+
* @internal
|
|
232
|
+
*/
|
|
233
|
+
function buildSummary(entitlements, violations, safe) {
|
|
234
|
+
const active = ALL_CATEGORIES.filter(c => entitlements[c]);
|
|
235
|
+
if (active.length === 0) {
|
|
236
|
+
return 'No I/O entitlements detected — handler is sandboxed.';
|
|
237
|
+
}
|
|
238
|
+
const errorCount = violations.filter(v => v.severity === 'error').length;
|
|
239
|
+
const violationSuffix = violations.length > 0
|
|
240
|
+
? ` | ${violations.length} violation(s) (${errorCount} errors)`
|
|
241
|
+
: ' | No violations';
|
|
242
|
+
return `Entitlements: [${active.join(', ')}]${violationSuffix} | ${safe ? 'SAFE' : 'UNSAFE'}`;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=EntitlementScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntitlementScanner.js","sourceRoot":"","sources":["../../src/introspection/EntitlementScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GovernanceObserver — Observability Bridge for Governance Operations
|
|
3
|
+
*
|
|
4
|
+
* Wraps governance operations (contract compilation, lockfile generation,
|
|
5
|
+
* integrity verification, attestation) with structured debug events and
|
|
6
|
+
* OpenTelemetry-compatible tracing spans.
|
|
7
|
+
*
|
|
8
|
+
* This module is the bridge between the governance/introspection layer
|
|
9
|
+
* and the observability layer. It is opt-in — governance operations
|
|
10
|
+
* work identically without it. When enabled, every governance operation
|
|
11
|
+
* emits a `GovernanceEvent` and/or a tracing span.
|
|
12
|
+
*
|
|
13
|
+
* **Zero overhead when disabled**: When no observer or tracer is
|
|
14
|
+
* configured, the wrapper functions are no-ops that delegate directly.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import type { DebugObserverFn, GovernanceOperation } from '../observability/DebugObserver.js';
|
|
19
|
+
import type { FusionTracer } from '../observability/Tracing.js';
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for governance observability.
|
|
22
|
+
*
|
|
23
|
+
* Pass to `createGovernanceObserver()` to enable debug events
|
|
24
|
+
* and/or tracing spans for governance operations.
|
|
25
|
+
*/
|
|
26
|
+
export interface GovernanceObserverConfig {
|
|
27
|
+
/** Debug event handler — receives GovernanceEvent */
|
|
28
|
+
readonly debug?: DebugObserverFn;
|
|
29
|
+
/** OpenTelemetry-compatible tracer */
|
|
30
|
+
readonly tracer?: FusionTracer;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A governance observer that emits debug events and tracing spans.
|
|
34
|
+
*
|
|
35
|
+
* All methods accept a callback that performs the actual work.
|
|
36
|
+
* The observer wraps the callback with timing and event emission.
|
|
37
|
+
*/
|
|
38
|
+
export interface GovernanceObserver {
|
|
39
|
+
/**
|
|
40
|
+
* Wrap a governance operation with observability.
|
|
41
|
+
*
|
|
42
|
+
* @param operation - Named governance operation
|
|
43
|
+
* @param label - Human-readable label
|
|
44
|
+
* @param fn - The actual work to perform
|
|
45
|
+
* @returns The result of `fn`
|
|
46
|
+
*/
|
|
47
|
+
observe<T>(operation: GovernanceOperation, label: string, fn: () => T): T;
|
|
48
|
+
/**
|
|
49
|
+
* Wrap an async governance operation with observability.
|
|
50
|
+
*
|
|
51
|
+
* @param operation - Named governance operation
|
|
52
|
+
* @param label - Human-readable label
|
|
53
|
+
* @param fn - The actual async work to perform
|
|
54
|
+
* @returns The result of `fn`
|
|
55
|
+
*/
|
|
56
|
+
observeAsync<T>(operation: GovernanceOperation, label: string, fn: () => Promise<T>): Promise<T>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create a governance observer that emits debug events and/or tracing
|
|
60
|
+
* spans for governance operations.
|
|
61
|
+
*
|
|
62
|
+
* @param config - Observer configuration (debug handler and/or tracer)
|
|
63
|
+
* @returns A `GovernanceObserver` instance
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { createGovernanceObserver } from '@vinkius-core/mcp-fusion/introspection';
|
|
68
|
+
* import { createDebugObserver } from '@vinkius-core/mcp-fusion';
|
|
69
|
+
*
|
|
70
|
+
* const observer = createGovernanceObserver({
|
|
71
|
+
* debug: createDebugObserver(),
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* const contracts = observer.observe(
|
|
75
|
+
* 'contract.compile',
|
|
76
|
+
* 'Compiling 5 tool contracts',
|
|
77
|
+
* () => compileContracts(builders),
|
|
78
|
+
* );
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function createGovernanceObserver(config: GovernanceObserverConfig): GovernanceObserver;
|
|
82
|
+
/**
|
|
83
|
+
* Create a no-op governance observer.
|
|
84
|
+
*
|
|
85
|
+
* Used when observability is not configured. Zero overhead.
|
|
86
|
+
*/
|
|
87
|
+
export declare function createNoopObserver(): GovernanceObserver;
|
|
88
|
+
//# sourceMappingURL=GovernanceObserver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GovernanceObserver.d.ts","sourceRoot":"","sources":["../../src/introspection/GovernanceObserver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC9F,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,6BAA6B,CAAC;AActF;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACrC,qDAAqD;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAClC;AAMD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,EACL,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,CAAC,GACZ,CAAC,CAAC;IAEL;;;;;;;OAOG;IACH,YAAY,CAAC,CAAC,EACV,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,kBAAkB,CAoH7F;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,kBAAkB,CAKvD"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { SpanStatusCode } from '../observability/Tracing.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a governance observer that emits debug events and/or tracing
|
|
4
|
+
* spans for governance operations.
|
|
5
|
+
*
|
|
6
|
+
* @param config - Observer configuration (debug handler and/or tracer)
|
|
7
|
+
* @returns A `GovernanceObserver` instance
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createGovernanceObserver } from '@vinkius-core/mcp-fusion/introspection';
|
|
12
|
+
* import { createDebugObserver } from '@vinkius-core/mcp-fusion';
|
|
13
|
+
*
|
|
14
|
+
* const observer = createGovernanceObserver({
|
|
15
|
+
* debug: createDebugObserver(),
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* const contracts = observer.observe(
|
|
19
|
+
* 'contract.compile',
|
|
20
|
+
* 'Compiling 5 tool contracts',
|
|
21
|
+
* () => compileContracts(builders),
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function createGovernanceObserver(config) {
|
|
26
|
+
const { debug, tracer } = config;
|
|
27
|
+
function observe(operation, label, fn) {
|
|
28
|
+
const start = Date.now();
|
|
29
|
+
const span = tracer?.startSpan(`mcp.governance.${operation}`, {
|
|
30
|
+
attributes: {
|
|
31
|
+
'mcp.governance.operation': operation,
|
|
32
|
+
'mcp.governance.label': label,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
const result = fn();
|
|
37
|
+
const durationMs = Date.now() - start;
|
|
38
|
+
span?.setAttribute('mcp.governance.outcome', 'success');
|
|
39
|
+
span?.setAttribute('mcp.durationMs', durationMs);
|
|
40
|
+
span?.setStatus({ code: SpanStatusCode.OK });
|
|
41
|
+
debug?.({
|
|
42
|
+
type: 'governance',
|
|
43
|
+
operation,
|
|
44
|
+
label,
|
|
45
|
+
outcome: 'success',
|
|
46
|
+
durationMs,
|
|
47
|
+
timestamp: Date.now(),
|
|
48
|
+
});
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
const durationMs = Date.now() - start;
|
|
53
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
54
|
+
span?.setAttribute('mcp.governance.outcome', 'failure');
|
|
55
|
+
span?.setAttribute('mcp.durationMs', durationMs);
|
|
56
|
+
span?.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
57
|
+
span?.recordException(err instanceof Error ? err : new Error(message));
|
|
58
|
+
debug?.({
|
|
59
|
+
type: 'governance',
|
|
60
|
+
operation,
|
|
61
|
+
label,
|
|
62
|
+
outcome: 'failure',
|
|
63
|
+
detail: message,
|
|
64
|
+
durationMs,
|
|
65
|
+
timestamp: Date.now(),
|
|
66
|
+
});
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
span?.end();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function observeAsync(operation, label, fn) {
|
|
74
|
+
const start = Date.now();
|
|
75
|
+
const span = tracer?.startSpan(`mcp.governance.${operation}`, {
|
|
76
|
+
attributes: {
|
|
77
|
+
'mcp.governance.operation': operation,
|
|
78
|
+
'mcp.governance.label': label,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
try {
|
|
82
|
+
const result = await fn();
|
|
83
|
+
const durationMs = Date.now() - start;
|
|
84
|
+
span?.setAttribute('mcp.governance.outcome', 'success');
|
|
85
|
+
span?.setAttribute('mcp.durationMs', durationMs);
|
|
86
|
+
span?.setStatus({ code: SpanStatusCode.OK });
|
|
87
|
+
debug?.({
|
|
88
|
+
type: 'governance',
|
|
89
|
+
operation,
|
|
90
|
+
label,
|
|
91
|
+
outcome: 'success',
|
|
92
|
+
durationMs,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
});
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
const durationMs = Date.now() - start;
|
|
99
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
100
|
+
span?.setAttribute('mcp.governance.outcome', 'failure');
|
|
101
|
+
span?.setAttribute('mcp.durationMs', durationMs);
|
|
102
|
+
span?.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
103
|
+
span?.recordException(err instanceof Error ? err : new Error(message));
|
|
104
|
+
debug?.({
|
|
105
|
+
type: 'governance',
|
|
106
|
+
operation,
|
|
107
|
+
label,
|
|
108
|
+
outcome: 'failure',
|
|
109
|
+
detail: message,
|
|
110
|
+
durationMs,
|
|
111
|
+
timestamp: Date.now(),
|
|
112
|
+
});
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
span?.end();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return { observe, observeAsync };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create a no-op governance observer.
|
|
123
|
+
*
|
|
124
|
+
* Used when observability is not configured. Zero overhead.
|
|
125
|
+
*/
|
|
126
|
+
export function createNoopObserver() {
|
|
127
|
+
return {
|
|
128
|
+
observe: (_op, _label, fn) => fn(),
|
|
129
|
+
observeAsync: (_op, _label, fn) => fn(),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=GovernanceObserver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GovernanceObserver.js","sourceRoot":"","sources":["../../src/introspection/GovernanceObserver.ts"],"names":[],"mappings":"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"}
|