@bookedsolid/reagent 0.3.0 → 0.4.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/README.md +163 -82
- package/agents/ai-platforms/ai-anthropic-specialist.md +1 -1
- package/agents/ai-platforms/ai-fine-tuning-specialist.md +1 -1
- package/agents/ai-platforms/ai-gemini-specialist.md +1 -1
- package/agents/ai-platforms/ai-mcp-developer.md +1 -1
- package/agents/ai-platforms/ai-multi-modal-specialist.md +1 -1
- package/agents/ai-platforms/ai-open-source-models-specialist.md +1 -1
- package/agents/ai-platforms/ai-openai-specialist.md +1 -1
- package/agents/ai-platforms/ai-platform-strategist.md +1 -1
- package/agents/ai-platforms/ai-prompt-engineer.md +1 -1
- package/agents/ai-platforms/ai-rag-architect.md +1 -1
- package/agents/ai-platforms/ai-rea.md +2 -2
- package/agents/ai-platforms/ai-safety-reviewer.md +1 -1
- package/agents/engineering/accessibility-engineer.md +1 -1
- package/agents/engineering/aws-architect.md +1 -1
- package/agents/engineering/backend-engineer-payments.md +1 -1
- package/agents/engineering/backend-engineering-manager.md +1 -1
- package/agents/engineering/code-reviewer.md +1 -1
- package/agents/engineering/css3-animation-purist.md +1 -1
- package/agents/engineering/data-engineer.md +1 -1
- package/agents/engineering/database-architect.md +1 -1
- package/agents/engineering/design-system-developer.md +1 -1
- package/agents/engineering/design-systems-animator.md +1 -1
- package/agents/engineering/devops-engineer.md +1 -1
- package/agents/engineering/drupal-integration-specialist.md +1 -1
- package/agents/engineering/drupal-specialist.md +1 -1
- package/agents/engineering/engineering-manager-frontend.md +1 -1
- package/agents/engineering/frontend-specialist.md +1 -1
- package/agents/engineering/infrastructure-engineer.md +1 -1
- package/agents/engineering/lit-specialist.md +1 -1
- package/agents/engineering/migration-specialist.md +1 -1
- package/agents/engineering/ml-engineer.md +1 -1
- package/agents/engineering/mobile-engineer.md +1 -1
- package/agents/engineering/motion-designer-interactive.md +1 -1
- package/agents/engineering/nextjs-specialist.md +1 -1
- package/agents/engineering/open-source-specialist.md +1 -1
- package/agents/engineering/performance-engineer.md +1 -1
- package/agents/engineering/performance-qa-engineer.md +1 -1
- package/agents/engineering/pr-maintainer.md +1 -1
- package/agents/engineering/principal-engineer.md +1 -1
- package/agents/engineering/privacy-engineer.md +1 -1
- package/agents/engineering/qa-engineer.md +1 -1
- package/agents/engineering/security-engineer.md +1 -1
- package/agents/engineering/security-qa-engineer.md +1 -1
- package/agents/engineering/senior-backend-engineer.md +1 -1
- package/agents/engineering/senior-database-engineer.md +1 -1
- package/agents/engineering/senior-frontend-engineer.md +1 -1
- package/agents/engineering/senior-product-manager-platform.md +1 -1
- package/agents/engineering/senior-technical-project-manager.md +1 -1
- package/agents/engineering/site-reliability-engineer-2.md +1 -1
- package/agents/engineering/solutions-architect.md +1 -1
- package/agents/engineering/sre-lead.md +1 -1
- package/agents/engineering/staff-engineer-platform.md +1 -1
- package/agents/engineering/staff-software-engineer.md +1 -1
- package/agents/engineering/storybook-specialist.md +1 -1
- package/agents/engineering/supabase-specialist.md +1 -1
- package/agents/engineering/technical-project-manager.md +1 -1
- package/agents/engineering/technical-writer.md +1 -1
- package/agents/engineering/test-architect.md +1 -1
- package/agents/engineering/typescript-specialist.md +1 -1
- package/agents/engineering/ux-researcher.md +1 -1
- package/agents/engineering/vp-engineering.md +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +52 -3
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/config/gateway-config.d.ts.map +1 -1
- package/dist/config/gateway-config.js +5 -1
- package/dist/config/gateway-config.js.map +1 -1
- package/dist/config/policy-loader.d.ts.map +1 -1
- package/dist/config/policy-loader.js +15 -1
- package/dist/config/policy-loader.js.map +1 -1
- package/dist/config/tier-map.d.ts +1 -1
- package/dist/config/tier-map.d.ts.map +1 -1
- package/dist/config/tier-map.js +38 -5
- package/dist/config/tier-map.js.map +1 -1
- package/dist/gateway/client-manager.d.ts.map +1 -1
- package/dist/gateway/client-manager.js +9 -3
- package/dist/gateway/client-manager.js.map +1 -1
- package/dist/gateway/middleware/audit.d.ts +2 -1
- package/dist/gateway/middleware/audit.d.ts.map +1 -1
- package/dist/gateway/middleware/audit.js +57 -46
- package/dist/gateway/middleware/audit.js.map +1 -1
- package/dist/gateway/middleware/blocked-paths.d.ts +13 -0
- package/dist/gateway/middleware/blocked-paths.d.ts.map +1 -0
- package/dist/gateway/middleware/blocked-paths.js +118 -0
- package/dist/gateway/middleware/blocked-paths.js.map +1 -0
- package/dist/gateway/middleware/policy.d.ts +3 -1
- package/dist/gateway/middleware/policy.d.ts.map +1 -1
- package/dist/gateway/middleware/policy.js +22 -3
- package/dist/gateway/middleware/policy.js.map +1 -1
- package/dist/gateway/middleware/redact.d.ts.map +1 -1
- package/dist/gateway/middleware/redact.js +18 -5
- package/dist/gateway/middleware/redact.js.map +1 -1
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +7 -4
- package/dist/gateway/server.js.map +1 -1
- package/dist/gateway/tool-proxy.d.ts.map +1 -1
- package/dist/gateway/tool-proxy.js +18 -6
- package/dist/gateway/tool-proxy.js.map +1 -1
- package/dist/types/enums.d.ts +0 -4
- package/dist/types/enums.d.ts.map +1 -1
- package/dist/types/enums.js +0 -5
- package/dist/types/enums.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/hooks/attribution-advisory.sh +1 -1
- package/hooks/dangerous-bash-interceptor.sh +1 -1
- package/hooks/env-file-protection.sh +1 -1
- package/hooks/secret-scanner.sh +1 -1
- package/package.json +16 -1
- package/profiles/bst-internal.json +1 -1
- package/templates/CLAUDE.md +14 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { InvocationStatus } from '../../types/index.js';
|
|
3
|
+
import { loadPolicy } from '../../config/policy-loader.js';
|
|
4
|
+
/**
|
|
5
|
+
* Pre-execution middleware: denies tool invocations whose arguments
|
|
6
|
+
* reference paths that are in the policy's blocked_paths list.
|
|
7
|
+
*
|
|
8
|
+
* SECURITY: Inspects all string values in arguments (including nested objects/arrays).
|
|
9
|
+
* SECURITY: Always blocks .reagent/ regardless of policy configuration.
|
|
10
|
+
* SECURITY: Normalizes URL-encoded characters, path separators, and case before comparison.
|
|
11
|
+
* SECURITY: Re-reads blocked_paths from policy.yaml when baseDir is provided (hot-reload).
|
|
12
|
+
*/
|
|
13
|
+
export function createBlockedPathsMiddleware(initialPolicy, baseDir) {
|
|
14
|
+
return async (ctx, next) => {
|
|
15
|
+
// Hot-reload blocked_paths from policy.yaml if baseDir is available
|
|
16
|
+
let blockedPaths = initialPolicy.blocked_paths;
|
|
17
|
+
if (baseDir) {
|
|
18
|
+
try {
|
|
19
|
+
const policy = loadPolicy(baseDir);
|
|
20
|
+
blockedPaths = policy.blocked_paths;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Fall back to initial policy's blocked_paths on read failure
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Always protect .reagent/ — it's the trust root of the system.
|
|
27
|
+
const paths = [...new Set([...blockedPaths, '.reagent/'])];
|
|
28
|
+
// Recursively extract all string values from arguments
|
|
29
|
+
const stringValues = extractStringValues(ctx.arguments);
|
|
30
|
+
for (const [key, value] of stringValues) {
|
|
31
|
+
for (const blocked of paths) {
|
|
32
|
+
if (containsBlockedPath(value, blocked)) {
|
|
33
|
+
ctx.status = InvocationStatus.Denied;
|
|
34
|
+
ctx.error = `Argument "${key}" references blocked path "${blocked}". Tool: ${ctx.tool_name}`;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
await next();
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Recursively extract all string values from an object, with their key paths.
|
|
44
|
+
* Handles nested objects and arrays.
|
|
45
|
+
*/
|
|
46
|
+
function extractStringValues(obj, prefix = '', seen = new WeakSet()) {
|
|
47
|
+
const results = [];
|
|
48
|
+
if (obj === null || obj === undefined)
|
|
49
|
+
return results;
|
|
50
|
+
if (typeof obj === 'string') {
|
|
51
|
+
results.push([prefix || 'value', obj]);
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
if (typeof obj !== 'object')
|
|
55
|
+
return results;
|
|
56
|
+
// Circular reference guard
|
|
57
|
+
const objRef = obj;
|
|
58
|
+
if (seen.has(objRef))
|
|
59
|
+
return results;
|
|
60
|
+
seen.add(objRef);
|
|
61
|
+
if (Array.isArray(obj)) {
|
|
62
|
+
for (let i = 0; i < obj.length; i++) {
|
|
63
|
+
results.push(...extractStringValues(obj[i], `${prefix}[${i}]`, seen));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
68
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
69
|
+
results.push(...extractStringValues(value, fullKey, seen));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return results;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if a string value references a blocked path.
|
|
76
|
+
*
|
|
77
|
+
* SECURITY: Decodes URL-encoded characters (%2F, %2f, etc.)
|
|
78
|
+
* SECURITY: Normalizes path separators and resolves . and .. segments
|
|
79
|
+
* SECURITY: Performs case-insensitive comparison for cross-platform safety
|
|
80
|
+
*/
|
|
81
|
+
function containsBlockedPath(value, blockedPath) {
|
|
82
|
+
// Normalize the value: decode URL encoding, normalize slashes and path segments
|
|
83
|
+
const normalized = normalizePath(value);
|
|
84
|
+
const normalizedBlocked = blockedPath.replace(/\\/g, '/').toLowerCase();
|
|
85
|
+
// Direct containment check (case-insensitive)
|
|
86
|
+
if (normalized.includes(normalizedBlocked))
|
|
87
|
+
return true;
|
|
88
|
+
// Check without leading dot/slash for relative path variants
|
|
89
|
+
const stripped = normalizedBlocked.replace(/^\.?\/?/, '');
|
|
90
|
+
if (stripped && normalized.includes(stripped))
|
|
91
|
+
return true;
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Normalize a path string for blocked-path comparison.
|
|
96
|
+
*
|
|
97
|
+
* 1. Decode URL-encoded characters (handles %2F, %2f, %2E, etc.)
|
|
98
|
+
* 2. Normalize backslashes to forward slashes
|
|
99
|
+
* 3. Normalize path segments (resolve . and ..)
|
|
100
|
+
* 4. Lowercase for case-insensitive comparison
|
|
101
|
+
*/
|
|
102
|
+
function normalizePath(value) {
|
|
103
|
+
let decoded = value;
|
|
104
|
+
// Decode URL-encoded characters (try/catch for malformed sequences)
|
|
105
|
+
try {
|
|
106
|
+
decoded = decodeURIComponent(value);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// If decoding fails, use the original value — may contain partial encoding
|
|
110
|
+
}
|
|
111
|
+
// Normalize backslashes to forward slashes
|
|
112
|
+
decoded = decoded.replace(/\\/g, '/');
|
|
113
|
+
// Use path.normalize to resolve . and .. segments, then re-normalize slashes
|
|
114
|
+
decoded = path.normalize(decoded).replace(/\\/g, '/');
|
|
115
|
+
// Lowercase for case-insensitive comparison
|
|
116
|
+
return decoded.toLowerCase();
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=blocked-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocked-paths.js","sourceRoot":"","sources":["../../../src/gateway/middleware/blocked-paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,10 @@ import type { Middleware } from './chain.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Checks autonomy level against tool tier, and checks blocked tools.
|
|
5
5
|
*
|
|
6
|
+
* SECURITY: Re-reads policy.yaml on every invocation so autonomy level changes
|
|
7
|
+
* take effect immediately without gateway restart.
|
|
6
8
|
* SECURITY: Re-derives tier from tool_name independently — never trusts ctx.tier.
|
|
7
9
|
* SECURITY: Undefined/unknown tier defaults to DENY (fail-closed).
|
|
8
10
|
*/
|
|
9
|
-
export declare function createPolicyMiddleware(
|
|
11
|
+
export declare function createPolicyMiddleware(initialPolicy: Policy, gatewayConfig?: GatewayConfig, baseDir?: string): Middleware;
|
|
10
12
|
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/gateway/middleware/policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/gateway/middleware/policy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgB7C;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,aAAa,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,UAAU,CAmDZ"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AutonomyLevel, InvocationStatus, Tier } from '../../types/index.js';
|
|
2
2
|
import { classifyTool, isToolBlocked } from '../../config/tier-map.js';
|
|
3
|
+
import { loadPolicy } from '../../config/policy-loader.js';
|
|
3
4
|
/**
|
|
4
5
|
* Autonomy level tier permissions:
|
|
5
6
|
* - L0: Read only
|
|
@@ -16,11 +17,29 @@ const TIER_ALLOWED = {
|
|
|
16
17
|
/**
|
|
17
18
|
* Checks autonomy level against tool tier, and checks blocked tools.
|
|
18
19
|
*
|
|
20
|
+
* SECURITY: Re-reads policy.yaml on every invocation so autonomy level changes
|
|
21
|
+
* take effect immediately without gateway restart.
|
|
19
22
|
* SECURITY: Re-derives tier from tool_name independently — never trusts ctx.tier.
|
|
20
23
|
* SECURITY: Undefined/unknown tier defaults to DENY (fail-closed).
|
|
21
24
|
*/
|
|
22
|
-
export function createPolicyMiddleware(
|
|
25
|
+
export function createPolicyMiddleware(initialPolicy, gatewayConfig, baseDir) {
|
|
26
|
+
// SECURITY: Cache last successfully parsed policy for fallback.
|
|
27
|
+
// This prevents falling back to a potentially more permissive initial policy
|
|
28
|
+
// if the file is corrupted after a stricter policy was loaded.
|
|
29
|
+
let lastGoodPolicy = initialPolicy;
|
|
23
30
|
return async (ctx, next) => {
|
|
31
|
+
// SECURITY: Re-read policy on each invocation for live autonomy changes.
|
|
32
|
+
// Falls back to last successfully parsed policy on read failure.
|
|
33
|
+
let policy = lastGoodPolicy;
|
|
34
|
+
if (baseDir) {
|
|
35
|
+
try {
|
|
36
|
+
policy = loadPolicy(baseDir);
|
|
37
|
+
lastGoodPolicy = policy; // Cache successful parse
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Fail-safe: use last successfully parsed policy if re-read fails
|
|
41
|
+
}
|
|
42
|
+
}
|
|
24
43
|
// Check if tool is explicitly blocked
|
|
25
44
|
if (isToolBlocked(ctx.tool_name, ctx.server_name, gatewayConfig)) {
|
|
26
45
|
ctx.status = InvocationStatus.Denied;
|
|
@@ -44,9 +63,9 @@ export function createPolicyMiddleware(policy, gatewayConfig) {
|
|
|
44
63
|
ctx.error = `Autonomy level ${policy.autonomy_level} does not allow ${tier}-tier tools. Tool: ${ctx.tool_name}`;
|
|
45
64
|
return;
|
|
46
65
|
}
|
|
66
|
+
// Store current autonomy level in metadata for audit middleware
|
|
67
|
+
ctx.metadata.autonomy_level = policy.autonomy_level;
|
|
47
68
|
await next();
|
|
48
|
-
// SECURITY: Re-assert denial status cannot be undone by downstream middleware.
|
|
49
|
-
// Once denied, status is locked.
|
|
50
69
|
};
|
|
51
70
|
}
|
|
52
71
|
//# sourceMappingURL=policy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/gateway/middleware/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/gateway/middleware/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D;;;;;;GAMG;AACH,MAAM,YAAY,GAAqC;IACrD,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;CACvE,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,aAAqB,EACrB,aAA6B,EAC7B,OAAgB;IAEhB,gEAAgE;IAChE,6EAA6E;IAC7E,+DAA+D;IAC/D,IAAI,cAAc,GAAG,aAAa,CAAC;IAEnC,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,yEAAyE;QACzE,iEAAiE;QACjE,IAAI,MAAM,GAAG,cAAc,CAAC;QAC5B,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC7B,cAAc,GAAG,MAAM,CAAC,CAAC,yBAAyB;YACpD,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;YACrC,GAAG,CAAC,KAAK,GAAG,SAAS,GAAG,CAAC,SAAS,2CAA2C,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,yFAAyF;QACzF,qFAAqF;QACrF,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACzE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,8CAA8C;QAE/D,mCAAmC;QACnC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;YACrC,GAAG,CAAC,KAAK,GAAG,2BAA2B,MAAM,CAAC,cAAc,uBAAuB,CAAC;YACpF,OAAO;QACT,CAAC;QAED,mEAAmE;QACnE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;YACrC,GAAG,CAAC,KAAK,GAAG,kBAAkB,MAAM,CAAC,cAAc,mBAAmB,IAAI,sBAAsB,GAAG,CAAC,SAAS,EAAE,CAAC;YAChH,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,GAAG,CAAC,QAAQ,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAEpD,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/gateway/middleware/redact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkC7C;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAenF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/gateway/middleware/redact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkC7C;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAenF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,UA6B9B,CAAC"}
|
|
@@ -53,6 +53,14 @@ export function redactSecrets(input) {
|
|
|
53
53
|
* could corrupt the result if a replacement changes JSON structure.
|
|
54
54
|
*/
|
|
55
55
|
export const redactMiddleware = async (ctx, next) => {
|
|
56
|
+
// SECURITY: Pre-execution — scan arguments for secrets before they reach the downstream tool.
|
|
57
|
+
if (ctx.arguments) {
|
|
58
|
+
const argRedacted = [];
|
|
59
|
+
redactDeep(ctx.arguments, argRedacted);
|
|
60
|
+
if (argRedacted.length > 0) {
|
|
61
|
+
ctx.redacted_fields = [...new Set(argRedacted)];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
56
64
|
await next();
|
|
57
65
|
if (ctx.result == null)
|
|
58
66
|
return;
|
|
@@ -60,7 +68,7 @@ export const redactMiddleware = async (ctx, next) => {
|
|
|
60
68
|
const { output, redacted } = redactSecrets(ctx.result);
|
|
61
69
|
if (redacted.length > 0) {
|
|
62
70
|
ctx.result = output;
|
|
63
|
-
ctx.redacted_fields = redacted;
|
|
71
|
+
ctx.redacted_fields = [...new Set([...(ctx.redacted_fields ?? []), ...redacted])];
|
|
64
72
|
}
|
|
65
73
|
return;
|
|
66
74
|
}
|
|
@@ -68,15 +76,20 @@ export const redactMiddleware = async (ctx, next) => {
|
|
|
68
76
|
const allRedacted = [];
|
|
69
77
|
redactDeep(ctx.result, allRedacted);
|
|
70
78
|
if (allRedacted.length > 0) {
|
|
71
|
-
ctx.redacted_fields = [...new Set(allRedacted)];
|
|
79
|
+
ctx.redacted_fields = [...new Set([...(ctx.redacted_fields ?? []), ...allRedacted])];
|
|
72
80
|
}
|
|
73
81
|
};
|
|
74
82
|
/**
|
|
75
83
|
* Recursively walk an object/array and redact string values in-place.
|
|
84
|
+
* Uses a WeakSet to guard against circular references.
|
|
76
85
|
*/
|
|
77
|
-
function redactDeep(obj, redacted) {
|
|
86
|
+
function redactDeep(obj, redacted, seen = new WeakSet()) {
|
|
78
87
|
if (obj == null || typeof obj !== 'object')
|
|
79
88
|
return;
|
|
89
|
+
// Guard against circular references
|
|
90
|
+
if (seen.has(obj))
|
|
91
|
+
return;
|
|
92
|
+
seen.add(obj);
|
|
80
93
|
if (Array.isArray(obj)) {
|
|
81
94
|
for (let i = 0; i < obj.length; i++) {
|
|
82
95
|
if (typeof obj[i] === 'string') {
|
|
@@ -87,7 +100,7 @@ function redactDeep(obj, redacted) {
|
|
|
87
100
|
}
|
|
88
101
|
}
|
|
89
102
|
else {
|
|
90
|
-
redactDeep(obj[i], redacted);
|
|
103
|
+
redactDeep(obj[i], redacted, seen);
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
106
|
return;
|
|
@@ -102,7 +115,7 @@ function redactDeep(obj, redacted) {
|
|
|
102
115
|
}
|
|
103
116
|
}
|
|
104
117
|
else {
|
|
105
|
-
redactDeep(record[key], redacted);
|
|
118
|
+
redactDeep(record[key], redacted, seen);
|
|
106
119
|
}
|
|
107
120
|
}
|
|
108
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/gateway/middleware/redact.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,eAAe,GAA6C;IAChE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,oBAAoB,EAAE;IACzD;QACE,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,oEAAoE;KAC9E;IACD,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,8BAA8B,EAAE;IACjE;QACE,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,kEAAkE;KAC5E;IACD,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,kCAAkC,EAAE;IACrE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,2DAA2D,EAAE;IAC7F,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,4CAA4C,EAAE;IAChF,sEAAsE;IACtE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,gCAAgC,EAAE;CACtE,CAAC;AAEF;;GAEG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,eAAe,EAAE,CAAC;QAChD,qCAAqC;QACrC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;YACtB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAe,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IAC9D,MAAM,IAAI,EAAE,CAAC;IAEb,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO;IAE/B,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,GAAG,CAAC,eAAe,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/gateway/middleware/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4EvE"}
|
package/dist/gateway/server.js
CHANGED
|
@@ -11,6 +11,7 @@ import { createTierMiddleware } from './middleware/tier.js';
|
|
|
11
11
|
import { createPolicyMiddleware } from './middleware/policy.js';
|
|
12
12
|
import { redactMiddleware } from './middleware/redact.js';
|
|
13
13
|
import { createAuditMiddleware } from './middleware/audit.js';
|
|
14
|
+
import { createBlockedPathsMiddleware } from './middleware/blocked-paths.js';
|
|
14
15
|
/**
|
|
15
16
|
* Starts the MCP gateway server.
|
|
16
17
|
*
|
|
@@ -30,13 +31,15 @@ export async function startGateway(options) {
|
|
|
30
31
|
console.error(`[reagent] Gateway: ${Object.keys(gatewayConfig.servers).length} downstream server(s)`);
|
|
31
32
|
// Build middleware chain
|
|
32
33
|
// SECURITY: Audit is outermost so it records ALL invocations, including kill-switch denials.
|
|
33
|
-
//
|
|
34
|
+
// SECURITY: blocked-paths runs before tool execution to prevent writes to protected paths.
|
|
35
|
+
// Order (onion): audit → session → kill-switch → tier → policy → blocked-paths → redact → [execute]
|
|
34
36
|
const middlewares = [
|
|
35
|
-
createAuditMiddleware(baseDir),
|
|
37
|
+
createAuditMiddleware(baseDir, policy),
|
|
36
38
|
createSessionMiddleware(),
|
|
37
39
|
createKillSwitchMiddleware(baseDir),
|
|
38
40
|
createTierMiddleware(gatewayConfig),
|
|
39
|
-
createPolicyMiddleware(policy, gatewayConfig),
|
|
41
|
+
createPolicyMiddleware(policy, gatewayConfig, baseDir),
|
|
42
|
+
createBlockedPathsMiddleware(policy, baseDir),
|
|
40
43
|
redactMiddleware,
|
|
41
44
|
];
|
|
42
45
|
// Create gateway MCP server
|
|
@@ -71,7 +74,7 @@ export async function startGateway(options) {
|
|
|
71
74
|
catch (err) {
|
|
72
75
|
console.error('[reagent] Error during gateway close:', err instanceof Error ? err.message : err);
|
|
73
76
|
}
|
|
74
|
-
process.
|
|
77
|
+
process.exitCode = 0;
|
|
75
78
|
};
|
|
76
79
|
process.on('SIGINT', shutdown);
|
|
77
80
|
process.on('SIGTERM', shutdown);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-proxy.d.ts","sourceRoot":"","sources":["../../src/gateway/tool-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAqB,MAAM,uBAAuB,CAAC;AAI3E,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;CACvB;AA0BD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAwB;IAE/B,mBAAmB,CACvB,OAAO,EAAE,SAAS,EAClB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,UAAU,EAAE,GACxB,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-proxy.d.ts","sourceRoot":"","sources":["../../src/gateway/tool-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAqB,MAAM,uBAAuB,CAAC;AAI3E,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;CACvB;AA0BD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAwB;IAE/B,mBAAmB,CACvB,OAAO,EAAE,SAAS,EAClB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,UAAU,EAAE,GACxB,OAAO,CAAC,MAAM,CAAC;IAoIlB,QAAQ,IAAI,cAAc,EAAE;CAG7B"}
|
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { executeChain } from './middleware/chain.js';
|
|
3
3
|
import { InvocationStatus } from '../types/index.js';
|
|
4
4
|
/**
|
|
5
|
-
* Convert a JSON Schema properties object to a Zod record of `z.
|
|
5
|
+
* Convert a JSON Schema properties object to a Zod record of `z.unknown().optional()`.
|
|
6
6
|
* This preserves the downstream tool's top-level parameter names so the MCP caller
|
|
7
7
|
* sends them directly (not wrapped in `{ args: ... }`).
|
|
8
8
|
*/
|
|
@@ -12,12 +12,12 @@ function jsonSchemaToZodParams(inputSchema) {
|
|
|
12
12
|
const required = inputSchema.required ?? [];
|
|
13
13
|
if (properties) {
|
|
14
14
|
for (const key of Object.keys(properties)) {
|
|
15
|
-
zodParams[key] = required.includes(key) ? z.
|
|
15
|
+
zodParams[key] = required.includes(key) ? z.unknown() : z.unknown().optional();
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
// If no properties defined, accept arbitrary keys
|
|
19
19
|
if (Object.keys(zodParams).length === 0) {
|
|
20
|
-
return { _passthrough: z.
|
|
20
|
+
return { _passthrough: z.unknown().optional() };
|
|
21
21
|
}
|
|
22
22
|
return zodParams;
|
|
23
23
|
}
|
|
@@ -67,12 +67,24 @@ export class ToolProxy {
|
|
|
67
67
|
return; // Short-circuited by a prior middleware
|
|
68
68
|
}
|
|
69
69
|
try {
|
|
70
|
-
const
|
|
70
|
+
const callPromise = managed.client.callTool({
|
|
71
71
|
name: tool.name,
|
|
72
72
|
arguments: innerCtx.arguments,
|
|
73
73
|
});
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
// Per-tool timeout — prevents hung downstream from blocking the gateway.
|
|
75
|
+
const timeoutMs = 30_000;
|
|
76
|
+
let timer;
|
|
77
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
78
|
+
timer = setTimeout(() => reject(new Error(`Tool "${tool.name}" timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
79
|
+
});
|
|
80
|
+
try {
|
|
81
|
+
const callResult = await Promise.race([callPromise, timeoutPromise]);
|
|
82
|
+
innerCtx.result = callResult;
|
|
83
|
+
innerCtx.status = InvocationStatus.Allowed;
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
}
|
|
76
88
|
}
|
|
77
89
|
catch (err) {
|
|
78
90
|
innerCtx.status = InvocationStatus.Error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-proxy.js","sourceRoot":"","sources":["../../src/gateway/tool-proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAUrD;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,WAAoC;IACjE,MAAM,SAAS,GAA8B,EAAE,CAAC;IAChD,MAAM,UAAU,GAAG,WAAW,CAAC,UAAiD,CAAC;IACjF,MAAM,QAAQ,GAAI,WAAW,CAAC,QAAqB,IAAI,EAAE,CAAC;IAE1D,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1C,SAAS,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"tool-proxy.js","sourceRoot":"","sources":["../../src/gateway/tool-proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/types/enums.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,oBAAY,IAAI;IACd,IAAI,SAAS;IACb,KAAK,UAAU;IACf,WAAW,gBAAgB;CAC5B;AAED,oBAAY,aAAa;IACvB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;CACV;AAED,oBAAY,
|
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,oBAAY,IAAI;IACd,IAAI,SAAS;IACb,KAAK,UAAU;IACf,WAAW,gBAAgB;CAC5B;AAED,oBAAY,aAAa;IACvB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;CACV;AAED,oBAAY,gBAAgB;IAC1B,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB"}
|
package/dist/types/enums.js
CHANGED
|
@@ -11,11 +11,6 @@ export var AutonomyLevel;
|
|
|
11
11
|
AutonomyLevel["L2"] = "L2";
|
|
12
12
|
AutonomyLevel["L3"] = "L3";
|
|
13
13
|
})(AutonomyLevel || (AutonomyLevel = {}));
|
|
14
|
-
export var KillSwitchState;
|
|
15
|
-
(function (KillSwitchState) {
|
|
16
|
-
KillSwitchState["Active"] = "active";
|
|
17
|
-
KillSwitchState["Inactive"] = "inactive";
|
|
18
|
-
})(KillSwitchState || (KillSwitchState = {}));
|
|
19
14
|
export var InvocationStatus;
|
|
20
15
|
(function (InvocationStatus) {
|
|
21
16
|
InvocationStatus["Allowed"] = "allowed";
|
package/dist/types/enums.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enums.js","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,IAIX;AAJD,WAAY,IAAI;IACd,qBAAa,CAAA;IACb,uBAAe,CAAA;IACf,mCAA2B,CAAA;AAC7B,CAAC,EAJW,IAAI,KAAJ,IAAI,QAIf;AAED,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACvB,0BAAS,CAAA;IACT,0BAAS,CAAA;IACT,0BAAS,CAAA;IACT,0BAAS,CAAA;AACX,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;AAED,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"enums.js","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,IAIX;AAJD,WAAY,IAAI;IACd,qBAAa,CAAA;IACb,uBAAe,CAAA;IACf,mCAA2B,CAAA;AAC7B,CAAC,EAJW,IAAI,KAAJ,IAAI,QAIf;AAED,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACvB,0BAAS,CAAA;IACT,0BAAS,CAAA;IACT,0BAAS,CAAA;IACT,0BAAS,CAAA;AACX,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;AAED,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,uCAAmB,CAAA;IACnB,qCAAiB,CAAA;IACjB,mCAAe,CAAA;AACjB,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Tier, AutonomyLevel,
|
|
1
|
+
export { Tier, AutonomyLevel, InvocationStatus } from './enums.js';
|
|
2
2
|
export type { Policy } from './policy.js';
|
|
3
3
|
export type { GatewayConfig, DownstreamServer, ToolOverride } from './gateway.js';
|
|
4
4
|
export type { AuditRecord } from './audit.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClF,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/types/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Tier, AutonomyLevel,
|
|
1
|
+
export { Tier, AutonomyLevel, InvocationStatus } from './enums.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -30,7 +30,7 @@ REAGENT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
|
30
30
|
HALT_FILE="${REAGENT_ROOT}/.reagent/HALT"
|
|
31
31
|
if [ -f "$HALT_FILE" ]; then
|
|
32
32
|
printf 'REAGENT HALT: %s\nAll agent operations suspended. Run: reagent unfreeze\n' \
|
|
33
|
-
"$(
|
|
33
|
+
"$(head -c 1024 "$HALT_FILE" 2>/dev/null || echo 'Reason unknown')" >&2
|
|
34
34
|
exit 2
|
|
35
35
|
fi
|
|
36
36
|
|
|
@@ -30,7 +30,7 @@ REAGENT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
|
30
30
|
HALT_FILE="${REAGENT_ROOT}/.reagent/HALT"
|
|
31
31
|
if [ -f "$HALT_FILE" ]; then
|
|
32
32
|
printf 'REAGENT HALT: %s\nAll agent operations suspended. Run: reagent unfreeze\n' \
|
|
33
|
-
"$(
|
|
33
|
+
"$(head -c 1024 "$HALT_FILE" 2>/dev/null || echo 'Reason unknown')" >&2
|
|
34
34
|
exit 2
|
|
35
35
|
fi
|
|
36
36
|
|
|
@@ -31,7 +31,7 @@ REAGENT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
|
31
31
|
HALT_FILE="${REAGENT_ROOT}/.reagent/HALT"
|
|
32
32
|
if [ -f "$HALT_FILE" ]; then
|
|
33
33
|
printf 'REAGENT HALT: %s\nAll agent operations suspended. Run: reagent unfreeze\n' \
|
|
34
|
-
"$(
|
|
34
|
+
"$(head -c 1024 "$HALT_FILE" 2>/dev/null || echo 'Reason unknown')" >&2
|
|
35
35
|
exit 2
|
|
36
36
|
fi
|
|
37
37
|
|
package/hooks/secret-scanner.sh
CHANGED
|
@@ -33,7 +33,7 @@ REAGENT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
|
33
33
|
HALT_FILE="${REAGENT_ROOT}/.reagent/HALT"
|
|
34
34
|
if [ -f "$HALT_FILE" ]; then
|
|
35
35
|
printf 'REAGENT HALT: %s\nAll agent operations suspended. Run: reagent unfreeze\n' \
|
|
36
|
-
"$(
|
|
36
|
+
"$(head -c 1024 "$HALT_FILE" 2>/dev/null || echo 'Reason unknown')" >&2
|
|
37
37
|
exit 2
|
|
38
38
|
fi
|
|
39
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bookedsolid/reagent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Zero-trust MCP gateway — policy enforcement, secret redaction, and audit logging for AI-assisted projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Booked Solid Technology <oss@bookedsolid.tech> (https://bookedsolid.tech)",
|
|
@@ -16,6 +16,21 @@
|
|
|
16
16
|
"bin": {
|
|
17
17
|
"reagent": "dist/cli/index.js"
|
|
18
18
|
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/types/index.d.ts",
|
|
22
|
+
"import": "./dist/types/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./config": {
|
|
25
|
+
"types": "./dist/config/policy-loader.d.ts",
|
|
26
|
+
"import": "./dist/config/policy-loader.js"
|
|
27
|
+
},
|
|
28
|
+
"./middleware": {
|
|
29
|
+
"types": "./dist/gateway/middleware/chain.d.ts",
|
|
30
|
+
"import": "./dist/gateway/middleware/chain.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"sideEffects": false,
|
|
19
34
|
"engines": {
|
|
20
35
|
"node": ">=22"
|
|
21
36
|
},
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"huskyPreCommit": true,
|
|
7
7
|
"huskyPrePush": true,
|
|
8
8
|
"cursorRules": ["001-no-hallucination", "002-verify-before-act", "003-attribution"],
|
|
9
|
-
"blockedPaths": [],
|
|
9
|
+
"blockedPaths": [".reagent/", ".env"],
|
|
10
10
|
"gitignoreEntries": [".claude/agents/", ".claude/hooks/", ".claude/settings.json", "RESTART.md"],
|
|
11
11
|
"claudeMd": {
|
|
12
12
|
"preflightCmd": "pnpm preflight",
|
package/templates/CLAUDE.md
CHANGED
|
@@ -48,7 +48,20 @@ This session may be subject to audit logging per `.reagent/policy.yaml`. All too
|
|
|
48
48
|
|
|
49
49
|
## Delegation
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
This project uses a "bring your own engineering team" model. All non-trivial work flows through the orchestrator to specialist agents.
|
|
52
|
+
|
|
53
|
+
**CRITICAL: For any non-trivial task, delegate to the `reagent-orchestrator` agent FIRST.**
|
|
54
|
+
|
|
55
|
+
The orchestrator (`subagent_type: "reagent-orchestrator"`) is the primary routing layer:
|
|
56
|
+
|
|
57
|
+
- It reads `.reagent/policy.yaml` and checks HALT before any work
|
|
58
|
+
- It selects the right specialist agents from `.claude/agents/` based on the task
|
|
59
|
+
- It enforces engineering processes, coordinates multi-step work, and ensures quality gates
|
|
60
|
+
- It can launch multiple specialists in parallel for maximum throughput
|
|
61
|
+
|
|
62
|
+
**Fallback**: If the orchestrator is unavailable or the task is narrowly scoped to a single domain, you may route directly to a specialist agent by scanning `.claude/agents/` and using the matching `subagent_type` (e.g., `security-engineer`, `frontend-specialist`, `database-architect`).
|
|
63
|
+
|
|
64
|
+
**Do NOT** use generic Agent calls without specifying a `subagent_type`. Every agent invocation should target a discoverable specialist from `.claude/agents/`.
|
|
52
65
|
|
|
53
66
|
Exception: simple read-only questions and direct clarifications may be answered without delegation.
|
|
54
67
|
|