git-doc-mcp 0.1.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/LICENSE +21 -0
- package/README.md +543 -0
- package/dist/audit/index.d.ts +2 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +2 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/logger.d.ts +81 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/logger.js +179 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +44 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +360 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/index.d.ts +21 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +71 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/http/client.d.ts +39 -0
- package/dist/http/client.d.ts.map +1 -0
- package/dist/http/client.js +114 -0
- package/dist/http/client.js.map +1 -0
- package/dist/http/index.d.ts +7 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +7 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/redirect-utils.d.ts +27 -0
- package/dist/http/redirect-utils.d.ts.map +1 -0
- package/dist/http/redirect-utils.js +73 -0
- package/dist/http/redirect-utils.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest/index.d.ts +7 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +7 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/loader.d.ts +55 -0
- package/dist/manifest/loader.d.ts.map +1 -0
- package/dist/manifest/loader.js +222 -0
- package/dist/manifest/loader.js.map +1 -0
- package/dist/manifest/schema.d.ts +909 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/manifest/schema.js +148 -0
- package/dist/manifest/schema.js.map +1 -0
- package/dist/rate-limit/index.d.ts +6 -0
- package/dist/rate-limit/index.d.ts.map +1 -0
- package/dist/rate-limit/index.js +6 -0
- package/dist/rate-limit/index.js.map +1 -0
- package/dist/rate-limit/limiter.d.ts +38 -0
- package/dist/rate-limit/limiter.d.ts.map +1 -0
- package/dist/rate-limit/limiter.js +55 -0
- package/dist/rate-limit/limiter.js.map +1 -0
- package/dist/sandbox/context.d.ts +69 -0
- package/dist/sandbox/context.d.ts.map +1 -0
- package/dist/sandbox/context.js +134 -0
- package/dist/sandbox/context.js.map +1 -0
- package/dist/sandbox/executor.d.ts +50 -0
- package/dist/sandbox/executor.d.ts.map +1 -0
- package/dist/sandbox/executor.js +259 -0
- package/dist/sandbox/executor.js.map +1 -0
- package/dist/sandbox/index.d.ts +8 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +8 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/url-validator.d.ts +40 -0
- package/dist/sandbox/url-validator.d.ts.map +1 -0
- package/dist/sandbox/url-validator.js +178 -0
- package/dist/sandbox/url-validator.js.map +1 -0
- package/dist/secrets/index.d.ts +7 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +7 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/manager.d.ts +55 -0
- package/dist/secrets/manager.d.ts.map +1 -0
- package/dist/secrets/manager.js +94 -0
- package/dist/secrets/manager.js.map +1 -0
- package/dist/secrets/patterns.d.ts +33 -0
- package/dist/secrets/patterns.d.ts.map +1 -0
- package/dist/secrets/patterns.js +71 -0
- package/dist/secrets/patterns.js.map +1 -0
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +6 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp.d.ts +60 -0
- package/dist/server/mcp.d.ts.map +1 -0
- package/dist/server/mcp.js +173 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/worker/index.d.ts +7 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +7 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/process.d.ts +64 -0
- package/dist/worker/process.d.ts.map +1 -0
- package/dist/worker/process.js +222 -0
- package/dist/worker/process.js.map +1 -0
- package/dist/worker/protocol.d.ts +83 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +55 -0
- package/dist/worker/protocol.js.map +1 -0
- package/dist/worker/worker-entry.d.ts +30 -0
- package/dist/worker/worker-entry.d.ts.map +1 -0
- package/dist/worker/worker-entry.js +136 -0
- package/dist/worker/worker-entry.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* git-doc-mcp CLI entry point.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx git-doc-mcp --manifest <url-or-path> [options]
|
|
7
|
+
* npx git-doc-mcp serve --manifest <url-or-path> [options]
|
|
8
|
+
*
|
|
9
|
+
* Options:
|
|
10
|
+
* --manifest <path> URL or local path to manifest.yml
|
|
11
|
+
* --manifest-header <header> Header for fetching manifest (can be repeated)
|
|
12
|
+
* --manifest-hash <hash> Expected manifest hash (for pinning)
|
|
13
|
+
* --action-code-header <h> Header for downloading action scripts
|
|
14
|
+
* --secret <name=value> Pre-approved secret (can be repeated)
|
|
15
|
+
* --help Show help
|
|
16
|
+
* --version Show version
|
|
17
|
+
*/
|
|
18
|
+
import { Command } from 'commander';
|
|
19
|
+
import { serveCommand } from './commands/serve.js';
|
|
20
|
+
const program = new Command();
|
|
21
|
+
program
|
|
22
|
+
.name('git-doc-mcp')
|
|
23
|
+
.description('Turn any manifest into an MCP server')
|
|
24
|
+
.version('0.1.0');
|
|
25
|
+
// Top-level options (allow running without 'serve' subcommand)
|
|
26
|
+
program
|
|
27
|
+
.option('--manifest <path>', 'URL or local path to manifest.yml')
|
|
28
|
+
.option('--manifest-header <header>', 'Header for fetching manifest (can be repeated)', collect, [])
|
|
29
|
+
.option('--manifest-hash <hash>', 'Expected manifest hash for pinning')
|
|
30
|
+
.option('--action-code-header <header>', 'Header for downloading action scripts', collect, [])
|
|
31
|
+
.option('--resource-header <header>', 'Header for fetching resources (can be repeated)', collect, [])
|
|
32
|
+
.option('--secret <name=value>', 'Pre-approved secret (can be repeated)', collect, [])
|
|
33
|
+
.option('--timeout <ms>', 'Worker timeout in milliseconds', '60000')
|
|
34
|
+
.option('--memory-limit <bytes>', 'Memory limit for sandbox', '134217728')
|
|
35
|
+
.option('--allow-http', 'Allow insecure HTTP connections (default: HTTPS-only)', false)
|
|
36
|
+
.option('--trust-changed', 'Accept manifest changes on TOFU hash mismatch', false)
|
|
37
|
+
.option('--rate-limit <calls-per-minute>', 'Rate limit for tool calls (0 = unlimited)', '60')
|
|
38
|
+
.action((options) => {
|
|
39
|
+
// If --manifest is provided at top level, run serve directly
|
|
40
|
+
if (options.manifest) {
|
|
41
|
+
return serveCommand(options);
|
|
42
|
+
}
|
|
43
|
+
// Otherwise show help
|
|
44
|
+
program.outputHelp();
|
|
45
|
+
});
|
|
46
|
+
// 'serve' subcommand (explicit)
|
|
47
|
+
program
|
|
48
|
+
.command('serve')
|
|
49
|
+
.description('Start MCP server from a manifest')
|
|
50
|
+
.requiredOption('--manifest <path>', 'URL or local path to manifest.yml')
|
|
51
|
+
.option('--manifest-header <header>', 'Header for fetching manifest (can be repeated)', collect, [])
|
|
52
|
+
.option('--manifest-hash <hash>', 'Expected manifest hash for pinning')
|
|
53
|
+
.option('--action-code-header <header>', 'Header for downloading action scripts', collect, [])
|
|
54
|
+
.option('--resource-header <header>', 'Header for fetching resources (can be repeated)', collect, [])
|
|
55
|
+
.option('--secret <name=value>', 'Pre-approved secret (can be repeated)', collect, [])
|
|
56
|
+
.option('--timeout <ms>', 'Worker timeout in milliseconds', '60000')
|
|
57
|
+
.option('--memory-limit <bytes>', 'Memory limit for sandbox', '134217728')
|
|
58
|
+
.option('--allow-http', 'Allow insecure HTTP connections (default: HTTPS-only)', false)
|
|
59
|
+
.option('--trust-changed', 'Accept manifest changes on TOFU hash mismatch', false)
|
|
60
|
+
.option('--rate-limit <calls-per-minute>', 'Rate limit for tool calls (0 = unlimited)', '60')
|
|
61
|
+
.action(serveCommand);
|
|
62
|
+
/**
|
|
63
|
+
* Collect repeated option values.
|
|
64
|
+
*/
|
|
65
|
+
function collect(value, previous) {
|
|
66
|
+
return [...previous, value];
|
|
67
|
+
}
|
|
68
|
+
// Parse arguments
|
|
69
|
+
program.parse();
|
|
70
|
+
export { program };
|
|
71
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,+DAA+D;AAC/D,OAAO;KACJ,MAAM,CAAC,mBAAmB,EAAE,mCAAmC,CAAC;KAChE,MAAM,CAAC,4BAA4B,EAAE,gDAAgD,EAAE,OAAO,EAAE,EAAE,CAAC;KACnG,MAAM,CAAC,wBAAwB,EAAE,oCAAoC,CAAC;KACtE,MAAM,CAAC,+BAA+B,EAAE,uCAAuC,EAAE,OAAO,EAAE,EAAE,CAAC;KAC7F,MAAM,CAAC,4BAA4B,EAAE,iDAAiD,EAAE,OAAO,EAAE,EAAE,CAAC;KACpG,MAAM,CAAC,uBAAuB,EAAE,uCAAuC,EAAE,OAAO,EAAE,EAAE,CAAC;KACrF,MAAM,CAAC,gBAAgB,EAAE,gCAAgC,EAAE,OAAO,CAAC;KACnE,MAAM,CAAC,wBAAwB,EAAE,0BAA0B,EAAE,WAAW,CAAC;KACzE,MAAM,CAAC,cAAc,EAAE,uDAAuD,EAAE,KAAK,CAAC;KACtF,MAAM,CAAC,iBAAiB,EAAE,+CAA+C,EAAE,KAAK,CAAC;KACjF,MAAM,CAAC,iCAAiC,EAAE,2CAA2C,EAAE,IAAI,CAAC;KAC5F,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,6DAA6D;IAC7D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,sBAAsB;IACtB,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,gCAAgC;AAChC,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,cAAc,CAAC,mBAAmB,EAAE,mCAAmC,CAAC;KACxE,MAAM,CAAC,4BAA4B,EAAE,gDAAgD,EAAE,OAAO,EAAE,EAAE,CAAC;KACnG,MAAM,CAAC,wBAAwB,EAAE,oCAAoC,CAAC;KACtE,MAAM,CAAC,+BAA+B,EAAE,uCAAuC,EAAE,OAAO,EAAE,EAAE,CAAC;KAC7F,MAAM,CAAC,4BAA4B,EAAE,iDAAiD,EAAE,OAAO,EAAE,EAAE,CAAC;KACpG,MAAM,CAAC,uBAAuB,EAAE,uCAAuC,EAAE,OAAO,EAAE,EAAE,CAAC;KACrF,MAAM,CAAC,gBAAgB,EAAE,gCAAgC,EAAE,OAAO,CAAC;KACnE,MAAM,CAAC,wBAAwB,EAAE,0BAA0B,EAAE,WAAW,CAAC;KACzE,MAAM,CAAC,cAAc,EAAE,uDAAuD,EAAE,KAAK,CAAC;KACtF,MAAM,CAAC,iBAAiB,EAAE,+CAA+C,EAAE,KAAK,CAAC;KACjF,MAAM,CAAC,iCAAiC,EAAE,2CAA2C,EAAE,IAAI,CAAC;KAC5F,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB;;GAEG;AACH,SAAS,OAAO,CAAC,KAAa,EAAE,QAAkB;IAChD,OAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,kBAAkB;AAClB,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for fetching action scripts.
|
|
3
|
+
* @module http/client
|
|
4
|
+
*/
|
|
5
|
+
import type { AuditLogger } from '../audit/logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* HTTP client options.
|
|
8
|
+
*/
|
|
9
|
+
export interface HttpClientOptions {
|
|
10
|
+
/** Headers for requests */
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
/** Timeout in ms */
|
|
13
|
+
timeout?: number;
|
|
14
|
+
/** Maximum response size in bytes */
|
|
15
|
+
maxSize?: number;
|
|
16
|
+
/** Optional audit logger for structured error event logging */
|
|
17
|
+
auditLogger?: AuditLogger;
|
|
18
|
+
/** Allow HTTP URLs (default: false, HTTPS-only) */
|
|
19
|
+
allowHttp?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fetch result.
|
|
23
|
+
*/
|
|
24
|
+
export interface FetchResult {
|
|
25
|
+
content: string;
|
|
26
|
+
hash: string;
|
|
27
|
+
etag?: string;
|
|
28
|
+
lastModified?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fetch content from URL with SSRF protection.
|
|
32
|
+
*/
|
|
33
|
+
export declare function fetchContent(url: string, options?: HttpClientOptions): Promise<FetchResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Verify content hash.
|
|
36
|
+
* @throws Error if hash doesn't match
|
|
37
|
+
*/
|
|
38
|
+
export declare function verifyHash(content: string, expectedHash: string): void;
|
|
39
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAWD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAOD;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,WAAW,CAAC,CAoGtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAQtE"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for fetching action scripts.
|
|
3
|
+
* @module http/client
|
|
4
|
+
*/
|
|
5
|
+
import * as crypto from 'node:crypto';
|
|
6
|
+
import { validateUrl, validateRedirect } from '../sandbox/url-validator.js';
|
|
7
|
+
import { stripCrossOriginHeaders } from './redirect-utils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Default HTTP client options.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_OPTIONS = {
|
|
12
|
+
headers: {},
|
|
13
|
+
timeout: 30000,
|
|
14
|
+
maxSize: 500 * 1024, // 500KB for action scripts
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Maximum number of redirects to follow when fetching action scripts.
|
|
18
|
+
*/
|
|
19
|
+
const MAX_REDIRECTS = 5;
|
|
20
|
+
/**
|
|
21
|
+
* Fetch content from URL with SSRF protection.
|
|
22
|
+
*/
|
|
23
|
+
export async function fetchContent(url, options = {}) {
|
|
24
|
+
const { auditLogger, allowHttp = false, ...rest } = options;
|
|
25
|
+
const opts = { ...DEFAULT_OPTIONS, ...rest };
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timeoutId = setTimeout(() => controller.abort(), opts.timeout);
|
|
28
|
+
const allowedSchemes = allowHttp ? ['https', 'http'] : ['https'];
|
|
29
|
+
const validationOptions = { allowedSchemes };
|
|
30
|
+
try {
|
|
31
|
+
// Validate the initial URL against SSRF before fetching
|
|
32
|
+
await validateUrl(url, validationOptions);
|
|
33
|
+
let currentUrl = url;
|
|
34
|
+
let redirectCount = 0;
|
|
35
|
+
let currentHeaders = { ...opts.headers };
|
|
36
|
+
let response = await fetch(currentUrl, {
|
|
37
|
+
method: 'GET',
|
|
38
|
+
headers: {
|
|
39
|
+
'Accept': 'application/javascript, text/javascript, */*',
|
|
40
|
+
...currentHeaders,
|
|
41
|
+
},
|
|
42
|
+
signal: controller.signal,
|
|
43
|
+
redirect: 'manual',
|
|
44
|
+
});
|
|
45
|
+
while (response.status >= 300 && response.status < 400) {
|
|
46
|
+
const location = response.headers.get('location');
|
|
47
|
+
if (!location) {
|
|
48
|
+
auditLogger?.logError('Redirect without location header', { url: currentUrl, status: response.status });
|
|
49
|
+
throw new Error(`Redirect response ${response.status} missing Location header`);
|
|
50
|
+
}
|
|
51
|
+
redirectCount++;
|
|
52
|
+
if (redirectCount > MAX_REDIRECTS) {
|
|
53
|
+
auditLogger?.logError('Too many redirects fetching action', { url, maxRedirects: MAX_REDIRECTS });
|
|
54
|
+
throw new Error(`Too many redirects (max ${MAX_REDIRECTS}) fetching action from ${url}`);
|
|
55
|
+
}
|
|
56
|
+
// Resolve relative redirect URLs
|
|
57
|
+
const redirectTarget = new URL(location, currentUrl).href;
|
|
58
|
+
// Validate the redirect target for SSRF
|
|
59
|
+
await validateRedirect(redirectTarget, url, validationOptions);
|
|
60
|
+
// Strip sensitive headers on cross-origin redirect
|
|
61
|
+
currentHeaders = stripCrossOriginHeaders(currentHeaders, currentUrl, redirectTarget);
|
|
62
|
+
currentUrl = redirectTarget;
|
|
63
|
+
response = await fetch(currentUrl, {
|
|
64
|
+
method: 'GET',
|
|
65
|
+
headers: {
|
|
66
|
+
'Accept': 'application/javascript, text/javascript, */*',
|
|
67
|
+
...currentHeaders,
|
|
68
|
+
},
|
|
69
|
+
signal: controller.signal,
|
|
70
|
+
redirect: 'manual',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
auditLogger?.logError('Action fetch failed', { url: currentUrl, status: response.status });
|
|
75
|
+
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
76
|
+
}
|
|
77
|
+
// Check size
|
|
78
|
+
const contentLength = response.headers.get('content-length');
|
|
79
|
+
if (contentLength && parseInt(contentLength, 10) > opts.maxSize) {
|
|
80
|
+
auditLogger?.logError('Action content too large', { url: currentUrl, contentLength: parseInt(contentLength, 10), maxSize: opts.maxSize });
|
|
81
|
+
throw new Error(`Content too large: ${contentLength} bytes (max: ${opts.maxSize})`);
|
|
82
|
+
}
|
|
83
|
+
const content = await response.text();
|
|
84
|
+
// Check actual size
|
|
85
|
+
if (content.length > opts.maxSize) {
|
|
86
|
+
auditLogger?.logError('Action body too large', { url: currentUrl, actualSize: content.length, maxSize: opts.maxSize });
|
|
87
|
+
throw new Error(`Content too large: ${content.length} bytes (max: ${opts.maxSize})`);
|
|
88
|
+
}
|
|
89
|
+
// Compute hash
|
|
90
|
+
const hash = 'sha256:' + crypto.createHash('sha256').update(content).digest('hex');
|
|
91
|
+
const etag = response.headers.get('etag');
|
|
92
|
+
const lastModified = response.headers.get('last-modified');
|
|
93
|
+
return {
|
|
94
|
+
content,
|
|
95
|
+
hash,
|
|
96
|
+
...(etag ? { etag } : {}),
|
|
97
|
+
...(lastModified ? { lastModified } : {}),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
clearTimeout(timeoutId);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Verify content hash.
|
|
106
|
+
* @throws Error if hash doesn't match
|
|
107
|
+
*/
|
|
108
|
+
export function verifyHash(content, expectedHash) {
|
|
109
|
+
const actualHash = 'sha256:' + crypto.createHash('sha256').update(content).digest('hex');
|
|
110
|
+
if (actualHash !== expectedHash) {
|
|
111
|
+
throw new Error(`Hash mismatch: expected ${expectedHash}, got ${actualHash}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redirect utilities for cross-origin header stripping.
|
|
3
|
+
* @module http/redirect-utils
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Accepted header input formats (equivalent to the Fetch API HeadersInit type).
|
|
7
|
+
* Covers all forms accepted by the Headers constructor:
|
|
8
|
+
* - Plain object (string values or readonly string arrays)
|
|
9
|
+
* - Array of [key, value] pairs
|
|
10
|
+
* - Headers instance
|
|
11
|
+
*/
|
|
12
|
+
type HeadersInput = Record<string, string | ReadonlyArray<string>> | string[][] | Headers;
|
|
13
|
+
/**
|
|
14
|
+
* Strip sensitive headers when a redirect crosses origins.
|
|
15
|
+
*
|
|
16
|
+
* Per RFC 9110 and browser security best practices, credentials
|
|
17
|
+
* (Authorization, Cookie, Proxy-Authorization) must not follow
|
|
18
|
+
* redirects to a different origin (scheme + host + port).
|
|
19
|
+
*
|
|
20
|
+
* @param headers - Current request headers
|
|
21
|
+
* @param originalUrl - URL of the request that triggered the redirect
|
|
22
|
+
* @param redirectUrl - URL the redirect points to
|
|
23
|
+
* @returns Headers with sensitive entries removed if cross-origin, or unchanged if same-origin
|
|
24
|
+
*/
|
|
25
|
+
export declare function stripCrossOriginHeaders(headers: HeadersInput, originalUrl: string, redirectUrl: string): Record<string, string>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=redirect-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirect-utils.d.ts","sourceRoot":"","sources":["../../src/http/redirect-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AACH,KAAK,YAAY,GACb,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAC9C,MAAM,EAAE,EAAE,GACV,OAAO,CAAC;AA2CZ;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBxB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redirect utilities for cross-origin header stripping.
|
|
3
|
+
* @module http/redirect-utils
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Headers that MUST be stripped on cross-origin redirects.
|
|
7
|
+
* These contain credentials that should not leak to untrusted origins.
|
|
8
|
+
* Matching is case-insensitive (see stripCrossOriginHeaders).
|
|
9
|
+
*/
|
|
10
|
+
const SENSITIVE_HEADERS = ['authorization', 'cookie', 'proxy-authorization'];
|
|
11
|
+
/**
|
|
12
|
+
* Normalize HeadersInput to a plain Record<string, string>.
|
|
13
|
+
* Handles Headers instances, [key, value] tuples, and plain objects.
|
|
14
|
+
*/
|
|
15
|
+
function normalizeHeaders(headers) {
|
|
16
|
+
if (headers instanceof Headers) {
|
|
17
|
+
const result = {};
|
|
18
|
+
headers.forEach((value, key) => { result[key] = value; });
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(headers)) {
|
|
22
|
+
const result = {};
|
|
23
|
+
for (const pair of headers) {
|
|
24
|
+
const key = pair[0];
|
|
25
|
+
const value = pair[1];
|
|
26
|
+
if (key !== undefined && value !== undefined) {
|
|
27
|
+
result[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
// Plain object: may have string or ReadonlyArray<string> values
|
|
33
|
+
const result = {};
|
|
34
|
+
for (const [key, val] of Object.entries(headers)) {
|
|
35
|
+
if (typeof val === 'string') {
|
|
36
|
+
result[key] = val;
|
|
37
|
+
}
|
|
38
|
+
else if (Array.isArray(val) && val.length > 0) {
|
|
39
|
+
// For multi-value headers, join with comma (per HTTP spec)
|
|
40
|
+
result[key] = val.join(', ');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Strip sensitive headers when a redirect crosses origins.
|
|
47
|
+
*
|
|
48
|
+
* Per RFC 9110 and browser security best practices, credentials
|
|
49
|
+
* (Authorization, Cookie, Proxy-Authorization) must not follow
|
|
50
|
+
* redirects to a different origin (scheme + host + port).
|
|
51
|
+
*
|
|
52
|
+
* @param headers - Current request headers
|
|
53
|
+
* @param originalUrl - URL of the request that triggered the redirect
|
|
54
|
+
* @param redirectUrl - URL the redirect points to
|
|
55
|
+
* @returns Headers with sensitive entries removed if cross-origin, or unchanged if same-origin
|
|
56
|
+
*/
|
|
57
|
+
export function stripCrossOriginHeaders(headers, originalUrl, redirectUrl) {
|
|
58
|
+
const normalized = normalizeHeaders(headers);
|
|
59
|
+
const originalOrigin = new URL(originalUrl).origin;
|
|
60
|
+
const redirectOrigin = new URL(redirectUrl).origin;
|
|
61
|
+
if (originalOrigin === redirectOrigin) {
|
|
62
|
+
return normalized;
|
|
63
|
+
}
|
|
64
|
+
// Cross-origin: strip sensitive headers (case-insensitive)
|
|
65
|
+
const stripped = {};
|
|
66
|
+
for (const [key, value] of Object.entries(normalized)) {
|
|
67
|
+
if (!SENSITIVE_HEADERS.includes(key.toLowerCase())) {
|
|
68
|
+
stripped[key] = value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return stripped;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=redirect-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirect-utils.js","sourceRoot":"","sources":["../../src/http/redirect-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,CAAC,eAAe,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAC;AAE7E;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAqB;IAC7C,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;QAC/B,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACtB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,gEAAgE;IAChE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACpB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,2DAA2D;YAC3D,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAqB,EACrB,WAAmB,EACnB,WAAmB;IAEnB,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;IACnD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;IAEnD,IAAI,cAAc,KAAK,cAAc,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,2DAA2D;IAC3D,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACnD,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @git-doc-mcp/core - Core library for git-doc-mcp
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Manifest loading and validation
|
|
6
|
+
* - Sandbox execution with isolated-vm
|
|
7
|
+
* - Worker process management
|
|
8
|
+
* - Secret scoping and approval
|
|
9
|
+
* - MCP server setup
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { loadManifest, createMcpServer, startMcpServer } from '@git-doc-mcp/core';
|
|
14
|
+
*
|
|
15
|
+
* const result = await loadManifest({ manifestPath: './manifest.yml' });
|
|
16
|
+
* const server = createMcpServer({
|
|
17
|
+
* manifest: result.manifest,
|
|
18
|
+
* onToolCall: async (name, input) => {
|
|
19
|
+
* // Execute tool
|
|
20
|
+
* return { content: [{ type: 'text', text: 'result' }] };
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
* await startMcpServer(server);
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module @git-doc-mcp/core
|
|
27
|
+
*/
|
|
28
|
+
export * from './manifest/index.js';
|
|
29
|
+
export * from './secrets/index.js';
|
|
30
|
+
export * from './sandbox/index.js';
|
|
31
|
+
export * from './worker/index.js';
|
|
32
|
+
export * from './server/index.js';
|
|
33
|
+
export * from './http/index.js';
|
|
34
|
+
export * from './audit/index.js';
|
|
35
|
+
export * from './rate-limit/index.js';
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @git-doc-mcp/core - Core library for git-doc-mcp
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Manifest loading and validation
|
|
6
|
+
* - Sandbox execution with isolated-vm
|
|
7
|
+
* - Worker process management
|
|
8
|
+
* - Secret scoping and approval
|
|
9
|
+
* - MCP server setup
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { loadManifest, createMcpServer, startMcpServer } from '@git-doc-mcp/core';
|
|
14
|
+
*
|
|
15
|
+
* const result = await loadManifest({ manifestPath: './manifest.yml' });
|
|
16
|
+
* const server = createMcpServer({
|
|
17
|
+
* manifest: result.manifest,
|
|
18
|
+
* onToolCall: async (name, input) => {
|
|
19
|
+
* // Execute tool
|
|
20
|
+
* return { content: [{ type: 'text', text: 'result' }] };
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
* await startMcpServer(server);
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module @git-doc-mcp/core
|
|
27
|
+
*/
|
|
28
|
+
// Manifest
|
|
29
|
+
export * from './manifest/index.js';
|
|
30
|
+
// Secrets
|
|
31
|
+
export * from './secrets/index.js';
|
|
32
|
+
// Sandbox
|
|
33
|
+
export * from './sandbox/index.js';
|
|
34
|
+
// Worker
|
|
35
|
+
export * from './worker/index.js';
|
|
36
|
+
// Server
|
|
37
|
+
export * from './server/index.js';
|
|
38
|
+
// HTTP
|
|
39
|
+
export * from './http/index.js';
|
|
40
|
+
// Audit
|
|
41
|
+
export * from './audit/index.js';
|
|
42
|
+
// Rate limiting
|
|
43
|
+
export * from './rate-limit/index.js';
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,WAAW;AACX,cAAc,qBAAqB,CAAC;AAEpC,UAAU;AACV,cAAc,oBAAoB,CAAC;AAEnC,UAAU;AACV,cAAc,oBAAoB,CAAC;AAEnC,SAAS;AACT,cAAc,mBAAmB,CAAC;AAElC,SAAS;AACT,cAAc,mBAAmB,CAAC;AAElC,OAAO;AACP,cAAc,iBAAiB,CAAC;AAEhC,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,gBAAgB;AAChB,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest loader - fetches manifest from URL or local file.
|
|
3
|
+
* @module manifest/loader
|
|
4
|
+
*/
|
|
5
|
+
import { Manifest } from './schema.js';
|
|
6
|
+
import type { AuditLogger } from '../audit/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Manifest loader options.
|
|
9
|
+
*/
|
|
10
|
+
export interface ManifestLoaderOptions {
|
|
11
|
+
/** URL or file path to manifest.yml */
|
|
12
|
+
manifestPath: string;
|
|
13
|
+
/** Headers for HTTP requests (for private manifests) */
|
|
14
|
+
headers?: Record<string, string>;
|
|
15
|
+
/** Timeout for HTTP requests in ms */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
/** Optional audit logger for structured error event logging */
|
|
18
|
+
auditLogger?: AuditLogger;
|
|
19
|
+
/** Allow HTTP URLs (default: false, HTTPS-only) */
|
|
20
|
+
allowHttp?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Manifest load result.
|
|
24
|
+
*/
|
|
25
|
+
export interface ManifestLoadResult {
|
|
26
|
+
manifest: Manifest;
|
|
27
|
+
/** SHA-256 hash of manifest content */
|
|
28
|
+
hash: string;
|
|
29
|
+
/** ETag from HTTP response (if applicable) */
|
|
30
|
+
etag?: string;
|
|
31
|
+
/** Last-Modified from HTTP response (if applicable) */
|
|
32
|
+
lastModified?: string;
|
|
33
|
+
/** Source URL or file path */
|
|
34
|
+
source: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if path is a URL.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isUrl(path: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Compute SHA-256 hash of content.
|
|
42
|
+
*/
|
|
43
|
+
export declare function computeHash(content: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Load manifest from URL or local file.
|
|
46
|
+
*/
|
|
47
|
+
export declare function loadManifest(options: ManifestLoaderOptions): Promise<ManifestLoadResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Check if manifest has changed using ETag.
|
|
50
|
+
*/
|
|
51
|
+
export declare function checkManifestUpdate(url: string, etag: string, headers?: Record<string, string>, timeout?: number, allowHttp?: boolean): Promise<{
|
|
52
|
+
changed: boolean;
|
|
53
|
+
result?: ManifestLoadResult;
|
|
54
|
+
}>;
|
|
55
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/manifest/loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,QAAQ,EAAiB,MAAM,aAAa,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAa9F;AAyID;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACpC,OAAO,SAAQ,EACf,SAAS,UAAQ,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAiF5D"}
|