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 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/manifest/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for git-doc-mcp manifest files.
|
|
3
|
+
* @module manifest/schema
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
/**
|
|
7
|
+
* Schema version for future compatibility.
|
|
8
|
+
*/
|
|
9
|
+
export const SchemaVersionSchema = z.string().regex(/^\d+\.\d+$/);
|
|
10
|
+
/**
|
|
11
|
+
* Secret scope pattern for URL validation.
|
|
12
|
+
* Examples: "https://api.github.com/*", "https://raw.githubusercontent.com"
|
|
13
|
+
*/
|
|
14
|
+
export const SecretScopeSchema = z.string().min(1);
|
|
15
|
+
/**
|
|
16
|
+
* Secret declaration in a manifest.
|
|
17
|
+
*/
|
|
18
|
+
export const SecretSchema = z.object({
|
|
19
|
+
name: z.string().min(1),
|
|
20
|
+
description: z.string().optional(),
|
|
21
|
+
scope: z.union([
|
|
22
|
+
SecretScopeSchema,
|
|
23
|
+
z.array(SecretScopeSchema).min(1),
|
|
24
|
+
]),
|
|
25
|
+
required: z.boolean().default(false),
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Tool annotation hints for MCP clients.
|
|
29
|
+
*/
|
|
30
|
+
export const ToolAnnotationsSchema = z.object({
|
|
31
|
+
title: z.string().optional(),
|
|
32
|
+
readOnlyHint: z.boolean().default(false),
|
|
33
|
+
destructiveHint: z.boolean().default(false),
|
|
34
|
+
idempotentHint: z.boolean().default(false),
|
|
35
|
+
openWorldHint: z.boolean().default(false),
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* JSON Schema for tool input validation.
|
|
39
|
+
*/
|
|
40
|
+
export const InputSchemaSchema = z.object({
|
|
41
|
+
type: z.literal('object'),
|
|
42
|
+
properties: z.record(z.unknown()),
|
|
43
|
+
required: z.array(z.string()).optional(),
|
|
44
|
+
additionalProperties: z.boolean().optional(),
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Tool definition in a manifest.
|
|
48
|
+
*/
|
|
49
|
+
export const ToolSchema = z.object({
|
|
50
|
+
name: z.string().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/),
|
|
51
|
+
title: z.string().optional(),
|
|
52
|
+
description: z.string().min(1),
|
|
53
|
+
inputSchema: InputSchemaSchema,
|
|
54
|
+
action: z.string().url(),
|
|
55
|
+
actionHash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
56
|
+
annotations: ToolAnnotationsSchema.optional(),
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Resource definition in a manifest.
|
|
60
|
+
*/
|
|
61
|
+
export const ResourceSchema = z.object({
|
|
62
|
+
name: z.string().min(1),
|
|
63
|
+
uri: z.string().url(),
|
|
64
|
+
description: z.string().optional(),
|
|
65
|
+
mimeType: z.string().optional(),
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* Prompt argument definition.
|
|
69
|
+
*/
|
|
70
|
+
export const PromptArgSchema = z.object({
|
|
71
|
+
name: z.string().min(1),
|
|
72
|
+
description: z.string().optional(),
|
|
73
|
+
required: z.boolean().default(false),
|
|
74
|
+
});
|
|
75
|
+
/**
|
|
76
|
+
* Text content in a prompt message (MCP TextContent).
|
|
77
|
+
*/
|
|
78
|
+
export const PromptTextContentSchema = z.object({
|
|
79
|
+
type: z.literal('text'),
|
|
80
|
+
text: z.string().min(1),
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* Embedded resource content in a prompt message (MCP EmbeddedResource).
|
|
84
|
+
*/
|
|
85
|
+
export const PromptResourceContentSchema = z.object({
|
|
86
|
+
type: z.literal('resource'),
|
|
87
|
+
resource: z.object({
|
|
88
|
+
uri: z.string().min(1),
|
|
89
|
+
text: z.string().optional(),
|
|
90
|
+
mimeType: z.string().optional(),
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* Content block in a prompt message.
|
|
95
|
+
* Matches MCP ContentBlock subset relevant for declarative prompts.
|
|
96
|
+
*/
|
|
97
|
+
export const PromptContentSchema = z.discriminatedUnion('type', [
|
|
98
|
+
PromptTextContentSchema,
|
|
99
|
+
PromptResourceContentSchema,
|
|
100
|
+
]);
|
|
101
|
+
/**
|
|
102
|
+
* A message in a prompt template (MCP PromptMessage).
|
|
103
|
+
*/
|
|
104
|
+
export const PromptMessageSchema = z.object({
|
|
105
|
+
role: z.enum(['user', 'assistant']),
|
|
106
|
+
content: PromptContentSchema,
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* Prompt definition in a manifest.
|
|
110
|
+
*
|
|
111
|
+
* When `messages` is provided, they are returned directly (with {{arg}} substitution).
|
|
112
|
+
* When omitted, a single user message is built from `description` + args.
|
|
113
|
+
*/
|
|
114
|
+
export const PromptSchema = z.object({
|
|
115
|
+
name: z.string().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/),
|
|
116
|
+
title: z.string().optional(),
|
|
117
|
+
description: z.string().min(1),
|
|
118
|
+
args: z.array(PromptArgSchema).optional(),
|
|
119
|
+
messages: z.array(PromptMessageSchema).min(1).optional(),
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Complete manifest schema.
|
|
123
|
+
*/
|
|
124
|
+
export const ManifestSchema = z.object({
|
|
125
|
+
schemaVersion: SchemaVersionSchema,
|
|
126
|
+
name: z.string().min(1).max(64),
|
|
127
|
+
version: z.string().regex(/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/),
|
|
128
|
+
description: z.string().optional(),
|
|
129
|
+
instructions: z.string().optional(),
|
|
130
|
+
secrets: z.array(SecretSchema).optional(),
|
|
131
|
+
tools: z.array(ToolSchema).min(1),
|
|
132
|
+
resources: z.array(ResourceSchema).optional(),
|
|
133
|
+
prompts: z.array(PromptSchema).optional(),
|
|
134
|
+
});
|
|
135
|
+
/**
|
|
136
|
+
* Parse and validate a manifest from YAML content.
|
|
137
|
+
*/
|
|
138
|
+
export function parseManifest(yamlContent, parseYaml) {
|
|
139
|
+
const raw = parseYaml(yamlContent);
|
|
140
|
+
return ManifestSchema.parse(raw);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Validate a manifest object.
|
|
144
|
+
*/
|
|
145
|
+
export function validateManifest(manifest) {
|
|
146
|
+
return ManifestSchema.parse(manifest);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/manifest/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rate-limit/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rate-limit/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sliding-window rate limiter.
|
|
3
|
+
* @module rate-limit/limiter
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A simple sliding-window rate limiter.
|
|
7
|
+
*
|
|
8
|
+
* Tracks call timestamps in an array and prunes entries
|
|
9
|
+
* outside the sliding window on each acquire attempt.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const limiter = new RateLimiter(60, 60_000); // 60 calls per minute
|
|
14
|
+
* if (!limiter.tryAcquire()) {
|
|
15
|
+
* // Rate limited
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare class RateLimiter {
|
|
20
|
+
private readonly maxCalls;
|
|
21
|
+
private readonly windowMs;
|
|
22
|
+
private timestamps;
|
|
23
|
+
/**
|
|
24
|
+
* @param maxCalls - Maximum number of calls allowed in the window
|
|
25
|
+
* @param windowMs - Window size in milliseconds
|
|
26
|
+
*/
|
|
27
|
+
constructor(maxCalls?: number, windowMs?: number);
|
|
28
|
+
/**
|
|
29
|
+
* Try to acquire a rate limit slot.
|
|
30
|
+
* @returns true if the call is allowed, false if rate limited
|
|
31
|
+
*/
|
|
32
|
+
tryAcquire(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get the current number of calls in the window.
|
|
35
|
+
*/
|
|
36
|
+
get currentCount(): number;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limiter.d.ts","sourceRoot":"","sources":["../../src/rate-limit/limiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,UAAU,CAAgB;IAElC;;;OAGG;gBAEgB,QAAQ,GAAE,MAAW,EACrB,QAAQ,GAAE,MAAe;IAG5C;;;OAGG;IACH,UAAU,IAAI,OAAO;IAerB;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAIzB;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sliding-window rate limiter.
|
|
3
|
+
* @module rate-limit/limiter
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A simple sliding-window rate limiter.
|
|
7
|
+
*
|
|
8
|
+
* Tracks call timestamps in an array and prunes entries
|
|
9
|
+
* outside the sliding window on each acquire attempt.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const limiter = new RateLimiter(60, 60_000); // 60 calls per minute
|
|
14
|
+
* if (!limiter.tryAcquire()) {
|
|
15
|
+
* // Rate limited
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class RateLimiter {
|
|
20
|
+
maxCalls;
|
|
21
|
+
windowMs;
|
|
22
|
+
timestamps = [];
|
|
23
|
+
/**
|
|
24
|
+
* @param maxCalls - Maximum number of calls allowed in the window
|
|
25
|
+
* @param windowMs - Window size in milliseconds
|
|
26
|
+
*/
|
|
27
|
+
constructor(maxCalls = 60, windowMs = 60_000) {
|
|
28
|
+
this.maxCalls = maxCalls;
|
|
29
|
+
this.windowMs = windowMs;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Try to acquire a rate limit slot.
|
|
33
|
+
* @returns true if the call is allowed, false if rate limited
|
|
34
|
+
*/
|
|
35
|
+
tryAcquire() {
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
const windowStart = now - this.windowMs;
|
|
38
|
+
// Prune expired timestamps
|
|
39
|
+
this.timestamps = this.timestamps.filter(t => t > windowStart);
|
|
40
|
+
if (this.timestamps.length >= this.maxCalls) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
this.timestamps.push(now);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the current number of calls in the window.
|
|
48
|
+
*/
|
|
49
|
+
get currentCount() {
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
const windowStart = now - this.windowMs;
|
|
52
|
+
return this.timestamps.filter(t => t > windowStart).length;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limiter.js","sourceRoot":"","sources":["../../src/rate-limit/limiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,WAAW;IAQH;IACA;IARX,UAAU,GAAa,EAAE,CAAC;IAElC;;;OAGG;IACH,YACmB,WAAmB,EAAE,EACrB,WAAmB,MAAM;QADzB,aAAQ,GAAR,QAAQ,CAAa;QACrB,aAAQ,GAAR,QAAQ,CAAiB;IACzC,CAAC;IAEJ;;;OAGG;IACH,UAAU;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAExC,2BAA2B;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;QAE/D,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,IAAI,YAAY;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxC,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,CAAC;IAC7D,CAAC;CACF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action execution context.
|
|
3
|
+
* @module sandbox/context
|
|
4
|
+
*/
|
|
5
|
+
import { Manifest } from '../manifest/schema.js';
|
|
6
|
+
import type { AuditLogger } from '../audit/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Simplified manifest for context (only needed fields).
|
|
9
|
+
*/
|
|
10
|
+
export interface SimplifiedManifest {
|
|
11
|
+
name: string;
|
|
12
|
+
version: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Action context passed to action scripts.
|
|
16
|
+
*/
|
|
17
|
+
export interface ActionContext {
|
|
18
|
+
/** Manifest metadata */
|
|
19
|
+
manifest: SimplifiedManifest;
|
|
20
|
+
/**
|
|
21
|
+
* Scoped fetch function.
|
|
22
|
+
* - Validates URL for SSRF
|
|
23
|
+
* - Re-validates redirect URLs
|
|
24
|
+
* - Resolves relative redirects
|
|
25
|
+
* - Logs all requests for audit
|
|
26
|
+
*/
|
|
27
|
+
fetch: (url: string, options?: FetchOptions) => Promise<Response>;
|
|
28
|
+
/**
|
|
29
|
+
* Get a secret value with URL scope validation.
|
|
30
|
+
* Returns the secret value if the URL matches the secret's scope,
|
|
31
|
+
* or undefined if the secret doesn't exist or the URL is out of scope.
|
|
32
|
+
*/
|
|
33
|
+
getSecret: (name: string, url: string) => string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Logging function.
|
|
36
|
+
*/
|
|
37
|
+
log: (level: 'debug' | 'info' | 'warn' | 'error', message: string) => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fetch options for ctx.fetch.
|
|
41
|
+
*/
|
|
42
|
+
export interface FetchOptions extends RequestInit {
|
|
43
|
+
/** Maximum response size in bytes */
|
|
44
|
+
maxSize?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for creating action context.
|
|
48
|
+
*/
|
|
49
|
+
export interface CreateContextOptions {
|
|
50
|
+
manifest: SimplifiedManifest | Manifest;
|
|
51
|
+
secrets: Record<string, string>;
|
|
52
|
+
/** Secret scopes: secret name -> patterns */
|
|
53
|
+
secretScopes: Record<string, string[]>;
|
|
54
|
+
/** Maximum response size (default: 10MB) */
|
|
55
|
+
maxResponseSize?: number;
|
|
56
|
+
/** Maximum redirects (default: 5) */
|
|
57
|
+
maxRedirects?: number;
|
|
58
|
+
/** Logger function */
|
|
59
|
+
logger?: (level: string, message: string) => void;
|
|
60
|
+
/** Request timeout in ms */
|
|
61
|
+
timeout?: number;
|
|
62
|
+
/** Optional audit logger for structured event logging */
|
|
63
|
+
auditLogger?: AuditLogger;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create action context for isolated execution.
|
|
67
|
+
*/
|
|
68
|
+
export declare function createActionContext(options: CreateContextOptions): ActionContext;
|
|
69
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/sandbox/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,QAAQ,EAAE,kBAAkB,CAAC;IAE7B;;;;;;OAMG;IACH,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAElE;;;;OAIG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAE7D;;OAEG;IACH,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5E;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,kBAAkB,GAAG,QAAQ,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAwJhF"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action execution context.
|
|
3
|
+
* @module sandbox/context
|
|
4
|
+
*/
|
|
5
|
+
import { validateUrl, validateRedirect } from './url-validator.js';
|
|
6
|
+
import { validateUrlScope } from '../secrets/patterns.js';
|
|
7
|
+
import { stripCrossOriginHeaders } from '../http/redirect-utils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create action context for isolated execution.
|
|
10
|
+
*/
|
|
11
|
+
export function createActionContext(options) {
|
|
12
|
+
const { manifest, secrets, secretScopes, maxResponseSize = 10 * 1024 * 1024, // 10MB
|
|
13
|
+
maxRedirects = 5, logger = console.error, auditLogger, } = options;
|
|
14
|
+
const log = (level, message) => {
|
|
15
|
+
logger(level, `[${manifest.name}] ${message}`);
|
|
16
|
+
auditLogger?.logActionLog(level, message, manifest.name);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Get a secret with URL scope validation (AC2-AC4).
|
|
20
|
+
* The inverted scope logic is removed (AC5) — scope validation only
|
|
21
|
+
* applies when a secret is explicitly accessed via getSecret.
|
|
22
|
+
*/
|
|
23
|
+
const getSecret = (name, url) => {
|
|
24
|
+
const value = secrets[name];
|
|
25
|
+
if (!value)
|
|
26
|
+
return undefined;
|
|
27
|
+
const patterns = secretScopes[name];
|
|
28
|
+
if (!patterns)
|
|
29
|
+
return undefined;
|
|
30
|
+
try {
|
|
31
|
+
validateUrlScope(url, patterns);
|
|
32
|
+
auditLogger?.logSecretAccess(name, url, true, manifest.name);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
auditLogger?.logSecretAccess(name, url, false, manifest.name);
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const scopedFetch = async (url, init = {}) => {
|
|
41
|
+
const maxSize = init.maxSize ?? maxResponseSize;
|
|
42
|
+
// Remove maxSize from init before passing to native fetch
|
|
43
|
+
let { maxSize: _, ...fetchInit } = init;
|
|
44
|
+
// Pre-fetch audit log: always fires as an attempt signal
|
|
45
|
+
auditLogger?.logFetch(url, undefined, undefined, manifest.name);
|
|
46
|
+
const startTime = Date.now();
|
|
47
|
+
let responseStatus;
|
|
48
|
+
try {
|
|
49
|
+
// Validate URL for SSRF inside try/finally so DNS failures are also audit-logged (AC25)
|
|
50
|
+
await validateUrl(url, { maxRedirects });
|
|
51
|
+
// Execute fetch with redirect validation
|
|
52
|
+
let currentUrl = url;
|
|
53
|
+
let redirectCount = 0;
|
|
54
|
+
while (redirectCount < maxRedirects) {
|
|
55
|
+
const response = await fetch(currentUrl, {
|
|
56
|
+
...fetchInit,
|
|
57
|
+
redirect: 'manual',
|
|
58
|
+
});
|
|
59
|
+
// Handle redirect
|
|
60
|
+
if (response.status >= 300 && response.status < 400) {
|
|
61
|
+
const rawRedirectUrl = response.headers.get('location');
|
|
62
|
+
if (!rawRedirectUrl) {
|
|
63
|
+
throw new Error(`Redirect without location header from ${currentUrl}`);
|
|
64
|
+
}
|
|
65
|
+
redirectCount++;
|
|
66
|
+
// Resolve relative redirect URLs against current URL (AC11, AC12)
|
|
67
|
+
const resolvedRedirectUrl = new URL(rawRedirectUrl, currentUrl).href;
|
|
68
|
+
// Validate redirect URL for SSRF (AC13)
|
|
69
|
+
await validateRedirect(resolvedRedirectUrl, currentUrl, { maxRedirects });
|
|
70
|
+
// Strip sensitive headers on cross-origin redirect
|
|
71
|
+
// Pass headers directly — stripCrossOriginHeaders normalizes HeadersInit (Headers, tuples, objects)
|
|
72
|
+
const safeHeaders = stripCrossOriginHeaders(fetchInit.headers ?? {}, currentUrl, resolvedRedirectUrl);
|
|
73
|
+
fetchInit = { ...fetchInit, headers: safeHeaders };
|
|
74
|
+
auditLogger?.logRedirect(currentUrl, resolvedRedirectUrl, manifest.name);
|
|
75
|
+
currentUrl = resolvedRedirectUrl;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Record the final HTTP status for the post-fetch audit log
|
|
79
|
+
responseStatus = response.status;
|
|
80
|
+
// Check response size
|
|
81
|
+
const contentLength = response.headers.get('content-length');
|
|
82
|
+
if (contentLength && parseInt(contentLength, 10) > maxSize) {
|
|
83
|
+
throw new Error(`Response too large: ${contentLength} bytes (max: ${maxSize})`);
|
|
84
|
+
}
|
|
85
|
+
// Actually enforce size by reading with limit
|
|
86
|
+
const reader = response.body?.getReader();
|
|
87
|
+
if (reader) {
|
|
88
|
+
const chunks = [];
|
|
89
|
+
let totalSize = 0;
|
|
90
|
+
while (true) {
|
|
91
|
+
const { done, value } = await reader.read();
|
|
92
|
+
if (done)
|
|
93
|
+
break;
|
|
94
|
+
totalSize += value.length;
|
|
95
|
+
if (totalSize > maxSize) {
|
|
96
|
+
reader.cancel();
|
|
97
|
+
throw new Error(`Response body too large: ${totalSize} bytes (max: ${maxSize})`);
|
|
98
|
+
}
|
|
99
|
+
chunks.push(value);
|
|
100
|
+
}
|
|
101
|
+
// Reconstruct response with the body
|
|
102
|
+
const body = new Uint8Array(totalSize);
|
|
103
|
+
let offset = 0;
|
|
104
|
+
for (const chunk of chunks) {
|
|
105
|
+
body.set(chunk, offset);
|
|
106
|
+
offset += chunk.length;
|
|
107
|
+
}
|
|
108
|
+
// Return a new response with the read body
|
|
109
|
+
return new Response(body, {
|
|
110
|
+
status: response.status,
|
|
111
|
+
statusText: response.statusText,
|
|
112
|
+
headers: response.headers,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return response;
|
|
116
|
+
}
|
|
117
|
+
throw new Error(`Too many redirects (max: ${maxRedirects})`);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
// Post-fetch audit log: fires on success and error paths (AC25)
|
|
121
|
+
auditLogger?.logFetch(url, responseStatus, Date.now() - startTime, manifest.name);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
return {
|
|
125
|
+
manifest: {
|
|
126
|
+
name: manifest.name,
|
|
127
|
+
version: manifest.version,
|
|
128
|
+
},
|
|
129
|
+
fetch: scopedFetch,
|
|
130
|
+
getSecret,
|
|
131
|
+
log,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/sandbox/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox executor using isolated-vm.
|
|
3
|
+
* @module sandbox/executor
|
|
4
|
+
*/
|
|
5
|
+
import { CreateContextOptions } from './context.js';
|
|
6
|
+
/**
|
|
7
|
+
* Sandbox executor options.
|
|
8
|
+
*/
|
|
9
|
+
export interface SandboxOptions {
|
|
10
|
+
/** Memory limit in bytes (default: 128MB) */
|
|
11
|
+
memoryLimit?: number;
|
|
12
|
+
/** CPU time limit in ms (default: 30000) */
|
|
13
|
+
cpuTimeLimit?: number;
|
|
14
|
+
/** Wall time limit in ms (default: 60000) */
|
|
15
|
+
wallTimeLimit?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Tool result from action execution.
|
|
19
|
+
*/
|
|
20
|
+
export interface ToolResult {
|
|
21
|
+
content: Array<{
|
|
22
|
+
type: 'text';
|
|
23
|
+
text: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'image';
|
|
26
|
+
data: string;
|
|
27
|
+
mimeType: string;
|
|
28
|
+
}>;
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validate and truncate result if too large.
|
|
33
|
+
*/
|
|
34
|
+
export declare function validateResultSize(result: ToolResult): ToolResult;
|
|
35
|
+
/**
|
|
36
|
+
* Transform ES module action code to CommonJS-style for isolated-vm.
|
|
37
|
+
*/
|
|
38
|
+
export declare function transformActionCode(code: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Execute an action script in an isolated sandbox.
|
|
41
|
+
*
|
|
42
|
+
* The action code should export a default async function:
|
|
43
|
+
* ```javascript
|
|
44
|
+
* export default async function myAction(input, ctx) {
|
|
45
|
+
* return { content: [{ type: 'text', text: 'Result' }] };
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function executeAction(actionCode: string, input: unknown, contextOptions: CreateContextOptions, sandboxOptions?: SandboxOptions): Promise<ToolResult>;
|
|
50
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/sandbox/executor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAuB,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAiBD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnG,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CA6BjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsDxD;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,EACd,cAAc,EAAE,oBAAoB,EACpC,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,UAAU,CAAC,CAuKrB"}
|