@bookedsolid/reagent 0.7.1 → 0.10.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.
Files changed (127) hide show
  1. package/README.md +277 -140
  2. package/agents/engineering/motion-designer-interactive.md +5 -4
  3. package/agents/engineering/pr-voice-reviewer.md +229 -0
  4. package/agents/engineering/qa-engineer-automation.md +5 -4
  5. package/agents/engineering/qa-engineer-manual.md +5 -4
  6. package/agents/engineering/qa-lead.md +5 -4
  7. package/agents/engineering/security-engineer-appsec.md +5 -4
  8. package/agents/engineering/security-engineer-compliance.md +5 -4
  9. package/agents/engineering/security-qa-engineer.md +5 -4
  10. package/agents/engineering/technical-writer.md +5 -4
  11. package/agents/product-owner.md +152 -0
  12. package/agents/reagent-orchestrator.md +8 -0
  13. package/commands/pm-status.md +230 -0
  14. package/commands/review-pr.md +197 -0
  15. package/dist/cli/commands/catalyze/gap-detector.d.ts.map +1 -1
  16. package/dist/cli/commands/catalyze/gap-detector.js +1 -3
  17. package/dist/cli/commands/catalyze/gap-detector.js.map +1 -1
  18. package/dist/cli/commands/daemon/index.d.ts +5 -0
  19. package/dist/cli/commands/daemon/index.d.ts.map +1 -0
  20. package/dist/cli/commands/daemon/index.js +59 -0
  21. package/dist/cli/commands/daemon/index.js.map +1 -0
  22. package/dist/cli/commands/daemon/restart.d.ts +10 -0
  23. package/dist/cli/commands/daemon/restart.d.ts.map +1 -0
  24. package/dist/cli/commands/daemon/restart.js +20 -0
  25. package/dist/cli/commands/daemon/restart.js.map +1 -0
  26. package/dist/cli/commands/daemon/start.d.ts +2 -0
  27. package/dist/cli/commands/daemon/start.d.ts.map +1 -0
  28. package/dist/cli/commands/daemon/start.js +143 -0
  29. package/dist/cli/commands/daemon/start.js.map +1 -0
  30. package/dist/cli/commands/daemon/status.d.ts +2 -0
  31. package/dist/cli/commands/daemon/status.d.ts.map +1 -0
  32. package/dist/cli/commands/daemon/status.js +90 -0
  33. package/dist/cli/commands/daemon/status.js.map +1 -0
  34. package/dist/cli/commands/daemon/stop.d.ts +2 -0
  35. package/dist/cli/commands/daemon/stop.d.ts.map +1 -0
  36. package/dist/cli/commands/daemon/stop.js +73 -0
  37. package/dist/cli/commands/daemon/stop.js.map +1 -0
  38. package/dist/cli/commands/init/claude-hooks.d.ts +1 -1
  39. package/dist/cli/commands/init/claude-hooks.d.ts.map +1 -1
  40. package/dist/cli/commands/init/claude-hooks.js +10 -4
  41. package/dist/cli/commands/init/claude-hooks.js.map +1 -1
  42. package/dist/cli/commands/init/index.d.ts.map +1 -1
  43. package/dist/cli/commands/init/index.js +5 -1
  44. package/dist/cli/commands/init/index.js.map +1 -1
  45. package/dist/cli/commands/init/policy.d.ts.map +1 -1
  46. package/dist/cli/commands/init/policy.js +21 -0
  47. package/dist/cli/commands/init/policy.js.map +1 -1
  48. package/dist/cli/commands/init/types.d.ts +16 -0
  49. package/dist/cli/commands/init/types.d.ts.map +1 -1
  50. package/dist/cli/index.js +9 -0
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/config/daemon-loader.d.ts +16 -0
  53. package/dist/config/daemon-loader.d.ts.map +1 -0
  54. package/dist/config/daemon-loader.js +76 -0
  55. package/dist/config/daemon-loader.js.map +1 -0
  56. package/dist/config/gateway-config.d.ts.map +1 -1
  57. package/dist/config/gateway-config.js +6 -0
  58. package/dist/config/gateway-config.js.map +1 -1
  59. package/dist/config/policy-loader.d.ts +27 -0
  60. package/dist/config/policy-loader.d.ts.map +1 -1
  61. package/dist/config/policy-loader.js +103 -10
  62. package/dist/config/policy-loader.js.map +1 -1
  63. package/dist/gateway/circuit-breaker.d.ts +60 -0
  64. package/dist/gateway/circuit-breaker.d.ts.map +1 -0
  65. package/dist/gateway/circuit-breaker.js +104 -0
  66. package/dist/gateway/circuit-breaker.js.map +1 -0
  67. package/dist/gateway/collision-detector.d.ts +31 -0
  68. package/dist/gateway/collision-detector.d.ts.map +1 -0
  69. package/dist/gateway/collision-detector.js +53 -0
  70. package/dist/gateway/collision-detector.js.map +1 -0
  71. package/dist/gateway/middleware/blocked-paths.js +2 -2
  72. package/dist/gateway/middleware/blocked-paths.js.map +1 -1
  73. package/dist/gateway/middleware/circuit-breaker.d.ts +12 -0
  74. package/dist/gateway/middleware/circuit-breaker.d.ts.map +1 -0
  75. package/dist/gateway/middleware/circuit-breaker.js +44 -0
  76. package/dist/gateway/middleware/circuit-breaker.js.map +1 -0
  77. package/dist/gateway/middleware/injection.d.ts +23 -0
  78. package/dist/gateway/middleware/injection.d.ts.map +1 -0
  79. package/dist/gateway/middleware/injection.js +129 -0
  80. package/dist/gateway/middleware/injection.js.map +1 -0
  81. package/dist/gateway/middleware/policy.js +2 -2
  82. package/dist/gateway/middleware/policy.js.map +1 -1
  83. package/dist/gateway/middleware/rate-limit.d.ts +13 -0
  84. package/dist/gateway/middleware/rate-limit.d.ts.map +1 -0
  85. package/dist/gateway/middleware/rate-limit.js +32 -0
  86. package/dist/gateway/middleware/rate-limit.js.map +1 -0
  87. package/dist/gateway/middleware/redact.d.ts.map +1 -1
  88. package/dist/gateway/middleware/redact.js +7 -0
  89. package/dist/gateway/middleware/redact.js.map +1 -1
  90. package/dist/gateway/middleware/result-size-cap.d.ts +14 -0
  91. package/dist/gateway/middleware/result-size-cap.d.ts.map +1 -0
  92. package/dist/gateway/middleware/result-size-cap.js +49 -0
  93. package/dist/gateway/middleware/result-size-cap.js.map +1 -0
  94. package/dist/gateway/native-tools.js +1 -1
  95. package/dist/gateway/native-tools.js.map +1 -1
  96. package/dist/gateway/rate-limiter.d.ts +47 -0
  97. package/dist/gateway/rate-limiter.d.ts.map +1 -0
  98. package/dist/gateway/rate-limiter.js +89 -0
  99. package/dist/gateway/rate-limiter.js.map +1 -0
  100. package/dist/gateway/server.d.ts.map +1 -1
  101. package/dist/gateway/server.js +27 -1
  102. package/dist/gateway/server.js.map +1 -1
  103. package/dist/gateway/tool-proxy.js +1 -1
  104. package/dist/gateway/tool-proxy.js.map +1 -1
  105. package/dist/types/daemon.d.ts +45 -0
  106. package/dist/types/daemon.d.ts.map +1 -0
  107. package/dist/types/daemon.js +2 -0
  108. package/dist/types/daemon.js.map +1 -0
  109. package/dist/types/gateway.d.ts +9 -0
  110. package/dist/types/gateway.d.ts.map +1 -1
  111. package/dist/types/policy.d.ts +1 -0
  112. package/dist/types/policy.d.ts.map +1 -1
  113. package/hooks/_lib/discord.sh +75 -0
  114. package/hooks/blocked-paths-enforcer.sh +0 -1
  115. package/hooks/changeset-security-gate.sh +143 -0
  116. package/hooks/commit-review-gate.sh +12 -4
  117. package/hooks/import-guard.sh +14 -0
  118. package/hooks/network-exfil-guard.sh +20 -2
  119. package/hooks/pr-issue-link-gate.sh +65 -0
  120. package/hooks/push-review-gate.sh +17 -2
  121. package/hooks/rate-limit-guard.sh +26 -2
  122. package/hooks/reagent-notify.sh +65 -0
  123. package/hooks/security-disclosure-gate.sh +146 -0
  124. package/husky/pre-push.sh +84 -0
  125. package/package.json +10 -2
  126. package/profiles/bst-internal.json +12 -2
  127. package/profiles/client-engagement.json +12 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/gateway/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFvE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GvE"}
