@guardion/guardion 0.3.0 → 0.4.1

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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +202 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +590 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/connectors/claude-code/hooks/enforce.cjs +58 -0
  7. package/{hooks → dist/connectors/claude-code/hooks}/guardion-hook.cjs +123 -1
  8. package/dist/connectors/claude-code/hooks/tool-scanner.cjs +272 -0
  9. package/dist/connectors/claude-code/src/collect.d.ts +5 -0
  10. package/dist/connectors/claude-code/src/collect.d.ts.map +1 -0
  11. package/dist/connectors/claude-code/src/collect.js +17 -0
  12. package/dist/connectors/claude-code/src/collect.js.map +1 -0
  13. package/dist/{installer.d.ts → connectors/claude-code/src/installer.d.ts} +1 -1
  14. package/dist/connectors/claude-code/src/installer.d.ts.map +1 -0
  15. package/dist/{installer.js → connectors/claude-code/src/installer.js} +2 -2
  16. package/dist/connectors/claude-code/src/installer.js.map +1 -0
  17. package/dist/connectors/claude-code/src/scanner.d.ts.map +1 -0
  18. package/dist/{scanner.js → connectors/claude-code/src/scanner.js} +1 -1
  19. package/dist/connectors/claude-code/src/scanner.js.map +1 -0
  20. package/dist/{config.d.ts → core/config.d.ts} +96 -0
  21. package/dist/core/config.d.ts.map +1 -0
  22. package/dist/{config.js → core/config.js} +44 -0
  23. package/dist/core/config.js.map +1 -0
  24. package/dist/{constants.d.ts → core/constants.d.ts} +1 -1
  25. package/dist/core/constants.d.ts.map +1 -0
  26. package/dist/{constants.js → core/constants.js} +1 -1
  27. package/dist/core/constants.js.map +1 -0
  28. package/dist/core/discover.d.ts +36 -0
  29. package/dist/core/discover.d.ts.map +1 -0
  30. package/dist/core/discover.js +154 -0
  31. package/dist/core/discover.js.map +1 -0
  32. package/dist/core/fingerprint.cjs +84 -0
  33. package/dist/core/inventory.d.ts +35 -0
  34. package/dist/core/inventory.d.ts.map +1 -0
  35. package/dist/core/inventory.js +69 -0
  36. package/dist/core/inventory.js.map +1 -0
  37. package/dist/core/keychain.d.ts.map +1 -0
  38. package/dist/core/keychain.js.map +1 -0
  39. package/dist/core/mcp/guard-client.cjs +86 -0
  40. package/dist/core/mcp/interceptor.cjs +238 -0
  41. package/dist/core/mcp/jsonrpc.cjs +194 -0
  42. package/dist/core/mcp/transport/http-server-side.cjs +89 -0
  43. package/dist/core/mcp/transport/http-upstream.cjs +111 -0
  44. package/dist/core/mcp/transport/http_forward.cjs +40 -0
  45. package/dist/core/mcp/transport/http_input.cjs +46 -0
  46. package/dist/core/mcp/transport/http_reverse.cjs +33 -0
  47. package/dist/core/mcp/transport/index.cjs +32 -0
  48. package/dist/core/mcp/transport/sse_bridge.cjs +101 -0
  49. package/dist/core/mcp/transport/stdio.cjs +60 -0
  50. package/dist/core/mcp-interpose.cjs +141 -0
  51. package/dist/core/mcp-protect.d.ts +69 -0
  52. package/dist/core/mcp-protect.d.ts.map +1 -0
  53. package/dist/core/mcp-protect.js +205 -0
  54. package/dist/core/mcp-protect.js.map +1 -0
  55. package/dist/core/mcp-scan.d.ts +40 -0
  56. package/dist/core/mcp-scan.d.ts.map +1 -0
  57. package/dist/core/mcp-scan.js +201 -0
  58. package/dist/core/mcp-scan.js.map +1 -0
  59. package/dist/core/mock-server.d.ts.map +1 -0
  60. package/dist/{mock-server.js → core/mock-server.js} +41 -0
  61. package/dist/core/mock-server.js.map +1 -0
  62. package/package.json +10 -10
  63. package/config.yaml.example +0 -84
  64. package/dist/cli.d.ts.map +0 -1
  65. package/dist/cli.js +0 -298
  66. package/dist/cli.js.map +0 -1
  67. package/dist/config.d.ts.map +0 -1
  68. package/dist/config.js.map +0 -1
  69. package/dist/constants.d.ts.map +0 -1
  70. package/dist/constants.js.map +0 -1
  71. package/dist/installer.d.ts.map +0 -1
  72. package/dist/installer.js.map +0 -1
  73. package/dist/keychain.d.ts.map +0 -1
  74. package/dist/keychain.js.map +0 -1
  75. package/dist/mock-server.d.ts.map +0 -1
  76. package/dist/mock-server.js.map +0 -1
  77. package/dist/scanner.d.ts.map +0 -1
  78. package/dist/scanner.js.map +0 -1
  79. /package/dist/{cli.d.ts → bin/cli.d.ts} +0 -0
  80. /package/dist/{scanner.d.ts → connectors/claude-code/src/scanner.d.ts} +0 -0
  81. /package/dist/{keychain.d.ts → core/keychain.d.ts} +0 -0
  82. /package/dist/{keychain.js → core/keychain.js} +0 -0
  83. /package/{hooks → dist/core}/metadata.cjs +0 -0
  84. /package/dist/{mock-server.d.ts → core/mock-server.d.ts} +0 -0
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+ /**
3
+ * P2 enforcement mapping (pure, testable) — Claude-Code-native equivalent of
4
+ * AGT's MCP gateway dual-stage pipeline. PreToolUse scans tool INPUT, PostToolUse
5
+ * scans tool OUTPUT. The decision FOLLOWS THE POLICY ACTION: the Guard server
6
+ * returns `deny` only when policy.action=block, so:
7
+ * res.deny → DENY (PreToolUse: permissionDecision deny / PostToolUse: block)
8
+ * res.flagged → FLAG (warn, non-blocking additionalContext) — action=flag, or
9
+ * a held step_up/defer
10
+ * Default fail-OPEN; fail-closed only when explicitly enabled.
11
+ */
12
+
13
+ /** Build the tool message sent to /v1/guard from a Claude Code hook payload. */
14
+ function toolMessage(event, payload) {
15
+ const toolName = payload.tool_name || payload.toolName || '';
16
+ if (event === 'PostToolUse') {
17
+ const resp = payload.tool_response != null ? payload.tool_response
18
+ : (payload.tool_output != null ? payload.tool_output : '');
19
+ // Canonical Guard role is `tool_response` (NOT `tool_output`, which is a
20
+ // Target name) — must match MessagesRole in guard/guard/core/schemas.py.
21
+ return { role: 'tool_response', name: toolName,
22
+ content: typeof resp === 'string' ? resp : JSON.stringify(resp || '') };
23
+ }
24
+ const input = payload.tool_input != null ? payload.tool_input : (payload.toolInput || {});
25
+ const inputText = typeof input === 'string' ? input : JSON.stringify(input || {});
26
+ return { role: 'tool_input', name: toolName, content: `${toolName} ${inputText}`.trim() };
27
+ }
28
+
29
+ function guardReason(res) {
30
+ try {
31
+ const b = res && Array.isArray(res.breakdown) ? res.breakdown[0] : null;
32
+ const label = b && (b.top_label || b.label);
33
+ return label ? `Guardion governance: ${label}` : 'Guardion governance policy';
34
+ } catch { return 'Guardion governance policy'; }
35
+ }
36
+
37
+ /** Map a Guard verdict → Claude Code hook decision JSON, or null to allow. */
38
+ function enforceDecision(event, res, failClosed) {
39
+ if (!res) { // Guard unreachable / timeout
40
+ if (!failClosed) return null; // fail-open (default): allow
41
+ return event === 'PreToolUse'
42
+ ? { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny',
43
+ permissionDecisionReason: 'Guardion governance unavailable (fail-closed)' } }
44
+ : { decision: 'block', reason: 'Guardion governance unavailable (fail-closed)' };
45
+ }
46
+ const reason = guardReason(res);
47
+ if (res.deny) { // policy.action=block → DENY
48
+ return event === 'PreToolUse'
49
+ ? { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: reason } }
50
+ : { decision: 'block', reason };
51
+ }
52
+ if (res.flagged) { // policy.action=flag → FLAG (warn, non-blocking)
53
+ return { hookSpecificOutput: { hookEventName: event, additionalContext: `[guardion] flagged — ${reason}` } };
54
+ }
55
+ return null; // allow
56
+ }
57
+
58
+ module.exports = { toolMessage, guardReason, enforceDecision };
@@ -166,17 +166,99 @@ function postEvent(apiUrl, token, payload, timeoutMs) {
166
166
  });
