@aaronsb/kg-cli 0.6.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.
- package/README.md +112 -0
- package/dist/api/client.d.ts +867 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +1362 -0
- package/dist/api/client.js.map +1 -0
- package/dist/cli/admin/backup.d.ts +9 -0
- package/dist/cli/admin/backup.d.ts.map +1 -0
- package/dist/cli/admin/backup.js +363 -0
- package/dist/cli/admin/backup.js.map +1 -0
- package/dist/cli/admin/index.d.ts +7 -0
- package/dist/cli/admin/index.d.ts.map +1 -0
- package/dist/cli/admin/index.js +52 -0
- package/dist/cli/admin/index.js.map +1 -0
- package/dist/cli/admin/scheduler.d.ts +7 -0
- package/dist/cli/admin/scheduler.d.ts.map +1 -0
- package/dist/cli/admin/scheduler.js +125 -0
- package/dist/cli/admin/scheduler.js.map +1 -0
- package/dist/cli/admin/status.d.ts +7 -0
- package/dist/cli/admin/status.d.ts.map +1 -0
- package/dist/cli/admin/status.js +134 -0
- package/dist/cli/admin/status.js.map +1 -0
- package/dist/cli/admin/utils.d.ts +34 -0
- package/dist/cli/admin/utils.d.ts.map +1 -0
- package/dist/cli/admin/utils.js +441 -0
- package/dist/cli/admin/utils.js.map +1 -0
- package/dist/cli/ai-config/embedding.d.ts +11 -0
- package/dist/cli/ai-config/embedding.d.ts.map +1 -0
- package/dist/cli/ai-config/embedding.js +598 -0
- package/dist/cli/ai-config/embedding.js.map +1 -0
- package/dist/cli/ai-config/extraction.d.ts +11 -0
- package/dist/cli/ai-config/extraction.d.ts.map +1 -0
- package/dist/cli/ai-config/extraction.js +206 -0
- package/dist/cli/ai-config/extraction.js.map +1 -0
- package/dist/cli/ai-config/index.d.ts +21 -0
- package/dist/cli/ai-config/index.d.ts.map +1 -0
- package/dist/cli/ai-config/index.js +27 -0
- package/dist/cli/ai-config/index.js.map +1 -0
- package/dist/cli/ai-config/keys.d.ts +11 -0
- package/dist/cli/ai-config/keys.d.ts.map +1 -0
- package/dist/cli/ai-config/keys.js +182 -0
- package/dist/cli/ai-config/keys.js.map +1 -0
- package/dist/cli/ai-config/utils.d.ts +13 -0
- package/dist/cli/ai-config/utils.d.ts.map +1 -0
- package/dist/cli/ai-config/utils.js +84 -0
- package/dist/cli/ai-config/utils.js.map +1 -0
- package/dist/cli/artifact.d.ts +8 -0
- package/dist/cli/artifact.d.ts.map +1 -0
- package/dist/cli/artifact.js +296 -0
- package/dist/cli/artifact.js.map +1 -0
- package/dist/cli/auth-admin.d.ts +11 -0
- package/dist/cli/auth-admin.d.ts.map +1 -0
- package/dist/cli/auth-admin.js +415 -0
- package/dist/cli/auth-admin.js.map +1 -0
- package/dist/cli/colors.d.ts +105 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +164 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands.d.ts +6 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +164 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +6 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +694 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/curve-viz.d.ts +89 -0
- package/dist/cli/curve-viz.d.ts.map +1 -0
- package/dist/cli/curve-viz.js +228 -0
- package/dist/cli/curve-viz.js.map +1 -0
- package/dist/cli/database.d.ts +6 -0
- package/dist/cli/database.d.ts.map +1 -0
- package/dist/cli/database.js +324 -0
- package/dist/cli/database.js.map +1 -0
- package/dist/cli/document.d.ts +6 -0
- package/dist/cli/document.d.ts.map +1 -0
- package/dist/cli/document.js +458 -0
- package/dist/cli/document.js.map +1 -0
- package/dist/cli/group.d.ts +8 -0
- package/dist/cli/group.d.ts.map +1 -0
- package/dist/cli/group.js +174 -0
- package/dist/cli/group.js.map +1 -0
- package/dist/cli/health.d.ts +6 -0
- package/dist/cli/health.d.ts.map +1 -0
- package/dist/cli/health.js +34 -0
- package/dist/cli/health.js.map +1 -0
- package/dist/cli/help-formatter.d.ts +16 -0
- package/dist/cli/help-formatter.d.ts.map +1 -0
- package/dist/cli/help-formatter.js +248 -0
- package/dist/cli/help-formatter.js.map +1 -0
- package/dist/cli/help.d.ts +9 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +227 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/ingest.d.ts +6 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +722 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/jobs.d.ts +6 -0
- package/dist/cli/jobs.d.ts.map +1 -0
- package/dist/cli/jobs.js +663 -0
- package/dist/cli/jobs.js.map +1 -0
- package/dist/cli/login.d.ts +21 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +221 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/logout.d.ts +16 -0
- package/dist/cli/logout.d.ts.map +1 -0
- package/dist/cli/logout.js +141 -0
- package/dist/cli/logout.js.map +1 -0
- package/dist/cli/mcp-config.d.ts +10 -0
- package/dist/cli/mcp-config.d.ts.map +1 -0
- package/dist/cli/mcp-config.js +358 -0
- package/dist/cli/mcp-config.js.map +1 -0
- package/dist/cli/oauth.d.ts +15 -0
- package/dist/cli/oauth.d.ts.map +1 -0
- package/dist/cli/oauth.js +296 -0
- package/dist/cli/oauth.js.map +1 -0
- package/dist/cli/ontology.d.ts +6 -0
- package/dist/cli/ontology.d.ts.map +1 -0
- package/dist/cli/ontology.js +231 -0
- package/dist/cli/ontology.js.map +1 -0
- package/dist/cli/polarity.d.ts +6 -0
- package/dist/cli/polarity.d.ts.map +1 -0
- package/dist/cli/polarity.js +295 -0
- package/dist/cli/polarity.js.map +1 -0
- package/dist/cli/projection.d.ts +8 -0
- package/dist/cli/projection.d.ts.map +1 -0
- package/dist/cli/projection.js +297 -0
- package/dist/cli/projection.js.map +1 -0
- package/dist/cli/query-def.d.ts +8 -0
- package/dist/cli/query-def.d.ts.map +1 -0
- package/dist/cli/query-def.js +163 -0
- package/dist/cli/query-def.js.map +1 -0
- package/dist/cli/rbac.d.ts +12 -0
- package/dist/cli/rbac.d.ts.map +1 -0
- package/dist/cli/rbac.js +615 -0
- package/dist/cli/rbac.js.map +1 -0
- package/dist/cli/search.d.ts +6 -0
- package/dist/cli/search.d.ts.map +1 -0
- package/dist/cli/search.js +829 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli/source.d.ts +6 -0
- package/dist/cli/source.d.ts.map +1 -0
- package/dist/cli/source.js +202 -0
- package/dist/cli/source.js.map +1 -0
- package/dist/cli/verb-router.d.ts +25 -0
- package/dist/cli/verb-router.d.ts.map +1 -0
- package/dist/cli/verb-router.js +415 -0
- package/dist/cli/verb-router.js.map +1 -0
- package/dist/cli/vocabulary/config.d.ts +7 -0
- package/dist/cli/vocabulary/config.d.ts.map +1 -0
- package/dist/cli/vocabulary/config.js +201 -0
- package/dist/cli/vocabulary/config.js.map +1 -0
- package/dist/cli/vocabulary/consolidate.d.ts +8 -0
- package/dist/cli/vocabulary/consolidate.d.ts.map +1 -0
- package/dist/cli/vocabulary/consolidate.js +192 -0
- package/dist/cli/vocabulary/consolidate.js.map +1 -0
- package/dist/cli/vocabulary/embeddings.d.ts +9 -0
- package/dist/cli/vocabulary/embeddings.d.ts.map +1 -0
- package/dist/cli/vocabulary/embeddings.js +205 -0
- package/dist/cli/vocabulary/embeddings.js.map +1 -0
- package/dist/cli/vocabulary/epistemic.d.ts +7 -0
- package/dist/cli/vocabulary/epistemic.d.ts.map +1 -0
- package/dist/cli/vocabulary/epistemic.js +315 -0
- package/dist/cli/vocabulary/epistemic.js.map +1 -0
- package/dist/cli/vocabulary/index.d.ts +7 -0
- package/dist/cli/vocabulary/index.d.ts.map +1 -0
- package/dist/cli/vocabulary/index.js +45 -0
- package/dist/cli/vocabulary/index.js.map +1 -0
- package/dist/cli/vocabulary/profiles.d.ts +7 -0
- package/dist/cli/vocabulary/profiles.d.ts.map +1 -0
- package/dist/cli/vocabulary/profiles.js +171 -0
- package/dist/cli/vocabulary/profiles.js.map +1 -0
- package/dist/cli/vocabulary/similarity.d.ts +9 -0
- package/dist/cli/vocabulary/similarity.d.ts.map +1 -0
- package/dist/cli/vocabulary/similarity.js +199 -0
- package/dist/cli/vocabulary/similarity.js.map +1 -0
- package/dist/cli/vocabulary/status.d.ts +8 -0
- package/dist/cli/vocabulary/status.d.ts.map +1 -0
- package/dist/cli/vocabulary/status.js +280 -0
- package/dist/cli/vocabulary/status.js.map +1 -0
- package/dist/cli/vocabulary/sync.d.ts +7 -0
- package/dist/cli/vocabulary/sync.d.ts.map +1 -0
- package/dist/cli/vocabulary/sync.js +111 -0
- package/dist/cli/vocabulary/sync.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth/auth-client.d.ts +247 -0
- package/dist/lib/auth/auth-client.d.ts.map +1 -0
- package/dist/lib/auth/auth-client.js +305 -0
- package/dist/lib/auth/auth-client.js.map +1 -0
- package/dist/lib/auth/challenge.d.ts +39 -0
- package/dist/lib/auth/challenge.d.ts.map +1 -0
- package/dist/lib/auth/challenge.js +125 -0
- package/dist/lib/auth/challenge.js.map +1 -0
- package/dist/lib/auth/client-credentials-flow.d.ts +58 -0
- package/dist/lib/auth/client-credentials-flow.d.ts.map +1 -0
- package/dist/lib/auth/client-credentials-flow.js +118 -0
- package/dist/lib/auth/client-credentials-flow.js.map +1 -0
- package/dist/lib/auth/device-flow.d.ts +75 -0
- package/dist/lib/auth/device-flow.d.ts.map +1 -0
- package/dist/lib/auth/device-flow.js +177 -0
- package/dist/lib/auth/device-flow.js.map +1 -0
- package/dist/lib/auth/index.d.ts +14 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +34 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/oauth-types.d.ts +69 -0
- package/dist/lib/auth/oauth-types.d.ts.map +1 -0
- package/dist/lib/auth/oauth-types.js +10 -0
- package/dist/lib/auth/oauth-types.js.map +1 -0
- package/dist/lib/auth/oauth-utils.d.ts +51 -0
- package/dist/lib/auth/oauth-utils.d.ts.map +1 -0
- package/dist/lib/auth/oauth-utils.js +110 -0
- package/dist/lib/auth/oauth-utils.js.map +1 -0
- package/dist/lib/auth/token-manager.d.ts +87 -0
- package/dist/lib/auth/token-manager.d.ts.map +1 -0
- package/dist/lib/auth/token-manager.js +139 -0
- package/dist/lib/auth/token-manager.js.map +1 -0
- package/dist/lib/auth/token-refresh.d.ts +63 -0
- package/dist/lib/auth/token-refresh.d.ts.map +1 -0
- package/dist/lib/auth/token-refresh.js +141 -0
- package/dist/lib/auth/token-refresh.js.map +1 -0
- package/dist/lib/config.d.ts +286 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +537 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/job-stream.d.ts +53 -0
- package/dist/lib/job-stream.d.ts.map +1 -0
- package/dist/lib/job-stream.js +153 -0
- package/dist/lib/job-stream.js.map +1 -0
- package/dist/lib/mcp-allowlist.d.ts +101 -0
- package/dist/lib/mcp-allowlist.d.ts.map +1 -0
- package/dist/lib/mcp-allowlist.js +340 -0
- package/dist/lib/mcp-allowlist.js.map +1 -0
- package/dist/lib/table-example.d.ts +7 -0
- package/dist/lib/table-example.d.ts.map +1 -0
- package/dist/lib/table-example.js +105 -0
- package/dist/lib/table-example.js.map +1 -0
- package/dist/lib/table.d.ts +95 -0
- package/dist/lib/table.d.ts.map +1 -0
- package/dist/lib/table.js +263 -0
- package/dist/lib/table.js.map +1 -0
- package/dist/lib/terminal-images.d.ts +66 -0
- package/dist/lib/terminal-images.d.ts.map +1 -0
- package/dist/lib/terminal-images.js +268 -0
- package/dist/lib/terminal-images.js.map +1 -0
- package/dist/mcp/formatters.d.ts +100 -0
- package/dist/mcp/formatters.d.ts.map +1 -0
- package/dist/mcp/formatters.js +1411 -0
- package/dist/mcp/formatters.js.map +1 -0
- package/dist/mcp-server.d.ts +9 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +1810 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/types/index.d.ts +742 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Server-Sent Events (SSE) job progress streaming (ADR-018 Phase 1)
|
|
4
|
+
*
|
|
5
|
+
* Provides real-time job progress updates via EventSource API.
|
|
6
|
+
* Gracefully falls back to polling if SSE fails.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.JobProgressStream = void 0;
|
|
10
|
+
exports.trackJobProgress = trackJobProgress;
|
|
11
|
+
// Import EventSource from eventsource package (Node.js)
|
|
12
|
+
// The package exports { EventSource, ErrorEvent }
|
|
13
|
+
const { EventSource } = require('eventsource');
|
|
14
|
+
class JobProgressStream {
|
|
15
|
+
constructor(baseUrl, jobId, callbacks) {
|
|
16
|
+
this.baseUrl = baseUrl;
|
|
17
|
+
this.jobId = jobId;
|
|
18
|
+
this.callbacks = callbacks;
|
|
19
|
+
this.eventSource = null;
|
|
20
|
+
this.closed = false;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Start streaming job progress events.
|
|
24
|
+
*
|
|
25
|
+
* Opens SSE connection to /jobs/{job_id}/stream endpoint.
|
|
26
|
+
* Auto-closes on terminal events (completed/failed/cancelled).
|
|
27
|
+
*/
|
|
28
|
+
start() {
|
|
29
|
+
if (this.eventSource) {
|
|
30
|
+
throw new Error('Stream already started');
|
|
31
|
+
}
|
|
32
|
+
const url = `${this.baseUrl}/jobs/${this.jobId}/stream`;
|
|
33
|
+
this.eventSource = new EventSource(url);
|
|
34
|
+
// Progress event: Job state changed
|
|
35
|
+
this.eventSource.addEventListener('progress', (event) => {
|
|
36
|
+
try {
|
|
37
|
+
const progress = JSON.parse(event.data);
|
|
38
|
+
this.callbacks.onProgress?.(progress);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error('Failed to parse progress event:', error);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
// Completed event: Job finished successfully
|
|
45
|
+
this.eventSource.addEventListener('completed', (event) => {
|
|
46
|
+
try {
|
|
47
|
+
const result = JSON.parse(event.data);
|
|
48
|
+
// Close connection BEFORE callback to prevent error events during callback
|
|
49
|
+
this.close();
|
|
50
|
+
this.callbacks.onCompleted?.(result);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Failed to parse completed event:', error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Failed event: Job failed with error
|
|
57
|
+
this.eventSource.addEventListener('failed', (event) => {
|
|
58
|
+
try {
|
|
59
|
+
const data = JSON.parse(event.data);
|
|
60
|
+
this.close();
|
|
61
|
+
this.callbacks.onFailed?.(data.error);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('Failed to parse failed event:', error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Cancelled event: Job was cancelled
|
|
68
|
+
this.eventSource.addEventListener('cancelled', (event) => {
|
|
69
|
+
try {
|
|
70
|
+
const data = JSON.parse(event.data);
|
|
71
|
+
this.close();
|
|
72
|
+
this.callbacks.onCancelled?.(data.message);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error('Failed to parse cancelled event:', error);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
// Error event: Job not found or connection error
|
|
79
|
+
this.eventSource.addEventListener('error', (event) => {
|
|
80
|
+
try {
|
|
81
|
+
// Check if error contains data (job not found)
|
|
82
|
+
if (event.data) {
|
|
83
|
+
const data = JSON.parse(event.data);
|
|
84
|
+
this.callbacks.onError?.(new Error(data.error));
|
|
85
|
+
this.close();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Connection error - EventSource will auto-reconnect
|
|
89
|
+
// Only call onError if we haven't closed explicitly
|
|
90
|
+
if (!this.closed) {
|
|
91
|
+
this.callbacks.onError?.(new Error('Connection error - retrying...'));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error('Error event:', error);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Keepalive events (no action needed, just keep connection alive)
|
|
100
|
+
this.eventSource.addEventListener('keepalive', () => {
|
|
101
|
+
// No-op: Just prevents timeout
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Close the SSE connection.
|
|
106
|
+
*
|
|
107
|
+
* Safe to call multiple times.
|
|
108
|
+
*/
|
|
109
|
+
close() {
|
|
110
|
+
if (this.eventSource && !this.closed) {
|
|
111
|
+
this.eventSource.close();
|
|
112
|
+
this.eventSource = null;
|
|
113
|
+
this.closed = true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if stream is currently active.
|
|
118
|
+
*/
|
|
119
|
+
isActive() {
|
|
120
|
+
return this.eventSource !== null && !this.closed;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.JobProgressStream = JobProgressStream;
|
|
124
|
+
/**
|
|
125
|
+
* Track job progress with automatic SSE fallback to polling.
|
|
126
|
+
*
|
|
127
|
+
* Tries SSE first for real-time updates. If SSE fails or is unavailable,
|
|
128
|
+
* gracefully falls back to polling-based tracking.
|
|
129
|
+
*
|
|
130
|
+
* @param baseUrl - API base URL (e.g., http://localhost:8000)
|
|
131
|
+
* @param jobId - Job ID to track
|
|
132
|
+
* @param callbacks - Progress callbacks
|
|
133
|
+
* @param useSSE - Whether to try SSE (default: true)
|
|
134
|
+
* @returns JobProgressStream instance or null if using polling
|
|
135
|
+
*/
|
|
136
|
+
async function trackJobProgress(baseUrl, jobId, callbacks, useSSE = true) {
|
|
137
|
+
if (!useSSE) {
|
|
138
|
+
// Explicitly disabled - use polling fallback
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
// Try SSE first
|
|
143
|
+
const stream = new JobProgressStream(baseUrl, jobId, callbacks);
|
|
144
|
+
stream.start();
|
|
145
|
+
return stream;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
// SSE failed - fall back to polling
|
|
149
|
+
console.warn('SSE streaming unavailable, falling back to polling:', error);
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=job-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-stream.js","sourceRoot":"","sources":["../../src/lib/job-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP File Access Allowlist Manager
|
|
3
|
+
*
|
|
4
|
+
* ADR-062: MCP File Ingestion Security Model
|
|
5
|
+
*
|
|
6
|
+
* Manages path allowlist for secure file/directory ingestion from MCP server.
|
|
7
|
+
* Agent-readable but not agent-writable (CLI-only configuration).
|
|
8
|
+
*
|
|
9
|
+
* Security Model:
|
|
10
|
+
* - Fail-secure validation (blocked patterns checked first)
|
|
11
|
+
* - Explicit allowlist (no access without configuration)
|
|
12
|
+
* - Path resolution prevents traversal attacks (../../../)
|
|
13
|
+
* - Size/count limits prevent resource exhaustion
|
|
14
|
+
*/
|
|
15
|
+
export interface AllowlistConfig {
|
|
16
|
+
version: string;
|
|
17
|
+
allowed_directories: string[];
|
|
18
|
+
allowed_patterns: string[];
|
|
19
|
+
blocked_patterns: string[];
|
|
20
|
+
max_file_size_mb: number;
|
|
21
|
+
max_files_per_directory: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ValidationResult {
|
|
24
|
+
allowed: boolean;
|
|
25
|
+
reason?: string;
|
|
26
|
+
hint?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class McpAllowlistManager {
|
|
29
|
+
private configDir;
|
|
30
|
+
private allowlistPath;
|
|
31
|
+
private config;
|
|
32
|
+
constructor();
|
|
33
|
+
/**
|
|
34
|
+
* Get allowlist file path
|
|
35
|
+
*/
|
|
36
|
+
getAllowlistPath(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Load allowlist from disk
|
|
39
|
+
*/
|
|
40
|
+
private load;
|
|
41
|
+
/**
|
|
42
|
+
* Get default allowlist configuration
|
|
43
|
+
*/
|
|
44
|
+
getDefaultConfig(): AllowlistConfig;
|
|
45
|
+
/**
|
|
46
|
+
* Initialize allowlist with default configuration
|
|
47
|
+
*/
|
|
48
|
+
initialize(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Get current allowlist configuration
|
|
51
|
+
*/
|
|
52
|
+
getConfig(): AllowlistConfig | null;
|
|
53
|
+
/**
|
|
54
|
+
* Save allowlist configuration to disk
|
|
55
|
+
*/
|
|
56
|
+
private save;
|
|
57
|
+
/**
|
|
58
|
+
* Add allowed directory
|
|
59
|
+
*/
|
|
60
|
+
addAllowedDirectory(dir: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Remove allowed directory
|
|
63
|
+
*/
|
|
64
|
+
removeAllowedDirectory(dir: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* Add allowed file pattern
|
|
67
|
+
*/
|
|
68
|
+
addAllowedPattern(pattern: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Remove allowed file pattern
|
|
71
|
+
*/
|
|
72
|
+
removeAllowedPattern(pattern: string): void;
|
|
73
|
+
/**
|
|
74
|
+
* Add blocked file pattern
|
|
75
|
+
*/
|
|
76
|
+
addBlockedPattern(pattern: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Remove blocked file pattern
|
|
79
|
+
*/
|
|
80
|
+
removeBlockedPattern(pattern: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* Expand tilde in path
|
|
83
|
+
*/
|
|
84
|
+
private expandTilde;
|
|
85
|
+
/**
|
|
86
|
+
* Validate file path against allowlist (ADR-062 fail-secure validation)
|
|
87
|
+
*
|
|
88
|
+
* Security checks (in order):
|
|
89
|
+
* 1. Resolve to absolute path (prevents ../ attacks)
|
|
90
|
+
* 2. Check blocked patterns FIRST (fail-secure)
|
|
91
|
+
* 3. Must match at least one allowed directory
|
|
92
|
+
* 4. Must match at least one allowed file pattern
|
|
93
|
+
* 5. Check file size (if file exists)
|
|
94
|
+
*/
|
|
95
|
+
validatePath(filePath: string): ValidationResult;
|
|
96
|
+
/**
|
|
97
|
+
* Validate directory path
|
|
98
|
+
*/
|
|
99
|
+
validateDirectory(dirPath: string): ValidationResult;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=mcp-allowlist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-allowlist.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAyB;;IAUvC;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,OAAO,CAAC,IAAI;IAaZ;;OAEG;IACH,gBAAgB,IAAI,eAAe;IA+BnC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC;;OAEG;IACH,SAAS,IAAI,eAAe,GAAG,IAAI;IAInC;;OAEG;IACH,OAAO,CAAC,IAAI;IAaZ;;OAEG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IActC;;OAEG;IACH,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAUzC;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAWxC;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAS3C;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAWxC;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAS3C;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;;;;;;;;OASG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAmFhD;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB;CA2BrD"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCP File Access Allowlist Manager
|
|
4
|
+
*
|
|
5
|
+
* ADR-062: MCP File Ingestion Security Model
|
|
6
|
+
*
|
|
7
|
+
* Manages path allowlist for secure file/directory ingestion from MCP server.
|
|
8
|
+
* Agent-readable but not agent-writable (CLI-only configuration).
|
|
9
|
+
*
|
|
10
|
+
* Security Model:
|
|
11
|
+
* - Fail-secure validation (blocked patterns checked first)
|
|
12
|
+
* - Explicit allowlist (no access without configuration)
|
|
13
|
+
* - Path resolution prevents traversal attacks (../../../)
|
|
14
|
+
* - Size/count limits prevent resource exhaustion
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.McpAllowlistManager = void 0;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const os = __importStar(require("os"));
|
|
54
|
+
const minimatch_1 = require("minimatch");
|
|
55
|
+
class McpAllowlistManager {
|
|
56
|
+
constructor() {
|
|
57
|
+
// Use XDG config directory (~/.config/kg/)
|
|
58
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
59
|
+
this.configDir = path.join(xdgConfig, 'kg');
|
|
60
|
+
this.allowlistPath = path.join(this.configDir, 'mcp-allowed-paths.json');
|
|
61
|
+
this.config = this.load();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get allowlist file path
|
|
65
|
+
*/
|
|
66
|
+
getAllowlistPath() {
|
|
67
|
+
return this.allowlistPath;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Load allowlist from disk
|
|
71
|
+
*/
|
|
72
|
+
load() {
|
|
73
|
+
try {
|
|
74
|
+
if (fs.existsSync(this.allowlistPath)) {
|
|
75
|
+
const data = fs.readFileSync(this.allowlistPath, 'utf-8');
|
|
76
|
+
return JSON.parse(data);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.warn(`Warning: Failed to load allowlist from ${this.allowlistPath}:`, error);
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get default allowlist configuration
|
|
86
|
+
*/
|
|
87
|
+
getDefaultConfig() {
|
|
88
|
+
return {
|
|
89
|
+
version: '1.0',
|
|
90
|
+
allowed_directories: [],
|
|
91
|
+
allowed_patterns: [
|
|
92
|
+
'**/*.md',
|
|
93
|
+
'**/*.txt',
|
|
94
|
+
'**/*.pdf',
|
|
95
|
+
'**/*.png',
|
|
96
|
+
'**/*.jpg',
|
|
97
|
+
'**/*.jpeg',
|
|
98
|
+
],
|
|
99
|
+
blocked_patterns: [
|
|
100
|
+
'**/.env',
|
|
101
|
+
'**/.env.*',
|
|
102
|
+
'**/.git/**',
|
|
103
|
+
'**/node_modules/**',
|
|
104
|
+
'**/.ssh/**',
|
|
105
|
+
'**/*_history',
|
|
106
|
+
'**/*.key',
|
|
107
|
+
'**/*.pem',
|
|
108
|
+
'**/id_rsa',
|
|
109
|
+
'**/id_rsa.pub',
|
|
110
|
+
'**/id_ed25519',
|
|
111
|
+
'**/id_ed25519.pub',
|
|
112
|
+
],
|
|
113
|
+
max_file_size_mb: 10,
|
|
114
|
+
max_files_per_directory: 1000,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Initialize allowlist with default configuration
|
|
119
|
+
*/
|
|
120
|
+
async initialize() {
|
|
121
|
+
// Ensure config directory exists
|
|
122
|
+
if (!fs.existsSync(this.configDir)) {
|
|
123
|
+
fs.mkdirSync(this.configDir, { recursive: true });
|
|
124
|
+
}
|
|
125
|
+
// Create default allowlist if it doesn't exist
|
|
126
|
+
if (!fs.existsSync(this.allowlistPath)) {
|
|
127
|
+
const defaultConfig = this.getDefaultConfig();
|
|
128
|
+
fs.writeFileSync(this.allowlistPath, JSON.stringify(defaultConfig, null, 2));
|
|
129
|
+
this.config = defaultConfig;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get current allowlist configuration
|
|
134
|
+
*/
|
|
135
|
+
getConfig() {
|
|
136
|
+
return this.config;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Save allowlist configuration to disk
|
|
140
|
+
*/
|
|
141
|
+
save() {
|
|
142
|
+
if (!this.config) {
|
|
143
|
+
throw new Error('No configuration to save');
|
|
144
|
+
}
|
|
145
|
+
// Ensure config directory exists
|
|
146
|
+
if (!fs.existsSync(this.configDir)) {
|
|
147
|
+
fs.mkdirSync(this.configDir, { recursive: true });
|
|
148
|
+
}
|
|
149
|
+
fs.writeFileSync(this.allowlistPath, JSON.stringify(this.config, null, 2));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Add allowed directory
|
|
153
|
+
*/
|
|
154
|
+
addAllowedDirectory(dir) {
|
|
155
|
+
if (!this.config) {
|
|
156
|
+
throw new Error('Allowlist not initialized. Run: kg mcp-config init-allowlist');
|
|
157
|
+
}
|
|
158
|
+
// Expand tilde
|
|
159
|
+
const expandedDir = dir.startsWith('~') ? path.join(os.homedir(), dir.slice(1)) : dir;
|
|
160
|
+
if (!this.config.allowed_directories.includes(expandedDir)) {
|
|
161
|
+
this.config.allowed_directories.push(expandedDir);
|
|
162
|
+
this.save();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Remove allowed directory
|
|
167
|
+
*/
|
|
168
|
+
removeAllowedDirectory(dir) {
|
|
169
|
+
if (!this.config) {
|
|
170
|
+
throw new Error('Allowlist not initialized');
|
|
171
|
+
}
|
|
172
|
+
const expandedDir = dir.startsWith('~') ? path.join(os.homedir(), dir.slice(1)) : dir;
|
|
173
|
+
this.config.allowed_directories = this.config.allowed_directories.filter(d => d !== expandedDir);
|
|
174
|
+
this.save();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Add allowed file pattern
|
|
178
|
+
*/
|
|
179
|
+
addAllowedPattern(pattern) {
|
|
180
|
+
if (!this.config) {
|
|
181
|
+
throw new Error('Allowlist not initialized');
|
|
182
|
+
}
|
|
183
|
+
if (!this.config.allowed_patterns.includes(pattern)) {
|
|
184
|
+
this.config.allowed_patterns.push(pattern);
|
|
185
|
+
this.save();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Remove allowed file pattern
|
|
190
|
+
*/
|
|
191
|
+
removeAllowedPattern(pattern) {
|
|
192
|
+
if (!this.config) {
|
|
193
|
+
throw new Error('Allowlist not initialized');
|
|
194
|
+
}
|
|
195
|
+
this.config.allowed_patterns = this.config.allowed_patterns.filter(p => p !== pattern);
|
|
196
|
+
this.save();
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Add blocked file pattern
|
|
200
|
+
*/
|
|
201
|
+
addBlockedPattern(pattern) {
|
|
202
|
+
if (!this.config) {
|
|
203
|
+
throw new Error('Allowlist not initialized');
|
|
204
|
+
}
|
|
205
|
+
if (!this.config.blocked_patterns.includes(pattern)) {
|
|
206
|
+
this.config.blocked_patterns.push(pattern);
|
|
207
|
+
this.save();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Remove blocked file pattern
|
|
212
|
+
*/
|
|
213
|
+
removeBlockedPattern(pattern) {
|
|
214
|
+
if (!this.config) {
|
|
215
|
+
throw new Error('Allowlist not initialized');
|
|
216
|
+
}
|
|
217
|
+
this.config.blocked_patterns = this.config.blocked_patterns.filter(p => p !== pattern);
|
|
218
|
+
this.save();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Expand tilde in path
|
|
222
|
+
*/
|
|
223
|
+
expandTilde(filePath) {
|
|
224
|
+
if (filePath.startsWith('~/') || filePath === '~') {
|
|
225
|
+
return path.join(os.homedir(), filePath.slice(1));
|
|
226
|
+
}
|
|
227
|
+
return filePath;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Validate file path against allowlist (ADR-062 fail-secure validation)
|
|
231
|
+
*
|
|
232
|
+
* Security checks (in order):
|
|
233
|
+
* 1. Resolve to absolute path (prevents ../ attacks)
|
|
234
|
+
* 2. Check blocked patterns FIRST (fail-secure)
|
|
235
|
+
* 3. Must match at least one allowed directory
|
|
236
|
+
* 4. Must match at least one allowed file pattern
|
|
237
|
+
* 5. Check file size (if file exists)
|
|
238
|
+
*/
|
|
239
|
+
validatePath(filePath) {
|
|
240
|
+
// 0. Require allowlist configuration
|
|
241
|
+
if (!this.config) {
|
|
242
|
+
return {
|
|
243
|
+
allowed: false,
|
|
244
|
+
reason: 'Allowlist not configured',
|
|
245
|
+
hint: 'Run: kg mcp-config init-allowlist',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// 1. Resolve to absolute path (prevents ../../../ attacks)
|
|
249
|
+
const expandedPath = this.expandTilde(filePath);
|
|
250
|
+
const absolutePath = path.resolve(expandedPath);
|
|
251
|
+
// 2. Check blocked patterns FIRST (fail-secure)
|
|
252
|
+
for (const pattern of this.config.blocked_patterns) {
|
|
253
|
+
if ((0, minimatch_1.minimatch)(absolutePath, pattern, { dot: true })) {
|
|
254
|
+
return {
|
|
255
|
+
allowed: false,
|
|
256
|
+
reason: `Matches blocked pattern: ${pattern}`,
|
|
257
|
+
hint: 'This file type is blocked for security',
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// 3. Must match at least one allowed directory
|
|
262
|
+
let matchesAllowedDir = false;
|
|
263
|
+
for (const dir of this.config.allowed_directories) {
|
|
264
|
+
const expandedDir = this.expandTilde(dir);
|
|
265
|
+
// Check if path starts with allowed directory or matches pattern
|
|
266
|
+
if (absolutePath.startsWith(expandedDir) || (0, minimatch_1.minimatch)(absolutePath, expandedDir, { dot: true })) {
|
|
267
|
+
matchesAllowedDir = true;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (!matchesAllowedDir) {
|
|
272
|
+
return {
|
|
273
|
+
allowed: false,
|
|
274
|
+
reason: 'Path not in any allowed directory',
|
|
275
|
+
hint: `Allowed directories: ${this.config.allowed_directories.join(', ')}`,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// 4. Must match at least one allowed file pattern
|
|
279
|
+
let matchesPattern = false;
|
|
280
|
+
for (const pattern of this.config.allowed_patterns) {
|
|
281
|
+
if ((0, minimatch_1.minimatch)(absolutePath, pattern, { dot: true })) {
|
|
282
|
+
matchesPattern = true;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (!matchesPattern) {
|
|
287
|
+
return {
|
|
288
|
+
allowed: false,
|
|
289
|
+
reason: 'File extension not allowed',
|
|
290
|
+
hint: `Allowed patterns: ${this.config.allowed_patterns.join(', ')}`,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
// 5. Check file size (if file exists)
|
|
294
|
+
try {
|
|
295
|
+
if (fs.existsSync(absolutePath)) {
|
|
296
|
+
const stats = fs.statSync(absolutePath);
|
|
297
|
+
const sizeMB = stats.size / (1024 * 1024);
|
|
298
|
+
if (sizeMB > this.config.max_file_size_mb) {
|
|
299
|
+
return {
|
|
300
|
+
allowed: false,
|
|
301
|
+
reason: `File too large: ${sizeMB.toFixed(2)}MB (max: ${this.config.max_file_size_mb}MB)`,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
// File doesn't exist or permission error - allow validation to continue
|
|
308
|
+
// Actual file operations will fail later with appropriate error
|
|
309
|
+
}
|
|
310
|
+
return { allowed: true };
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Validate directory path
|
|
314
|
+
*/
|
|
315
|
+
validateDirectory(dirPath) {
|
|
316
|
+
if (!this.config) {
|
|
317
|
+
return {
|
|
318
|
+
allowed: false,
|
|
319
|
+
reason: 'Allowlist not configured',
|
|
320
|
+
hint: 'Run: kg mcp-config init-allowlist',
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
const expandedPath = this.expandTilde(dirPath);
|
|
324
|
+
const absolutePath = path.resolve(expandedPath);
|
|
325
|
+
// Check if directory path is allowed
|
|
326
|
+
for (const dir of this.config.allowed_directories) {
|
|
327
|
+
const expandedDir = this.expandTilde(dir);
|
|
328
|
+
if (absolutePath.startsWith(expandedDir) || (0, minimatch_1.minimatch)(absolutePath, expandedDir, { dot: true })) {
|
|
329
|
+
return { allowed: true };
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
allowed: false,
|
|
334
|
+
reason: 'Directory not in allowed paths',
|
|
335
|
+
hint: `Allowed directories: ${this.config.allowed_directories.join(', ')}`,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
exports.McpAllowlistManager = McpAllowlistManager;
|
|
340
|
+
//# sourceMappingURL=mcp-allowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-allowlist.js","sourceRoot":"","sources":["../../src/lib/mcp-allowlist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Refactored Jobs List using Table utility with type-based formatting
|
|
3
|
+
*/
|
|
4
|
+
import { Table } from './table';
|
|
5
|
+
import { JobStatus } from '../types';
|
|
6
|
+
export declare function createJobsTable(fullId?: boolean): Table<JobStatus>;
|
|
7
|
+
//# sourceMappingURL=table-example.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-example.d.ts","sourceRoot":"","sources":["../../src/lib/table-example.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,wBAAgB,eAAe,CAAC,MAAM,GAAE,OAAe,oBA0DtD"}
|