@@ -10,9 +10,16 @@ import { createKillSwitchMiddleware } from './middleware/kill-switch.js';
10
10
  import { createTierMiddleware } from './middleware/tier.js';
11
11
  import { createPolicyMiddleware } from './middleware/policy.js';
12
12
  import { redactMiddleware } from './middleware/redact.js';
13
+ import { createInjectionMiddleware } from './middleware/injection.js';
13
14
  import { createAuditMiddleware } from './middleware/audit.js';
14
15
  import { createBlockedPathsMiddleware } from './middleware/blocked-paths.js';
16
+ import { createResultSizeCapMiddleware } from './middleware/result-size-cap.js';
17
+ import { createRateLimitMiddleware } from './middleware/rate-limit.js';
18
+ import { createCircuitBreakerMiddleware } from './middleware/circuit-breaker.js';
19
+ import { RateLimiter } from './rate-limiter.js';
20
+ import { CircuitBreaker } from './circuit-breaker.js';
15
21
  import { registerNativeTools } from './native-tools.js';
22
+ import { detectToolCollisions } from './collision-detector.js';
16
23
  /**
17
24
  * Starts the MCP gateway server.
18
25
  *
@@ -33,7 +40,17 @@ export async function startGateway(options) {
33
40
  // Build middleware chain
34
41
  // SECURITY: Audit is outermost so it records ALL invocations, including kill-switch denials.
35
42
  // SECURITY: blocked-paths runs before tool execution to prevent writes to protected paths.
36
- // Order (onion): audit session kill-switch tier policy blocked-paths → redact → [execute]
43
+ // SECURITY: injection runs PostToolUse (after redact) to scan downstream results for prompt injection.
44
+ // SECURITY: result-size-cap runs PostToolUse after injection so it caps already-scanned output.
45
+ // SECURITY: rate-limit runs after policy (so denied calls don't burn rate budget) but before execution.
46
+ // SECURITY: circuit-breaker wraps the execute step so it can observe Error status and track failures.
47
+ // Placed after rate-limit so a rate-limited call doesn't count as a downstream failure.
48
+ // Order (onion): audit → session → kill-switch → tier → policy → blocked-paths → rate-limit → circuit-breaker → redact → injection → result-size-cap → [execute]
49
+ const injectionAction = policy.injection_detection === 'warn'
50
+ ? 'warn'
51
+ : 'block';
52
+ const rateLimiter = new RateLimiter(gatewayConfig);
53
+ const circuitBreaker = new CircuitBreaker();
37
54
  const middlewares = [
38
55
  createAuditMiddleware(baseDir, policy),
39
56
  createSessionMiddleware(),
@@ -41,13 +58,22 @@ export async function startGateway(options) {
41
58
  createTierMiddleware(gatewayConfig),
42
59
  createPolicyMiddleware(policy, gatewayConfig, baseDir),
43
60
  createBlockedPathsMiddleware(policy, baseDir),
61
+ createRateLimitMiddleware(rateLimiter),
62
+ createCircuitBreakerMiddleware(circuitBreaker),
44
63
  redactMiddleware,
64
+ createInjectionMiddleware(injectionAction),
65
+ createResultSizeCapMiddleware(gatewayConfig),
45
66
  ];
46
67
  // Create gateway MCP server
47
68
  const gateway = new McpServer({ name: 'reagent', version: getPkgVersion() }, { capabilities: { tools: {} } });
48
69
  // Connect to downstream servers
49
70
  const clientManager = new ClientManager();
50
71
  await clientManager.connectAll(gatewayConfig);
72
+ // Detect tool name collisions before accepting connections (GHSA-4j9r)
73
+ const { collisions } = await detectToolCollisions(clientManager);
74
+ if (collisions.length > 0) {
75
+ console.error(`[reagent] ${collisions.length} tool name collision(s) detected — shadowed tools will be registered with server-prefixed names`);
76
+ }
51
77
  // Register native (first-party) tools
52
78
  const nativeCount = registerNativeTools(gateway, baseDir, middlewares);
53
79
  // Discover and register proxied tools
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/gateway/server.ts"],"names":[],"mappings":"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"}
@@ -53,7 +53,7 @@ export class ToolProxy {
53
53
  tool_name: tool.name,
54
54
  server_name: serverName,
55
55
  arguments: args,
56
- session_id: '',
56
+ session_id: crypto.randomUUID(),
57
57
  status: InvocationStatus.Allowed,
58
58
  start_time: Date.now(),
59
59
  metadata: {},
@@ -1 +1 @@
1
- {"version":3,"file":"tool-proxy.js","sourceRoot":"","sources":["../../src/gateway/tool-proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-proxy.js","sourceRoot":"","sources":["../../src/gateway/tool-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * DaemonConfig — global daemon settings loaded from ~/.reagent/daemon.yaml.
3
+ *
4
+ * This file is the source of truth for daemon configuration shape on the
5
+ * TypeScript side. The Rust daemon reads the same YAML file; keep field names
6
+ * in sync with daemon/src/config.rs.
7
+ */
8
+ export interface DaemonConfig {
9
+ /** TCP port the daemon listens on. Default: 7777 */
10
+ port: number;
11
+ /** Bind address. Default: '127.0.0.1' */
12
+ bind: string;
13
+ /** Idle session TTL in minutes. Default: 30 */
14
+ session_ttl_minutes: number;
15
+ /** Log verbosity passed to the Rust daemon via RUST_LOG. Default: 'info' */
16
+ log_level: 'debug' | 'info' | 'warn' | 'error';
17
+ /** Optional API key authentication for the daemon HTTP surface. */
18
+ auth?: DaemonAuth;
19
+ }
20
+ export interface DaemonAuth {
21
+ /** List of accepted bearer tokens. If empty or absent, auth is disabled. */
22
+ api_keys?: readonly string[];
23
+ }
24
+ /** Represents a single active session as returned by GET /sessions.
25
+ *
26
+ * Field names match the Rust SessionSummary struct in daemon/src/session.rs.
27
+ */
28
+ export interface DaemonSession {
29
+ session_id: string;
30
+ project_root: string;
31
+ /** Seconds elapsed since last MCP activity on this session. */
32
+ last_activity_elapsed_secs: number;
33
+ }
34
+ /** Shape of GET /health response body. */
35
+ export interface DaemonHealthResponse {
36
+ status: 'ok';
37
+ version: string;
38
+ sessions: number;
39
+ uptime_seconds: number;
40
+ }
41
+ /** Shape of GET /sessions response body. */
42
+ export interface DaemonSessionsResponse {
43
+ sessions: readonly DaemonSession[];
44
+ }
45
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/types/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,mEAAmE;IACnE,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CACpC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/types/daemon.ts"],"names":[],"mappings":""}
@@ -8,9 +8,18 @@ export interface DownstreamServer {
8
8
  args: string[];
9
9
  env?: Record<string, string>;
10
10
  tool_overrides?: Record<string, ToolOverride>;
11
+ /** Max concurrent in-flight calls to this server (0 = unlimited) */
12
+ max_concurrent_calls?: number;
13
+ /** Max calls per minute to this server (0 = unlimited) */
14
+ calls_per_minute?: number;
15
+ }
16
+ export interface GatewayOptions {
17
+ /** Cap on tool result size in KB. Results exceeding this are truncated. Default: 512 */
18
+ max_result_size_kb?: number;
11
19
  }