167
167
  }
168
168
 
169
+ // ── Tool inventory snapshot ──────────────────────────────────────────────────
170
+ // Sends the local tool inventory (skills, MCP servers, plugins, built-ins) to
171
+ // Guard API at /v1/guard for scanning + storage in ai_tool_inventory.
172
+ // Fire-and-forget; never blocks or fails the session.
173
+
174
+ function postInventorySnapshot(apiUrl, token, payload, timeoutMs) {
175
+ return new Promise(resolve => {
176
+ let url;
177
+ try { url = new URL('/v1/guard', apiUrl); } catch { return resolve(); }
178
+
179
+ const transport = url.protocol === 'https:' ? https : http;
180
+ const body = JSON.stringify(payload);
181
+
182
+ const req = transport.request({
183
+ hostname: url.hostname,
184
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
185
+ path: url.pathname,
186
+ method: 'POST',
187
+ headers: {
188
+ 'Content-Type': 'application/json',
189
+ 'Authorization': `Bearer ${token}`,
190
+ 'Content-Length': Buffer.byteLength(body),
191
+ },
192
+ timeout: timeoutMs,
193
+ }, res => { res.resume(); res.on('end', resolve); });
194
+
195
+ req.on('error', resolve);
196
+ req.on('timeout', () => { req.destroy(); resolve(); });
197
+ req.write(body);
198
+ req.end();
199
+ });
200
+ }
201
+
202
+ function collectInventory(cwd, inventoryConfig) {
203
+ try {
204
+ const { collectLocalTools } = require('./tool-scanner.cjs');
205
+ return collectLocalTools(cwd || process.cwd(), inventoryConfig || {});
206
+ } catch {
207
+ return [];
208
+ }
209
+ }
210
+
169
211
  // ── Metadata ─────────────────────────────────────────────────────────────────
170
212
 
171
213
  function collectMetadata(payload) {
172
214
  try {
173
- const { collectMetadata: collect } = require('./metadata.cjs');
215
+ const { collectMetadata: collect } = require('../../../core/metadata.cjs');
174
216
  return collect(payload);
175
217
  } catch {
176
218
  return { session_id: payload.session_id || null, cwd: payload.cwd || process.cwd() };
177
219
  }
178
220
  }
179
221
 
222
+ // ── Enforcement (P2): synchronous Guard eval + Claude Code hook decision ──────
223
+ // PreToolUse scans the tool INPUT and can deny/ask; PostToolUse scans the tool
224
+ // OUTPUT and can block. This is the Claude-Code-native equivalent of AGT's MCP
225
+ // gateway dual-stage pipeline (intercept_tool_call / intercept_tool_response) —
226
+ // no proxy needed. Fires for native AND mcp__* tools.
227
+
228
+ function postGuardEval(apiUrl, token, payload, timeoutMs) {
229
+ return new Promise(resolve => {
230
+ let url;
231
+ try { url = new URL('/v1/guard', apiUrl); } catch { return resolve(null); }
232
+ const transport = url.protocol === 'https:' ? https : http;
233
+ const body = JSON.stringify(payload);
234
+ const req = transport.request({
235
+ hostname: url.hostname,
236
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
237
+ path: url.pathname,
238
+ method: 'POST',
239
+ headers: {
240
+ 'Content-Type': 'application/json',
241
+ 'Authorization': `Bearer ${token}`,
242
+ 'Content-Length': Buffer.byteLength(body),
243
+ },
244
+ timeout: timeoutMs,
245
+ }, res => {
246
+ let data = '';
247
+ res.setEncoding('utf8');
248
+ res.on('data', c => { data += c; });
249
+ res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve(null); } });
250
+ });
251
+ req.on('error', () => resolve(null));
252
+ req.on('timeout', () => { req.destroy(); resolve(null); });
253
+ req.write(body);
254
+ req.end();
255
+ });
256
+ }
257
+
258
+ // Pure decision/mapping logic lives in enforce.cjs (testable; this file reads
259
+ // stdin + sets a timer on load, so it can't be required from tests).
260
+ const { toolMessage, enforceDecision } = require('./enforce.cjs');
261
+
180
262
  // ── Main ─────────────────────────────────────────────────────────────────────