12
20
  export interface GatewayConfig {
13
21
  version: string;
14
22
  servers: Record<string, DownstreamServer>;
23
+ gateway?: GatewayOptions;
15
24
  }
16
25
  //# sourceMappingURL=gateway.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/types/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC3C"}
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/types/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9C,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,wFAAwF;IACxF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B"}
@@ -10,5 +10,6 @@ export interface Policy {
10
10
  block_ai_attribution: boolean;
11
11
  blocked_paths: string[];
12
12
  notification_channel: string;
13
+ injection_detection?: 'block' | 'warn';
13
14
  }
14
15
  //# sourceMappingURL=policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/types/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,aAAa,CAAC;IAC9B,kBAAkB,EAAE,aAAa,CAAC;IAClC,iCAAiC,EAAE,OAAO,CAAC;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/types/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,aAAa,CAAC;IAC9B,kBAAkB,EAAE,aAAa,CAAC;IAClC,iCAAiC,EAAE,OAAO,CAAC;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAE7B,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACxC"}
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+ # hooks/_lib/discord.sh — Discord notification helpers for local git hooks
3
+ # Source this file; do not execute it directly.
4
+ #
5
+ # Requires: curl (for webhook delivery), gateway.yaml (for channel config)
6
+ # Design: always silently no-ops when Discord isn't configured — hooks must
7
+ # never block or add perceptible latency because of a missing notification setup.
8
+
9
+ # Post an embed message to a Discord webhook.
10
+ # Usage: discord_notify <channel_type> <message> [<color>]
11
+ # channel_type: dev | alert | release | task
12
+ # color: green | red | yellow | blue (default: blue)
13
+ #
14
+ # Webhook resolution order:
15
+ # 1. REAGENT_DISCORD_WEBHOOK env var (overrides everything)
16
+ # 2. Per-channel env vars: REAGENT_DISCORD_WEBHOOK_DEV, _ALERT, _RELEASE, _TASK
17
+ # 3. gateway.yaml channel webhook entries (parsed with grep/awk, no jq needed)
18
+ #
19
+ # The curl call runs in the background so it never stalls the hook.
20
+ discord_notify() {
21
+ local channel_type="$1"
22
+ local message="$2"
23
+ local color="${3:-blue}"
24
+
25
+ # Bail immediately if curl isn't present — no point continuing
26
+ if ! command -v curl >/dev/null 2>&1; then
27
+ return 0
28
+ fi
29
+
30
+ local repo_root
31
+ repo_root="$(git rev-parse --show-toplevel 2>/dev/null)" || return 0
32
+
33
+ local gateway_yaml="${repo_root}/.reagent/gateway.yaml"
34
+
35
+ # Resolve webhook: env override first, then per-channel env, then gateway.yaml
36
+ local webhook="${REAGENT_DISCORD_WEBHOOK:-}"
37
+
38
+ if [ -z "$webhook" ]; then
39
+ local upper_type
40
+ upper_type="$(printf '%s' "$channel_type" | tr '[:lower:]' '[:upper:]')"
41
+ local env_var="REAGENT_DISCORD_WEBHOOK_${upper_type}"
42
+ webhook="${!env_var:-}"
43
+ fi
44
+
45
+ if [ -z "$webhook" ] && [ -f "$gateway_yaml" ]; then
46
+ # Expect a block like:
47
+ # dev_channel:
48
+ # webhook: "https://discord.com/api/webhooks/..."
49
+ webhook=$(grep -A2 "${channel_type}_channel:" "$gateway_yaml" 2>/dev/null \
50
+ | grep "webhook:" \
51
+ | awk '{print $2}' \
52
+ | tr -d '"'"'" 2>/dev/null || true)
53
+ fi
54
+
55
+ # Nothing configured for this channel — silent no-op
56
+ [ -z "$webhook" ] && return 0
57
+
58
+ local color_int
59
+ case "$color" in
60
+ green) color_int=3066993 ;;
61
+ red) color_int=15158332 ;;
62
+ yellow) color_int=16776960 ;;
63
+ *) color_int=3447003 ;; # blue
64
+ esac
65
+
66
+ # Escape the message for JSON: backslashes, double-quotes, and control chars
67
+ local escaped_message
68
+ escaped_message="$(printf '%s' "$message" | sed 's/\\/\\\\/g; s/"/\\"/g' 2>/dev/null || printf '%s' "$message")"
69
+
70
+ # Fire-and-forget: run in the background so the hook returns immediately
71
+ curl -s -X POST "$webhook" \
72
+ -H "Content-Type: application/json" \
73
+ -d "{\"embeds\":[{\"description\":\"${escaped_message}\",\"color\":${color_int}}]}" \
74
+ >/dev/null 2>&1 &
75
+ }
@@ -138,7 +138,6 @@ for blocked in "${BLOCKED_PATHS[@]}"; do
138
138
  # Glob pattern match (contains *)