181
263
 
182
264
  const config = loadConfig();
@@ -201,6 +283,23 @@ process.stdin.on('end', async () => {
201
283
  if (config.policy) payload.policy = config.policy;
202
284
  if (config.application) payload.application = config.application;
203
285
 
286
+ // ── P2: synchronous enforcement for tool input/output ──────────────────────
287
+ // OPT-IN: set config.enforce=true to block/warn on tool input+output. Default
288
+ // off (observability-first) so day-one false positives can't block real work.
289
+ // The /v1/guard call also logs, so we skip the separate event post here.
290
+ if (config.enforce === true && (event === 'PreToolUse' || event === 'PostToolUse')) {
291
+ const res = await postGuardEval(config.api_url, token, {
292
+ application: payload.application || 'claude-code',
293
+ policy: config.policy || undefined,
294
+ session: payload.session_id || readCurrentSession() || undefined,
295
+ messages: [toolMessage(event, payload)],
296
+ log: true,
297
+ }, timeoutMs);
298
+ const out = enforceDecision(event, res, config.fail_closed === true);
299
+ if (out) process.stdout.write(JSON.stringify(out));
300
+ return process.exit(0);
301
+ }
302
+
204
303
  if (event === 'SessionStart') {
205
304
  const meta = collectMetadata(payload);
206
305
  const sessionId = payload.session_id || meta.session_id || `gs-${Date.now()}`;
@@ -217,6 +316,29 @@ process.stdin.on('end', async () => {
217
316
  injectTraceHeaders(sessionId, meta);
218
317
  }
219
318
 
319
+ // Tool inventory snapshot — scan local skills/MCP/plugins/built-ins and
320
+ // send to Guard API for scanning + inventory storage (fire-and-forget).
321
+ const inv = config.inventory || {};
322
+ if (inv.enabled !== false) {
323
+ const tools = collectInventory(payload.cwd, inv);
324
+ if (tools.length > 0) {
325
+ // Rug-pull pin (P1): attach prev_* fingerprints from the local pin so the
326
+ // server flags a changed tool description as drift. Never throws.
327
+ try {
328
+ const { pinAndEnrich } = require('../../../core/fingerprint.cjs');
329
+ pinAndEnrich(tools, path.join(GUARDION_DIR, 'fingerprints.json'));
330
+ } catch { /* fingerprint pin is best-effort */ }
331
+ await postInventorySnapshot(config.api_url, token, {
332
+ tools,
333
+ session: sessionId,
334
+ policy: config.policy || undefined,
335
+ application: config.application || 'claude-code',
336
+ log: true,
337
+ snapshot_source: 'plugin_scan',
338
+ }, timeoutMs);
339
+ }
340
+ }
341
+
220
342
  } else if (event === 'SessionEnd') {
221
343
  const sessionId = payload.session_id || readCurrentSession();
222
344
  payload.trace_id = sessionId;
@@ -0,0 +1,272 @@
1
+ 'use strict';
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ const HOME = os.homedir();
7
+
8
+ // ── SKILL.md parser ──────────────────────────────────────────────────────────
9
+ // Parse YAML frontmatter (---\nkey: value\n---) from a SKILL.md file.
10
+ // Returns { name, description } or null. Never throws.
11
+ function parseSkillFrontmatter(content) {
12
+ try {
13
+ const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
14
+ if (!match) return null;
15
+ const front = match[1];
16
+ const name = (front.match(/^name:\s*(.+)$/m) || [])[1]?.trim();
17
+ // description can be multi-line (| or |- syntax) — grab just the first line after |-
18
+ const descMatch = front.match(/^description:\s*(.+)$/m)
19
+ || front.match(/^description:\s*[|>-]*\s*\n\s+(.+)$/m);
20
+ const description = descMatch ? descMatch[1].trim() : null;
21
+ return { name: name || null, description: description || null };
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+
27
+ // ── Skills ───────────────────────────────────────────────────────────────────
28
+ function collectSkills(cwd) {
29
+ const tools = [];
30
+ const skillRoots = [
31
+ path.join(HOME, '.claude', 'skills'),
32
+ path.join(cwd, '.claude', 'skills'),
33
+ // plugin cache skills
34
+ path.join(HOME, '.claude', 'plugins', 'cache'),
35
+ path.join(HOME, '.claude', 'plugins', 'marketplaces'),
36
+ ];
37
+
38
+ for (const root of skillRoots) {
39
+ try {
40
+ // Recursively find SKILL.md files (max depth 6 to avoid runaway)
41
+ const found = findFiles(root, 'SKILL.md', 6);
42
+ for (const skillPath of found) {
43
+ try {
44
+ const content = fs.readFileSync(skillPath, 'utf8');
45
+ const meta = parseSkillFrontmatter(content);
46
+ if (!meta) continue;
47
+ const name = meta.name || path.basename(path.dirname(skillPath));
48
+ tools.push({
49
+ name,
50
+ description: meta.description || `Skill: ${name}`,
51
+ server: 'skill',
52
+ source: 'skill',
53
+ snapshot_source: 'plugin_scan',
54
+ });
55
+ } catch { /* skip unreadable files */ }
56
+ }
57
+ } catch { /* root dir absent */ }
58
+ }
59
+ return dedup(tools, t => `skill:${t.name}`);
60
+ }
61
+
62
+ // ── MCP servers ──────────────────────────────────────────────────────────────
63
+ function collectMCPServers(cwd) {
64
+ const tools = [];
65
+ const configPaths = [
66
+ path.join(HOME, '.claude', 'settings.json'),
67
+ path.join(cwd, '.mcp.json'),
68
+ path.join(cwd, '.claude', 'settings.json'),
69
+ ];
70
+
71
+ // Also scan plugin cache .mcp.json files
72
+ try {
73
+ const cacheRoot = path.join(HOME, '.claude', 'plugins', 'cache');
74
+ const mcpFiles = findFiles(cacheRoot, '.mcp.json', 5);
75
+ configPaths.push(...mcpFiles);
76
+ } catch { /* absent */ }
77
+
78
+ for (const cfgPath of configPaths) {
79
+ try {
80
+ const raw = fs.readFileSync(cfgPath, 'utf8');
81
+ const json = JSON.parse(raw);
82
+ const mcpServers = json.mcpServers || (cfgPath.endsWith('.mcp.json') ? json : null);
83
+ if (!mcpServers || typeof mcpServers !== 'object') continue;
84
+
85
+ for (const [serverName, serverCfg] of Object.entries(mcpServers)) {
86
+ const transport = serverCfg.type || (serverCfg.command ? 'stdio' : 'http');
87
+ const endpoint = serverCfg.url || serverCfg.command || 'unknown';
88
+ tools.push({
89
+ name: serverName,
90
+ description: `MCP server (${transport}): ${endpoint}`,
91
+ server: serverName,
92
+ source: 'mcp',
93
+ snapshot_source: 'plugin_scan',
94
+ });
95
+ }
96
+ } catch { /* skip invalid files */ }
97
+ }
98
+ return dedup(tools, t => `mcp:${t.name}`);
99
+ }
100
+
101
+ // ── Plugin agents ─────────────────────────────────────────────────────────────
102
+ // Report EVERY installed plugin in the Claude Code plugin cache — not only the
103
+ // ones declaring hooks — so the inventory reflects the agent's full installed-
104
+ // plugin surface. For each plugin we record what it provides (hooks / mcp /
105
+ // skills / commands / agents) both from the manifest and from the on-disk
106
+ // layout (Claude Code auto-discovers those directories).
107
+ //
108
+ // Identity is the install directory: a plugin that ships both a root and a
109
+ // `.claude-plugin/` manifest counts once, while distinct installs (different
110
+ // cache locations or versions) stay separate instead of being silently merged.
111
+ function collectPluginTools(cacheRootOverride) {
112
+ const tools = [];
113
+ const cacheRoot = cacheRootOverride || path.join(HOME, '.claude', 'plugins', 'cache');
114
+
115
+ let manifestFiles;
116
+ try { manifestFiles = findFiles(cacheRoot, 'plugin.json', 6); }
117
+ catch { return tools; }
118
+
119
+ // installDir -> aggregated info (collapses a plugin's root + .claude-plugin manifests)
120
+ const byInstall = new Map();
121
+
122
+ for (const mPath of manifestFiles) {
123
+ // Ignore stray manifests bundled inside a plugin's dependencies.
124
+ if (mPath.includes(`${path.sep}node_modules${path.sep}`)) continue;
125
+ try {
126
+ const manifest = JSON.parse(fs.readFileSync(mPath, 'utf8'));
127
+
128
+ // Install dir = the plugin root (strip a trailing .claude-plugin/).
129
+ let installDir = path.dirname(mPath);
130
+ if (path.basename(installDir) === '.claude-plugin') installDir = path.dirname(installDir);
131
+
132
+ // Marketplace = first path segment under the cache root (e.g. claude-plugins-official).
133
+ const rel = path.relative(cacheRoot, installDir);
134
+ const marketplace = (rel.split(path.sep)[0]) || 'local';
135
+
136
+ const entry = byInstall.get(installDir) || {
137
+ marketplace,
138
+ name: path.basename(installDir),
139
+ version: '',
140
+ description: '',
141
+ caps: new Set(),
142
+ mcpServers: {},
143
+ };
144
+ if (manifest.name) entry.name = manifest.name;
145
+ if (manifest.version) entry.version = manifest.version;
146
+ if (manifest.description) entry.description = manifest.description;
147
+
148
+ // Capabilities — from the manifest …
149
+ if (manifest.hooks && typeof manifest.hooks === 'object') entry.caps.add('hooks');
150
+ if (manifest.commands) entry.caps.add('commands');
151
+ if (manifest.agents) entry.caps.add('agents');
152
+ if (manifest.mcpServers && typeof manifest.mcpServers === 'object') {
153
+ entry.caps.add('mcp');
154
+ Object.assign(entry.mcpServers, manifest.mcpServers);
155
+ }
156
+ // … and from the on-disk layout (auto-discovered directories / files).
157
+ for (const [dir, cap] of [['hooks', 'hooks'], ['commands', 'commands'], ['agents', 'agents'], ['skills', 'skills']]) {
158
+ try { if (fs.existsSync(path.join(installDir, dir))) entry.caps.add(cap); } catch { /* ignore */ }
159
+ }
160
+ try { if (fs.existsSync(path.join(installDir, '.mcp.json'))) entry.caps.add('mcp'); } catch { /* ignore */ }
161
+
162
+ byInstall.set(installDir, entry);
163
+ } catch { /* skip invalid manifests */ }
164
+ }
165
+
166
+ for (const p of byInstall.values()) {
167
+ const capabilities = [...p.caps].sort();
168
+ const verLabel = p.version ? `@${p.version}` : '';
169
+ tools.push({
170
+ name: p.name,
171
+ description: p.description
172
+ ? `${p.description} [${capabilities.join(', ') || 'no declared components'}]`
173
+ : `Plugin ${p.name}${verLabel} [${capabilities.join(', ') || 'no declared components'}] from ${p.marketplace}`,
174
+ server: 'plugin',
175
+ source: 'plugin',
176
+ snapshot_source: 'plugin_scan',
177
+ // Structured metadata (Guard's ToolDefinition allows extra fields).
178
+ version: p.version || undefined,
179
+ marketplace: p.marketplace,
180
+ capabilities,
181
+ has_hooks: p.caps.has('hooks'),
182
+ has_mcp: p.caps.has('mcp'),
183
+ has_skills: p.caps.has('skills'),
184
+ });
185
+ // MCP servers declared inline in the plugin manifest → their own entries.
186
+ for (const [serverName, serverCfg] of Object.entries(p.mcpServers)) {
187
+ const cfg = serverCfg && typeof serverCfg === 'object' ? serverCfg : {};
188
+ const transport = cfg.type || (cfg.command ? 'stdio' : 'http');
189
+ const endpoint = cfg.url || cfg.command || 'plugin';
190
+ tools.push({
191
+ name: serverName,
192
+ description: `Plugin MCP server (${transport}): ${endpoint}`,
193
+ server: serverName,
194
+ source: 'mcp',
195
+ snapshot_source: 'plugin_scan',
196
+ });
197
+ }
198
+ }
199
+
200
+ // Plugins are unique per install (name:version:marketplace); MCP entries dedup by name.
201
+ return dedup(tools, t => t.source === 'plugin'
202
+ ? `plugin:${t.name}:${t.version || ''}:${t.marketplace || ''}`
203
+ : `mcp:${t.name}`);
204
+ }
205
+
206
+ // ── Built-in Claude Code tools ────────────────────────────────────────────────
207
+ function builtinTools() {
208
+ return [
209
+ { name: 'Read', description: 'Read file contents from the local filesystem' },
210
+ { name: 'Write', description: 'Write content to a file on the local filesystem' },
211
+ { name: 'Edit', description: 'Make targeted edits to a specific file' },
212
+ { name: 'MultiEdit', description: 'Make multiple targeted edits to one or more files' },
213
+ { name: 'Bash', description: 'Execute a bash command in the shell environment' },
214
+ { name: 'Glob', description: 'Find files and directories using glob patterns' },
215
+ { name: 'Grep', description: 'Search for patterns within file contents' },
216
+ { name: 'LS', description: 'List files and directories at a path' },
217
+ { name: 'WebFetch', description: 'Fetch content from a URL' },
218
+ { name: 'WebSearch', description: 'Search the web for information' },
219
+ { name: 'TodoRead', description: 'Read the current todo list for this session' },
220
+ { name: 'TodoWrite', description: 'Create or update the todo list for this session' },
221
+ { name: 'NotebookRead', description: 'Read and display a Jupyter notebook' },
222
+ { name: 'NotebookEdit', description: 'Edit a cell in a Jupyter notebook' },
223
+ { name: 'Agent', description: 'Spawn a subagent to handle a complex subtask' },
224
+ ].map(t => ({
225
+ ...t,
226
+ server: 'claude-code',
227
+ source: 'native',
228
+ snapshot_source: 'plugin_scan',
229
+ }));
230
+ }
231
+
232
+ // ── Helpers ───────────────────────────────────────────────────────────────────
233
+ function findFiles(dir, filename, maxDepth) {
234
+ const results = [];
235
+ if (maxDepth <= 0) return results;
236
+ let entries;
237
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return results; }
238
+ for (const entry of entries) {
239
+ const fullPath = path.join(dir, entry.name);
240
+ if (entry.isDirectory()) {
241
+ results.push(...findFiles(fullPath, filename, maxDepth - 1));
242
+ } else if (entry.name === filename) {
243
+ results.push(fullPath);
244
+ }
245
+ }
246
+ return results;
247
+ }
248
+
249
+ function dedup(tools, keyFn) {
250
+ const seen = new Set();
251
+ return tools.filter(t => {
252
+ const k = keyFn(t);
253
+ if (seen.has(k)) return false;
254
+ seen.add(k);
255
+ return true;
256
+ });
257
+ }
258
+
259
+ // ── Entry point ───────────────────────────────────────────────────────────────
260
+ function collectLocalTools(cwd, inventoryConfig) {
261
+ const cfg = inventoryConfig || {};
262
+ const tools = [];
263
+ try {
264
+ if (cfg.scan_skills !== false) tools.push(...collectSkills(cwd || process.cwd()));
265
+ if (cfg.scan_mcp !== false) tools.push(...collectMCPServers(cwd || process.cwd()));
266
+ if (cfg.scan_plugins !== false) tools.push(...collectPluginTools());
267
+ if (cfg.scan_builtins !== false) tools.push(...builtinTools());
268
+ } catch { /* never crash the hook */ }
269
+ return tools;
270
+ }
271
+
272
+ module.exports = { collectLocalTools, parseSkillFrontmatter, collectSkills, collectMCPServers, collectPluginTools, builtinTools };
@@ -0,0 +1,5 @@
1
+ import { type ScannedTool } from '../../../core/inventory.js';
2
+ import { type InventoryConfig } from '../../../core/config.js';
3
+ /** Discover local Claude Code tools (skills, MCP servers, plugins, built-ins). Never throws. */
4
+ export declare function collectInventory(cwd: string, inventory?: Partial<InventoryConfig>): ScannedTool[];
5
+ //# sourceMappingURL=collect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../../connectors/claude-code/src/collect.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEzF,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,WAAW,EAAE,CAMjG"}
@@ -0,0 +1,17 @@
1
+ // Claude Code connector — local tool discovery. Delegates to the zero-dep CJS
2
+ // scanner (hooks/tool-scanner.cjs) which knows the Claude Code paths
3
+ // (~/.claude/skills, ~/.claude/plugins, .mcp.json). Universal types + the Guard
4
+ // submission live in core/inventory.
5
+ import path from 'node:path';
6
+ import { createRequire } from 'node:module';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { DEFAULT_INVENTORY_CONFIG } from '../../../core/config.js';
9
+ /** Discover local Claude Code tools (skills, MCP servers, plugins, built-ins). Never throws. */
10
+ export function collectInventory(cwd, inventory) {
11
+ const requireCjs = createRequire(import.meta.url);
12
+ // tool-scanner.cjs sits in this connector's hooks/; dist mirrors source.
13
+ const scannerPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'hooks', 'tool-scanner.cjs');
14
+ const { collectLocalTools } = requireCjs(scannerPath);
15
+ return collectLocalTools(cwd, { ...DEFAULT_INVENTORY_CONFIG, ...(inventory ?? {}) });
16
+ }
17
+ //# sourceMappingURL=collect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../../connectors/claude-code/src/collect.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,qEAAqE;AACrE,gFAAgF;AAChF,qCAAqC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,wBAAwB,EAAwB,MAAM,yBAAyB,CAAC;AAEzF,gGAAgG;AAChG,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,SAAoC;IAChF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,yEAAyE;IACzE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAClH,MAAM,EAAE,iBAAiB,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACtD,OAAO,iBAAiB,CAAC,GAAG,EAAE,EAAE,GAAG,wBAAwB,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { ClaudeSettings, ScanResult } from './scanner.js';
2
- import { type GuardionConfig } from './config.js';
2
+ import { type GuardionConfig } from '../../../core/config.js';
3
3
  export interface PatchOptions {
4
4
  config: GuardionConfig;
5
5
  token: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../../connectors/claude-code/src/installer.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAChF,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,yBAAyB,CAAC;AAwGjC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAG,cAAc,CAAC;IACxB,KAAK,EAAI,MAAM,CAAC;IAChB,GAAG,CAAC,EAAK,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,GAAG,cAAc,CAmB1E;AAID,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAM9E;AAID,wBAAgB,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AAmBD,wBAAgB,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB3D;AAID,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc,CAmC9E"}
@@ -1,8 +1,8 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { BACKUP_SUFFIX, BACKUP_KEEP, HEADER_API_KEY, HEADER_PROVIDER, HEADER_POLICY, } from './constants.js';
5
- import { DEFAULT_GATEWAY, resolvedHookEvents, } from './config.js';
4
+ import { BACKUP_SUFFIX, BACKUP_KEEP, HEADER_API_KEY, HEADER_PROVIDER, HEADER_POLICY, } from '../../../core/constants.js';
5
+ import { DEFAULT_GATEWAY, resolvedHookEvents, } from '../../../core/config.js';
6
6
  // Production hook command — scoped npm package, works everywhere
7
7
  const HOOK_COMMAND_NPX = 'npx --yes @guardion/guardion hook';
8
8
  // Resolve absolute path to the CJS hook for local dev (no npm needed)
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../../../connectors/claude-code/src/installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../connectors/claude-code/src/scanner.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAMpE;AAED,wBAAgB,IAAI,IAAI,UAAU,CAejC"}
@@ -1,5 +1,5 @@
1
1
  import fs from 'node:fs';
2
- import { CLAUDE_SETTINGS_PATH } from './constants.js';
2
+ import { CLAUDE_SETTINGS_PATH } from '../../../core/constants.js';
3
3
  export function readSettings(filePath) {
4
4
  try {
5
5
  return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../../../connectors/claude-code/src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AA0BlE,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAmB,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,MAAM,YAAY,GAAG,oBAAoB,CAAC;IAC1C,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG;QACjB,GAAG,CAAC,QAAQ,EAAE,UAAU,IAAI,EAAE,CAAC;KAChC,CAAC;IAEF,uEAAuE;IACvE,MAAM,mBAAmB,GAAG,OAAO,CACjC,QAAQ,EAAE,GAAG,EAAE,aAAa;QAC1B,QAAQ,EAAE,GAAG,EAAE,gBAAgB;QAC/B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAC7D,CAAC;IAEF,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC;AACrE,CAAC"}