139
139
  if [[ "$blocked" == *'*'* ]]; then
140
140
  # Convert glob to regex: . → \., * → .*
141
- local regex
142
141
  regex=$(printf '%s' "$LOWER_BLOCKED" | sed 's/\./\\./g; s/\*/.*/g')
143
142
  if printf '%s' "$LOWER_NORM" | grep -qE "^${regex}$"; then
144
143
  {
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env bash
2
+ # changeset-security-gate.sh — PreToolUse: Write|Edit
3
+ #
4
+ # Guards .changeset/*.md files against two failure modes:
5
+ #
6
+ # 1. SECURITY DISCLOSURE LEAK — GHSA IDs or CVE numbers written to a changeset
7
+ # file before the advisory is published. Changeset files are committed to git
8
+ # and appear verbatim in CHANGELOG.md — referencing a GHSA ID pre-publish
9
+ # creates public pre-disclosure in git history.
10
+ #
11
+ # 2. MISSING OR MALFORMED FRONTMATTER — changeset files without proper frontmatter
12
+ # are silently ignored by the changesets tool, wasting the release entry.
13
+ #
14
+ # Triggered by: PreToolUse — Write and Edit tools
15
+
16
+ set -euo pipefail
17
+
18
+ # shellcheck source=_lib/common.sh
19
+ source "$(dirname "$0")/_lib/common.sh"
20
+
21
+ check_halt
22
+
23
+ INPUT="$(cat)"
24
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
25
+
26
+ # Only handle Write and Edit
27
+ if [[ "$TOOL_NAME" != "Write" && "$TOOL_NAME" != "Edit" ]]; then
28
+ exit 0
29
+ fi
30
+
31
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
32
+
33
+ # Only care about .changeset/*.md files — exclude README.md (changeset tool metadata)
34
+ if ! echo "$FILE_PATH" | grep -qE '\.changeset/[^/]+\.md$' || echo "$FILE_PATH" | grep -qE '\.changeset/README\.md$'; then
35
+ exit 0
36
+ fi
37
+
38
+ require_jq
39
+
40
+ # Extract the content being written
41
+ if [[ "$TOOL_NAME" == "Write" ]]; then
42
+ CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // ""')
43
+ else
44
+ # For Edit: check the new_string being inserted
45
+ CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // ""')
46
+ fi
47
+
48
+ # ─── 1. SECURITY DISCLOSURE CHECK ───────────────────────────────────────────
49
+ #
50
+ # These patterns in a changeset mean security details are about to be committed
51
+ # to git history BEFORE the advisory is published — creating pre-disclosure.
52
+ # GHSA IDs and CVE numbers must NEVER appear in changeset files.
53
+
54
+ DISCLOSURE_PATTERNS=(
55
+ 'GHSA-[0-9A-Za-z]{4}-[0-9A-Za-z]{4}-[0-9A-Za-z]{4}'
56
+ 'CVE-[0-9]{4}-[0-9]+'
57
+ )
58
+
59
+ MATCHED_PATTERN=""
60
+ for PATTERN in "${DISCLOSURE_PATTERNS[@]}"; do
61
+ if echo "$CONTENT" | grep -qE "$PATTERN"; then
62
+ MATCHED_PATTERN="$PATTERN"
63
+ break
64
+ fi
65
+ done
66
+
67
+ if [[ -n "$MATCHED_PATTERN" ]]; then
68
+ json_output "block" \
69
+ "CHANGESET SECURITY GATE: This changeset contains a security advisory identifier (matched: '${MATCHED_PATTERN}').
70
+
71
+ Do NOT reference GHSA IDs or CVE numbers in changeset files before the advisory is published.
72
+ Changeset files are committed to git — this creates pre-disclosure in public history and CHANGELOG.
73
+
74
+ CORRECT approach for security fix changesets:
75
+ Use vague language only — no identifiers, no vulnerability details.
76
+
77
+ WRONG: 'fix(hooks): patch GHSA-3w3m-7gg4-f82g — symlink-guard now covers Edit tool'
78
+ RIGHT: 'security: extend symlink protection to cover all write-capable tools'
79
+
80
+ WRONG: 'security: fix CVE-2026-1234 prompt injection via tool descriptions'
81
+ RIGHT: 'security: harden middleware chain against indirect instruction attacks'
82
+
83
+ After the release ships:
84
+ 1. Publish the GitHub Security Advisory (Security tab → Advisories → Publish)
85
+ 2. The GHSA becomes the detailed public disclosure document
86
+ 3. Optionally update CHANGELOG.md post-publish to add the GHSA reference"
87
+ fi
88
+
89
+ # ─── 2. FRONTMATTER VALIDATION ───────────────────────────────────────────────
90
+ #
91
+ # A changeset without valid frontmatter is silently ignored by the changesets
92
+ # tool — the package bump and CHANGELOG entry never appear in the release.
93
+
94
+ # Must start with ---
95
+ if ! echo "$CONTENT" | head -1 | grep -qE '^---'; then
96
+ json_output "block" \
97
+ "CHANGESET FORMAT GATE: Missing frontmatter block.
98
+
99
+ Every changeset must start with a frontmatter block specifying which package to bump:
100
+
101
+ ---
102
+ '@bookedsolid/reagent': patch
103
+ ---
104
+
105
+ Brief description of what changed and why (close #N if applicable).
106
+
107
+ Bump types: patch (bug fix/security), minor (new feature), major (breaking change)"
108
+ fi
109
+
110
+ # Must have at least one package bump entry and a closing ---
111
+ FRONTMATTER=$(echo "$CONTENT" | awk '/^---/{count++; if(count==2){exit} next} count==1{print}')
112
+ if ! echo "$FRONTMATTER" | grep -qE "^'.+': (patch|minor|major)"; then
113
+ json_output "block" \
114
+ "CHANGESET FORMAT GATE: Frontmatter does not contain a valid package bump entry.
115
+
116
+ The frontmatter must include at least one package/bump pair:
117
+
118
+ ---
119
+ '@bookedsolid/reagent': patch
120
+ ---
121
+
122
+ Valid bump types: patch | minor | major"
123
+ fi
124
+
125
+ # Must have a non-empty description after the closing ---
126
+ DESCRIPTION=$(echo "$CONTENT" | awk 'BEGIN{count=0} /^---/{count++; next} count>=2{print}' | grep -v '^[[:space:]]*$' | head -1 || true)
127
+ if [[ -z "$DESCRIPTION" ]]; then
128
+ json_output "block" \
129
+ "CHANGESET FORMAT GATE: Missing description after frontmatter.
130
+
131
+ Add a meaningful description explaining what changed and why:
132
+
133
+ ---
134
+ '@bookedsolid/reagent': patch
135
+ ---
136
+
137
+ fix(gateway): policy-loader now uses async I/O with 500ms TTL cache
138
+
139
+ Previously, loadPolicy used fs.readFileSync on every tool invocation, blocking
140
+ the event loop under concurrency. Closes #34."
141
+ fi
142
+
143
+ exit 0
@@ -97,15 +97,23 @@ if [[ "$SCORE" == "trivial" ]]; then
97
97
  exit 0
98
98
  fi
99
99
 
100
- # ── 9. Standard check review cache ─────────────────────────────────────────
101
- if [[ "$SCORE" == "standard" ]]; then
100
+ # ── 9. Resolve reagent CLI (node_modules/.bin first, dist fallback) ───────────
101
+ REAGENT_CLI_ARGS=()
102
+ if [[ -f "${REAGENT_ROOT}/node_modules/.bin/reagent" ]]; then
103
+ REAGENT_CLI_ARGS=(node "${REAGENT_ROOT}/node_modules/.bin/reagent")
104
+ elif [[ -f "${REAGENT_ROOT}/dist/cli/index.js" ]]; then
105
+ REAGENT_CLI_ARGS=(node "${REAGENT_ROOT}/dist/cli/index.js")
106
+ fi
107
+
108
+ # ── 10. Standard + Significant → check review cache ───────────────────────────
109
+ if [[ "$SCORE" == "standard" ]] || [[ "$SCORE" == "significant" ]]; then
102
110
  # Compute SHA of staged content for cache lookup
103
111
  STAGED_SHA=$(cd "$REAGENT_ROOT" && git diff --cached | shasum -a 256 | cut -d' ' -f1 2>/dev/null || echo "")
104
112
  BRANCH=$(cd "$REAGENT_ROOT" && git branch --show-current 2>/dev/null || echo "")
105
113
 
106
- if [[ -n "$STAGED_SHA" ]]; then
114
+ if [[ -n "$STAGED_SHA" ]] && [[ ${#REAGENT_CLI_ARGS[@]} -gt 0 ]]; then
107
115
  # Check review cache via reagent CLI
108
- CACHE_RESULT=$(node "${REAGENT_ROOT}/node_modules/.bin/reagent" cache check "$STAGED_SHA" --branch "$BRANCH" 2>/dev/null || echo '{"hit":false}')
116
+ CACHE_RESULT=$("${REAGENT_CLI_ARGS[@]}" cache check "$STAGED_SHA" --branch "$BRANCH" 2>/dev/null || echo '{"hit":false}')
109
117
  if printf '%s' "$CACHE_RESULT" | jq -e '.hit == true' >/dev/null 2>&1; then
110
118
  exit 0
111
119
  fi
@@ -83,6 +83,20 @@ if printf '%s' "$CONTENT" | grep -qE "require\([^'\"][^)]*\)"; then
83
83
  WARNINGS+=("Dynamic require(variable) — loading modules by variable name can be exploited for path traversal. Prefer static imports.")
84
84
  fi
85
85
 
86
+ # ESM dynamic import() of dangerous modules: await import('child_process'), import('vm').then(...)
87
+ if printf '%s' "$CONTENT" | grep -qE "import\(['\"]child_process['\"]"; then
88
+ WARNINGS+=("import('child_process') — ESM dynamic import grants shell execution capability. Use safer alternatives or document the necessity.")
89
+ fi
90
+
91
+ if printf '%s' "$CONTENT" | grep -qE "import\(['\"]vm['\"]"; then
92
+ WARNINGS+=("import('vm') — ESM dynamic import of Node.js VM module allows dynamic code execution. Ensure input is fully trusted and sandboxed.")
93
+ fi
94
+
95
+ # Dynamic import() with a variable or template literal: import(variable), import(\`...\`)
96
+ if printf '%s' "$CONTENT" | grep -qE "import\([^'\"(][^)]*\)"; then
97
+ WARNINGS+=("Dynamic import(variable) — loading modules by variable name or template literal can be exploited for path traversal. Prefer static imports.")
98
+ fi
99
+
86
100
  if [[ ${#WARNINGS[@]} -eq 0 ]]; then
87
101
  exit 0
88
102
  fi
@@ -65,7 +65,25 @@ if printf '%s' "$CMD" | grep -qiE '(curl|wget).*-d[[:space:]]+@'; then
65
65
  exit 2
66
66
  fi
67
67
 
68
- # ── Check 3: Host allowlist ───────────────────────────────────────────────────
68
+ # ── Check 3: Shell variable URL interpolation ─────────────────────────────────
69
+ # Detect curl/wget with variable-interpolated URLs that cannot be inspected at hook time.
70
+ # Patterns: curl $VAR, curl ${VAR}, curl "$VAR/path", curl "${VAR}/api", wget $VAR, etc.
71
+ # Uses two sub-patterns:
72
+ # 1. Bare variable argument (space before $VAR, ends with space or EOL)
73
+ # 2. Quoted variable as URL start (space before "$VAR...")
74
+ if printf '%s' "$CMD" | grep -qiE '(curl|wget)[^|]*[[:space:]][$][{]?[A-Za-z_][A-Za-z0-9_]*[}]?([[:space:]]|$)' || \
75
+ printf '%s' "$CMD" | grep -qiE '(curl|wget)[^|]*[[:space:]]"[$][{]?[A-Za-z_][A-Za-z0-9_]*[}]?[^"]*"'; then
76
+ printf 'NETWORK-EXFIL-GUARD: Shell variable URL interpolation detected\n' >&2
77
+ printf ' Pattern: curl/wget with a shell variable as the URL argument\n' >&2
78
+ printf ' Command: %s\n' "$(printf '%s' "$CMD" | head -c 200)" >&2
79
+ printf 'Warning: The destination URL cannot be inspected at hook time because it is stored in a variable.\n' >&2
80
+ printf 'Please confirm the variable resolves to an allowlisted host before proceeding.\n' >&2
81
+ printf 'Allowlisted hosts: registry.npmjs.org, github.com, api.github.com, raw.githubusercontent.com\n' >&2
82
+ printf 'If you are certain the destination is safe, replace the variable with a literal URL.\n' >&2
83
+ exit 2
84
+ fi
85
+
86
+ # ── Check 4: Host allowlist ───────────────────────────────────────────────────
69
87
  ALLOWLIST=(
70
88
  "registry.npmjs.org"
71
89
  "github.com"
@@ -80,7 +98,7 @@ ALLOWLIST=(
80
98
  URLS=$(printf '%s' "$CMD" | grep -oE 'https?://[^[:space:]"'"'"']+' | head -20)
81
99
 
82
100
  if [[ -z "$URLS" ]]; then
83
- # No parseable URLs allow (could be a variable-based URL we can't inspect)
101
+ # No parseable literal URLs found (variable-based URLs already caught above)
84
102
  exit 0
85
103
  fi
86
104
 
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # pr-issue-link-gate.sh — PreToolUse: Bash
3
+ #
4
+ # Ensures every `gh pr create` command references at least one GitHub issue
5
+ # via closes/fixes/resolves #N syntax in the PR body. When the magic keyword
6
+ # is present, GitHub automatically closes the linked issue when the PR merges
7
+ # to the default branch and creates a cross-reference in the issue timeline.
8
+ #
9
+ # This gate is ADVISORY (exit 0) — it warns but does not block. Some PRs
10
+ # legitimately have no linked issue (chores, hotfixes, release PRs). The
11
+ # advisory gives the agent an opportunity to add the link before proceeding.
12
+ #
13
+ # Only active for Bash tool calls containing `gh pr create`.
14
+ # JSONL-only projects (no GitHub) are unaffected — gh is unavailable there.
15
+ #
16
+ # Triggered by: PreToolUse — Bash tool
17
+
18
+ set -euo pipefail
19
+
20
+ # shellcheck source=_lib/common.sh
21
+ source "$(dirname "$0")/_lib/common.sh"
22
+
23
+ check_halt
24
+
25
+ INPUT="$(cat)"
26
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
27
+
28
+ if [[ "$TOOL_NAME" != "Bash" ]]; then
29
+ exit 0
30
+ fi
31
+
32
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
33
+
34
+ # Only intercept gh pr create
35
+ if ! echo "$COMMAND" | grep -qE 'gh\s+pr\s+create'; then
36
+ exit 0
37
+ fi
38
+
39
+ require_jq
40
+
41
+ # Check for closing keywords followed by an issue number
42
+ # Accepted: closes #N, fixes #N, resolves #N (case-insensitive, any spacing)
43
+ if echo "$COMMAND" | grep -qiE '(closes|fixes|resolves)\s+#[0-9]+'; then
44
+ exit 0
45
+ fi
46
+
47
+ # Advisory — warn but do not block.
48
+ # Chore PRs, release PRs, and hotfixes may legitimately have no linked issue.
49
+ printf 'PR ISSUE LINK ADVISORY: This PR does not reference a GitHub issue.\n' >&2
50
+ printf '\n' >&2
51
+ printf 'When a PR body includes a closing reference, GitHub automatically:\n' >&2
52
+ printf ' - Closes the issue when the PR merges to the default branch\n' >&2
53
+ printf ' - Creates a cross-reference in the issue timeline\n' >&2
54
+ printf ' - Links the PR in the CHANGELOG context\n' >&2
55
+ printf '\n' >&2
56
+ printf 'Add to the --body:\n' >&2
57
+ printf ' closes #N closes one issue\n' >&2
58
+ printf ' fixes #N same effect\n' >&2
59
+ printf ' resolves #N same effect\n' >&2
60
+ printf ' closes #N, closes #M closes multiple issues\n' >&2
61
+ printf '\n' >&2
62
+ printf 'If this is a chore, release, or hotfix PR with no upstream issue, you may proceed.\n' >&2
63
+
64
+ # Exit 0 — advisory only, does not block the PR creation
65
+ exit 0
@@ -79,9 +79,24 @@ LINE_COUNT=$(printf '%s' "$DIFF_FULL" | grep -cE '^\+[^+]|^-[^-]' 2>/dev/null ||
79
79
  # ── 8. Check review cache ────────────────────────────────────────────────────
80
80
  PUSH_SHA=$(printf '%s' "$DIFF_FULL" | shasum -a 256 | cut -d' ' -f1 2>/dev/null || echo "")
81
81
 
82
- if [[ -n "$PUSH_SHA" ]]; then
83
- CACHE_RESULT=$(node "${REAGENT_ROOT}/node_modules/.bin/reagent" cache check "$PUSH_SHA" --branch "$CURRENT_BRANCH" --base "$TARGET_BRANCH" 2>/dev/null || echo '{"hit":false}')
82
+ # Resolve reagent CLI (node_modules/.bin first, dist fallback)
83
+ REAGENT_CLI_ARGS=()
84
+ if [[ -f "${REAGENT_ROOT}/node_modules/.bin/reagent" ]]; then
85
+ REAGENT_CLI_ARGS=(node "${REAGENT_ROOT}/node_modules/.bin/reagent")
86
+ elif [[ -f "${REAGENT_ROOT}/dist/cli/index.js" ]]; then
87
+ REAGENT_CLI_ARGS=(node "${REAGENT_ROOT}/dist/cli/index.js")
88
+ fi
89
+
90
+ if [[ -n "$PUSH_SHA" ]] && [[ ${#REAGENT_CLI_ARGS[@]} -gt 0 ]]; then
91
+ CACHE_RESULT=$("${REAGENT_CLI_ARGS[@]}" cache check "$PUSH_SHA" --branch "$CURRENT_BRANCH" --base "$TARGET_BRANCH" 2>/dev/null || echo '{"hit":false}')
84
92
  if printf '%s' "$CACHE_RESULT" | jq -e '.hit == true' >/dev/null 2>&1; then
93
+ # Review was already approved — notify and allow the push through
94
+ DISCORD_LIB="${REAGENT_ROOT}/hooks/_lib/discord.sh"
95
+ if [ -f "$DISCORD_LIB" ]; then
96
+ # shellcheck source=/dev/null
97
+ source "$DISCORD_LIB"
98
+ discord_notify "dev" "Push passed quality gates on \`${CURRENT_BRANCH}\` -- $(cd "$REAGENT_ROOT" && git log -1 --oneline 2>/dev/null)" "green"
99
+ fi
85
100
  exit 0
86
101
  fi
87
102
  fi