agentlock-shared 0.1.0 → 0.3.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 (171) hide show
  1. package/dist/__tests__/billing.test.d.ts +2 -0
  2. package/dist/__tests__/billing.test.d.ts.map +1 -0
  3. package/dist/__tests__/billing.test.js +31 -0
  4. package/dist/__tests__/billing.test.js.map +1 -0
  5. package/dist/__tests__/crypto.test.js +137 -47
  6. package/dist/__tests__/crypto.test.js.map +1 -1
  7. package/dist/__tests__/dns-pinning.test.d.ts +2 -0
  8. package/dist/__tests__/dns-pinning.test.d.ts.map +1 -0
  9. package/dist/__tests__/dns-pinning.test.js +33 -0
  10. package/dist/__tests__/dns-pinning.test.js.map +1 -0
  11. package/dist/__tests__/llm-classifier-cache-store.test.d.ts +2 -0
  12. package/dist/__tests__/llm-classifier-cache-store.test.d.ts.map +1 -0
  13. package/dist/__tests__/llm-classifier-cache-store.test.js +65 -0
  14. package/dist/__tests__/llm-classifier-cache-store.test.js.map +1 -0
  15. package/dist/__tests__/llm-classifier-cache.test.d.ts +2 -0
  16. package/dist/__tests__/llm-classifier-cache.test.d.ts.map +1 -0
  17. package/dist/__tests__/llm-classifier-cache.test.js +44 -0
  18. package/dist/__tests__/llm-classifier-cache.test.js.map +1 -0
  19. package/dist/__tests__/llm-classifier.test.d.ts +2 -0
  20. package/dist/__tests__/llm-classifier.test.d.ts.map +1 -0
  21. package/dist/__tests__/llm-classifier.test.js +167 -0
  22. package/dist/__tests__/llm-classifier.test.js.map +1 -0
  23. package/dist/__tests__/messaging.test.d.ts +2 -0
  24. package/dist/__tests__/messaging.test.d.ts.map +1 -0
  25. package/dist/__tests__/messaging.test.js +75 -0
  26. package/dist/__tests__/messaging.test.js.map +1 -0
  27. package/dist/__tests__/plans-classifier-limits.test.d.ts +2 -0
  28. package/dist/__tests__/plans-classifier-limits.test.d.ts.map +1 -0
  29. package/dist/__tests__/plans-classifier-limits.test.js +22 -0
  30. package/dist/__tests__/plans-classifier-limits.test.js.map +1 -0
  31. package/dist/__tests__/policy-category-floor.test.d.ts +2 -0
  32. package/dist/__tests__/policy-category-floor.test.d.ts.map +1 -0
  33. package/dist/__tests__/policy-category-floor.test.js +46 -0
  34. package/dist/__tests__/policy-category-floor.test.js.map +1 -0
  35. package/dist/__tests__/policy-claude-bash.test.d.ts +2 -0
  36. package/dist/__tests__/policy-claude-bash.test.d.ts.map +1 -0
  37. package/dist/__tests__/policy-claude-bash.test.js +401 -0
  38. package/dist/__tests__/policy-claude-bash.test.js.map +1 -0
  39. package/dist/__tests__/policy-llm-floor.test.d.ts +2 -0
  40. package/dist/__tests__/policy-llm-floor.test.d.ts.map +1 -0
  41. package/dist/__tests__/policy-llm-floor.test.js +107 -0
  42. package/dist/__tests__/policy-llm-floor.test.js.map +1 -0
  43. package/dist/__tests__/policy-ssh-e2e.test.d.ts +2 -0
  44. package/dist/__tests__/policy-ssh-e2e.test.d.ts.map +1 -0
  45. package/dist/__tests__/policy-ssh-e2e.test.js +89 -0
  46. package/dist/__tests__/policy-ssh-e2e.test.js.map +1 -0
  47. package/dist/__tests__/policy-ssh-sessions.test.d.ts +2 -0
  48. package/dist/__tests__/policy-ssh-sessions.test.d.ts.map +1 -0
  49. package/dist/__tests__/policy-ssh-sessions.test.js +139 -0
  50. package/dist/__tests__/policy-ssh-sessions.test.js.map +1 -0
  51. package/dist/__tests__/policy-ssh.test.d.ts +2 -0
  52. package/dist/__tests__/policy-ssh.test.d.ts.map +1 -0
  53. package/dist/__tests__/policy-ssh.test.js +180 -0
  54. package/dist/__tests__/policy-ssh.test.js.map +1 -0
  55. package/dist/__tests__/policy.test.js +522 -7
  56. package/dist/__tests__/policy.test.js.map +1 -1
  57. package/dist/__tests__/redact.test.js +76 -0
  58. package/dist/__tests__/redact.test.js.map +1 -1
  59. package/dist/__tests__/signing.test.js +89 -0
  60. package/dist/__tests__/signing.test.js.map +1 -1
  61. package/dist/__tests__/ssh-fingerprint.test.d.ts +2 -0
  62. package/dist/__tests__/ssh-fingerprint.test.d.ts.map +1 -0
  63. package/dist/__tests__/ssh-fingerprint.test.js +19 -0
  64. package/dist/__tests__/ssh-fingerprint.test.js.map +1 -0
  65. package/dist/__tests__/vpn-route.test.d.ts +2 -0
  66. package/dist/__tests__/vpn-route.test.d.ts.map +1 -0
  67. package/dist/__tests__/vpn-route.test.js +72 -0
  68. package/dist/__tests__/vpn-route.test.js.map +1 -0
  69. package/dist/__tests__/wireguard.test.d.ts +2 -0
  70. package/dist/__tests__/wireguard.test.d.ts.map +1 -0
  71. package/dist/__tests__/wireguard.test.js +114 -0
  72. package/dist/__tests__/wireguard.test.js.map +1 -0
  73. package/dist/billing.d.ts +12 -0
  74. package/dist/billing.d.ts.map +1 -0
  75. package/dist/billing.js +41 -0
  76. package/dist/billing.js.map +1 -0
  77. package/dist/crypto.d.ts +41 -0
  78. package/dist/crypto.d.ts.map +1 -1
  79. package/dist/crypto.js +208 -6
  80. package/dist/crypto.js.map +1 -1
  81. package/dist/dns-pinning.d.ts +28 -0
  82. package/dist/dns-pinning.d.ts.map +1 -0
  83. package/dist/dns-pinning.js +113 -0
  84. package/dist/dns-pinning.js.map +1 -0
  85. package/dist/index.d.ts +6 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +9 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/llm-classifier-cache-store.d.ts +49 -0
  90. package/dist/llm-classifier-cache-store.d.ts.map +1 -0
  91. package/dist/llm-classifier-cache-store.js +63 -0
  92. package/dist/llm-classifier-cache-store.js.map +1 -0
  93. package/dist/llm-classifier-cache.d.ts +6 -0
  94. package/dist/llm-classifier-cache.d.ts.map +1 -0
  95. package/dist/llm-classifier-cache.js +52 -0
  96. package/dist/llm-classifier-cache.js.map +1 -0
  97. package/dist/llm-classifier.d.ts +29 -0
  98. package/dist/llm-classifier.d.ts.map +1 -0
  99. package/dist/llm-classifier.js +191 -0
  100. package/dist/llm-classifier.js.map +1 -0
  101. package/dist/observability.d.ts +36 -0
  102. package/dist/observability.d.ts.map +1 -0
  103. package/dist/observability.js +75 -0
  104. package/dist/observability.js.map +1 -0
  105. package/dist/plans.d.ts +21 -0
  106. package/dist/plans.d.ts.map +1 -1
  107. package/dist/plans.js +52 -14
  108. package/dist/plans.js.map +1 -1
  109. package/dist/policy.d.ts +173 -3
  110. package/dist/policy.d.ts.map +1 -1
  111. package/dist/policy.js +951 -58
  112. package/dist/policy.js.map +1 -1
  113. package/dist/redact.d.ts.map +1 -1
  114. package/dist/redact.js +104 -7
  115. package/dist/redact.js.map +1 -1
  116. package/dist/regex-safety.d.ts +21 -0
  117. package/dist/regex-safety.d.ts.map +1 -0
  118. package/dist/regex-safety.js +49 -0
  119. package/dist/regex-safety.js.map +1 -0
  120. package/dist/sanitize.d.ts +31 -0
  121. package/dist/sanitize.d.ts.map +1 -0
  122. package/dist/sanitize.js +54 -0
  123. package/dist/sanitize.js.map +1 -0
  124. package/dist/schemas.d.ts +267 -14
  125. package/dist/schemas.d.ts.map +1 -1
  126. package/dist/schemas.js +152 -10
  127. package/dist/schemas.js.map +1 -1
  128. package/dist/signing.d.ts +15 -0
  129. package/dist/signing.d.ts.map +1 -1
  130. package/dist/signing.js +53 -4
  131. package/dist/signing.js.map +1 -1
  132. package/dist/ssh-fingerprint.d.ts +10 -0
  133. package/dist/ssh-fingerprint.d.ts.map +1 -0
  134. package/dist/ssh-fingerprint.js +52 -0
  135. package/dist/ssh-fingerprint.js.map +1 -0
  136. package/dist/ssrf.d.ts +36 -0
  137. package/dist/ssrf.d.ts.map +1 -0
  138. package/dist/ssrf.js +140 -0
  139. package/dist/ssrf.js.map +1 -0
  140. package/dist/types.d.ts +131 -0
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/wireguard.d.ts +63 -0
  143. package/dist/wireguard.d.ts.map +1 -0
  144. package/dist/wireguard.js +226 -0
  145. package/dist/wireguard.js.map +1 -0
  146. package/package.json +42 -29
  147. package/.turbo/turbo-build.log +0 -4
  148. package/.turbo/turbo-test.log +0 -34
  149. package/dist/__tests__/content-crypto.test.d.ts +0 -2
  150. package/dist/__tests__/content-crypto.test.d.ts.map +0 -1
  151. package/dist/__tests__/content-crypto.test.js +0 -117
  152. package/dist/__tests__/content-crypto.test.js.map +0 -1
  153. package/dist/content-crypto.d.ts +0 -24
  154. package/dist/content-crypto.d.ts.map +0 -1
  155. package/dist/content-crypto.js +0 -58
  156. package/dist/content-crypto.js.map +0 -1
  157. package/src/__tests__/policy.test.ts +0 -88
  158. package/src/__tests__/redact.test.ts +0 -41
  159. package/src/__tests__/signing.test.ts +0 -55
  160. package/src/crypto.ts +0 -87
  161. package/src/index.ts +0 -8
  162. package/src/mcp-catalog.ts +0 -181
  163. package/src/plans.ts +0 -96
  164. package/src/policy.ts +0 -186
  165. package/src/redact.ts +0 -114
  166. package/src/schemas.ts +0 -53
  167. package/src/signing.ts +0 -120
  168. package/src/types.ts +0 -212
  169. package/test-gateway.mjs +0 -47
  170. package/tsconfig.json +0 -10
  171. package/vitest.config.ts +0 -8
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const llm_classifier_js_1 = require("../llm-classifier.js");
5
+ const llm_classifier_cache_store_js_1 = require("../llm-classifier-cache-store.js");
6
+ function mockClassifier(result) {
7
+ return async () => {
8
+ if (result instanceof Error)
9
+ throw result;
10
+ return result;
11
+ };
12
+ }
13
+ (0, vitest_1.describe)('classifyWithLLM', () => {
14
+ (0, vitest_1.beforeEach)(() => {
15
+ (0, llm_classifier_cache_store_js_1.resetClassifierCacheStoreForTest)();
16
+ (0, llm_classifier_js_1.__setClassifierForTest)(null); // reset to default
17
+ });
18
+ (0, vitest_1.it)('returns null when no API key is configured (env var missing)', async () => {
19
+ const original = process.env.OPENROUTER_API_KEY;
20
+ delete process.env.OPENROUTER_API_KEY;
21
+ try {
22
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('unknown.tool', { foo: 'bar' });
23
+ (0, vitest_1.expect)(result).toBeNull();
24
+ }
25
+ finally {
26
+ if (original !== undefined)
27
+ process.env.OPENROUTER_API_KEY = original;
28
+ }
29
+ });
30
+ (0, vitest_1.it)('returns classification from injected classifier', async () => {
31
+ (0, llm_classifier_js_1.__setClassifierForTest)(mockClassifier({
32
+ category: 'write',
33
+ reason: 'Tool name suggests a mutation',
34
+ confidence: 0.88,
35
+ model: 'google/gemini-2.5-flash-lite',
36
+ }));
37
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('notion.update_page', { pageId: 'abc' });
38
+ (0, vitest_1.expect)(result).not.toBeNull();
39
+ (0, vitest_1.expect)(result?.category).toBe('write');
40
+ (0, vitest_1.expect)(result?.cached).toBe(false);
41
+ });
42
+ (0, vitest_1.it)('caches results — same shape hits, different shape misses', async () => {
43
+ const spy = vitest_1.vi.fn(mockClassifier({
44
+ category: 'admin',
45
+ reason: 'Delete user action',
46
+ confidence: 0.97,
47
+ model: 'google/gemini-2.5-flash-lite',
48
+ }));
49
+ (0, llm_classifier_js_1.__setClassifierForTest)(spy);
50
+ // Same shape — r2 is a cache hit
51
+ const r1 = await (0, llm_classifier_js_1.classifyWithLLM)('custom.delete_user', { userId: 'user-1' });
52
+ const r2 = await (0, llm_classifier_js_1.classifyWithLLM)('custom.delete_user', { userId: 'user-2' });
53
+ (0, vitest_1.expect)(r1?.cached).toBe(false);
54
+ (0, vitest_1.expect)(r2?.cached).toBe(true);
55
+ (0, vitest_1.expect)(r2?.category).toBe('admin');
56
+ (0, vitest_1.expect)(spy).toHaveBeenCalledTimes(1);
57
+ // Different shape — r3 is a cache MISS, spy called again
58
+ const r3 = await (0, llm_classifier_js_1.classifyWithLLM)('custom.delete_user', {
59
+ userId: 'user-3',
60
+ force: true,
61
+ });
62
+ (0, vitest_1.expect)(r3?.cached).toBe(false);
63
+ (0, vitest_1.expect)(spy).toHaveBeenCalledTimes(2);
64
+ });
65
+ (0, vitest_1.it)('returns null (graceful fallback) when classifier throws', async () => {
66
+ (0, llm_classifier_js_1.__setClassifierForTest)(mockClassifier(new Error('OpenRouter 503')));
67
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('unknown.tool', {});
68
+ (0, vitest_1.expect)(result).toBeNull();
69
+ });
70
+ (0, vitest_1.it)('returns null (graceful fallback) when classifier returns null', async () => {
71
+ (0, llm_classifier_js_1.__setClassifierForTest)(mockClassifier(null));
72
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('unknown.tool', {});
73
+ (0, vitest_1.expect)(result).toBeNull();
74
+ });
75
+ (0, vitest_1.it)('enforces a hard timeout (does not wait forever)', async () => {
76
+ (0, llm_classifier_js_1.__setClassifierForTest)(async () => {
77
+ await new Promise((r) => setTimeout(r, 5000));
78
+ return null;
79
+ });
80
+ const start = Date.now();
81
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('slow.tool', {}, { timeoutMs: 100 });
82
+ const elapsed = Date.now() - start;
83
+ (0, vitest_1.expect)(result).toBeNull();
84
+ (0, vitest_1.expect)(elapsed).toBeLessThan(200); // timeout was 100ms, give some wiggle room
85
+ });
86
+ (0, vitest_1.it)('does not leak errors — just returns null', async () => {
87
+ (0, llm_classifier_js_1.__setClassifierForTest)(async () => {
88
+ throw new Error('Unexpected error');
89
+ });
90
+ await (0, vitest_1.expect)((0, llm_classifier_js_1.classifyWithLLM)('tool', {})).resolves.toBeNull();
91
+ });
92
+ (0, vitest_1.it)('never downgrades — a "read" response is still returned as read', async () => {
93
+ // The caller (evaluatePolicy) applies max(declared, staticFloor, llmFloor).
94
+ // This test just confirms the classifier faithfully returns whatever the
95
+ // LLM said; downgrade protection is a policy-layer concern.
96
+ (0, llm_classifier_js_1.__setClassifierForTest)(mockClassifier({
97
+ category: 'read',
98
+ reason: 'Looks like a read-only lookup',
99
+ confidence: 0.6,
100
+ model: 'google/gemini-2.5-flash-lite',
101
+ }));
102
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('some.tool', {});
103
+ (0, vitest_1.expect)(result?.category).toBe('read');
104
+ });
105
+ (0, vitest_1.it)('shapeOnly strips raw values from payloads — no values leak to the LLM', async () => {
106
+ const { shapeOnly } = await import('../llm-classifier.js');
107
+ const result = shapeOnly({
108
+ apiKey: 'sk-live-SECRET-DO-NOT-LEAK',
109
+ email: 'user@example.com',
110
+ amount: 999.99,
111
+ nested: { card: '4242-4242-4242-4242', count: 7 },
112
+ tags: ['alpha', 'beta'],
113
+ });
114
+ const serialized = JSON.stringify(result);
115
+ // Raw values must not appear
116
+ (0, vitest_1.expect)(serialized).not.toContain('sk-live-SECRET-DO-NOT-LEAK');
117
+ (0, vitest_1.expect)(serialized).not.toContain('user@example.com');
118
+ (0, vitest_1.expect)(serialized).not.toContain('999.99');
119
+ (0, vitest_1.expect)(serialized).not.toContain('4242');
120
+ (0, vitest_1.expect)(serialized).not.toContain('alpha');
121
+ // Keys ARE preserved
122
+ (0, vitest_1.expect)(serialized).toContain('apiKey');
123
+ (0, vitest_1.expect)(serialized).toContain('email');
124
+ (0, vitest_1.expect)(serialized).toContain('nested');
125
+ // Type descriptors ARE present
126
+ (0, vitest_1.expect)(serialized).toContain('<string>');
127
+ (0, vitest_1.expect)(serialized).toContain('<number>');
128
+ });
129
+ });
130
+ // ---------------------------------------------------------------------------
131
+ // Opt-in integration test — calls the real OpenRouter API.
132
+ // Skipped unless INTEGRATION=1 is set (pnpm test:integration runs with it).
133
+ // ---------------------------------------------------------------------------
134
+ vitest_1.describe.skipIf(process.env.INTEGRATION !== '1')('classifyWithLLM — OpenRouter integration', () => {
135
+ (0, vitest_1.beforeEach)(() => {
136
+ (0, llm_classifier_cache_store_js_1.resetClassifierCacheStoreForTest)();
137
+ (0, llm_classifier_js_1.__setClassifierForTest)(null); // use the real classifier
138
+ });
139
+ (0, vitest_1.it)('classifies notion.delete_workspace_page as write or admin', async () => {
140
+ if (!process.env.OPENROUTER_API_KEY) {
141
+ throw new Error('OPENROUTER_API_KEY not set — cannot run integration test');
142
+ }
143
+ // 5s timeout (vs. the 800ms production default) because cold-start latency
144
+ // to OpenRouter can exceed 800ms on the first real call of a test run.
145
+ // This test validates classification correctness, not the timeout mechanism —
146
+ // that's covered by the mocked unit tests.
147
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('notion.delete_workspace_page', {
148
+ pageId: '<string>',
149
+ permanent: '<boolean>',
150
+ }, { timeoutMs: 5000 });
151
+ (0, vitest_1.expect)(result).not.toBeNull();
152
+ (0, vitest_1.expect)(['write', 'admin']).toContain(result?.category);
153
+ (0, vitest_1.expect)(result?.reason.length).toBeGreaterThan(0);
154
+ (0, vitest_1.expect)(result?.model).toContain('gemini');
155
+ }, 10_000);
156
+ (0, vitest_1.it)('classifies unknown.read_user_profile as read', async () => {
157
+ if (!process.env.OPENROUTER_API_KEY) {
158
+ throw new Error('OPENROUTER_API_KEY not set — cannot run integration test');
159
+ }
160
+ const result = await (0, llm_classifier_js_1.classifyWithLLM)('unknown.read_user_profile', {
161
+ userId: '<string>',
162
+ }, { timeoutMs: 5000 });
163
+ (0, vitest_1.expect)(result).not.toBeNull();
164
+ (0, vitest_1.expect)(result?.category).toBe('read');
165
+ }, 10_000);
166
+ });
167
+ //# sourceMappingURL=llm-classifier.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-classifier.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-classifier.test.ts"],"names":[],"mappings":";;AAAA,mCAA8D;AAC9D,4DAA+E;AAC/E,oFAAoF;AAKpF,SAAS,cAAc,CAAC,MAAwD;IAC9E,OAAO,KAAK,IAAI,EAAE;QAChB,IAAI,MAAM,YAAY,KAAK;YAAE,MAAM,MAAM,CAAC;QAC1C,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED,IAAA,iBAAQ,EAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAA,mBAAU,EAAC,GAAG,EAAE;QACd,IAAA,gEAAgC,GAAE,CAAC;QACnC,IAAA,0CAAsB,EAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB;IACnD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAChD,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAAC,cAAc,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;YACrE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACT,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,QAAQ,CAAC;QACxE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,IAAA,0CAAsB,EAAC,cAAc,CAAC;YACpC,QAAQ,EAAE,OAAO;YACjB,MAAM,EAAE,+BAA+B;YACvC,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,8BAA8B;SACtC,CAAC,CAAC,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAA,eAAM,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,IAAA,eAAM,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,GAAG,GAAG,WAAE,CAAC,EAAE,CAAC,cAAc,CAAC;YAC/B,QAAQ,EAAE,OAAO;YACjB,MAAM,EAAE,oBAAoB;YAC5B,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,8BAA8B;SACtC,CAAC,CAAC,CAAC;QACJ,IAAA,0CAAsB,EAAC,GAAG,CAAC,CAAC;QAE5B,iCAAiC;QACjC,MAAM,EAAE,GAAG,MAAM,IAAA,mCAAe,EAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,MAAM,EAAE,GAAG,MAAM,IAAA,mCAAe,EAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE7E,IAAA,eAAM,EAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAA,eAAM,EAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAErC,yDAAyD;QACzD,MAAM,EAAE,GAAG,MAAM,IAAA,mCAAe,EAAC,oBAAoB,EAAE;YACrD,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QACH,IAAA,eAAM,EAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,IAAA,0CAAsB,EAAC,cAAc,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACzD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,IAAA,0CAAsB,EAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACzD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,IAAA,0CAAsB,EAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAAC,WAAW,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACnC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1B,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,2CAA2C;IAChF,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,IAAA,0CAAsB,EAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QACH,MAAM,IAAA,eAAM,EAAC,IAAA,mCAAe,EAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,4EAA4E;QAC5E,yEAAyE;QACzE,4DAA4D;QAC5D,IAAA,0CAAsB,EAAC,cAAc,CAAC;YACpC,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,+BAA+B;YACvC,UAAU,EAAE,GAAG;YACf,KAAK,EAAE,8BAA8B;SACtC,CAAC,CAAC,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACtD,IAAA,eAAM,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,SAAS,CAAC;YACvB,MAAM,EAAE,4BAA4B;YACpC,KAAK,EAAE,kBAAkB;YACzB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE;YACjD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1C,6BAA6B;QAC7B,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QAC/D,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACrD,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1C,qBAAqB;QACrB,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACvC,+BAA+B;QAC/B,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,2DAA2D;AAC3D,4EAA4E;AAC5E,8EAA8E;AAC9E,iBAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,0CAA0C,EAAE,GAAG,EAAE;IAChG,IAAA,mBAAU,EAAC,GAAG,EAAE;QACd,IAAA,gEAAgC,GAAE,CAAC;QACnC,IAAA,0CAAsB,EAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B;IAC1D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,2EAA2E;QAC3E,uEAAuE;QACvE,8EAA8E;QAC9E,2CAA2C;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAClC,8BAA8B,EAC9B;YACE,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,WAAW;SACvB,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;QACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAA,eAAM,EAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvD,IAAA,eAAM,EAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC,EAAE,MAAM,CAAC,CAAC;IAEX,IAAA,WAAE,EAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAe,EAClC,2BAA2B,EAC3B;YACE,MAAM,EAAE,UAAU;SACnB,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;QACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAA,eAAM,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=messaging.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/messaging.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const schemas_1 = require("../schemas");
5
+ (0, vitest_1.describe)('SendMessageSchema', () => {
6
+ (0, vitest_1.it)('accepts valid message with content only', () => {
7
+ const result = schemas_1.SendMessageSchema.safeParse({ content: 'Hello agent' });
8
+ (0, vitest_1.expect)(result.success).toBe(true);
9
+ });
10
+ (0, vitest_1.it)('accepts message with thread_id and expires_at', () => {
11
+ const result = schemas_1.SendMessageSchema.safeParse({
12
+ content: 'Do this task',
13
+ thread_id: '550e8400-e29b-41d4-a716-446655440000',
14
+ expires_at: '2026-04-01T12:00:00Z',
15
+ });
16
+ (0, vitest_1.expect)(result.success).toBe(true);
17
+ });
18
+ (0, vitest_1.it)('rejects empty content', () => {
19
+ const result = schemas_1.SendMessageSchema.safeParse({ content: '' });
20
+ (0, vitest_1.expect)(result.success).toBe(false);
21
+ });
22
+ (0, vitest_1.it)('rejects content over 4096 chars', () => {
23
+ const result = schemas_1.SendMessageSchema.safeParse({ content: 'x'.repeat(4097) });
24
+ (0, vitest_1.expect)(result.success).toBe(false);
25
+ });
26
+ (0, vitest_1.it)('rejects invalid thread_id', () => {
27
+ const result = schemas_1.SendMessageSchema.safeParse({ content: 'hi', thread_id: 'not-a-uuid' });
28
+ (0, vitest_1.expect)(result.success).toBe(false);
29
+ });
30
+ });
31
+ (0, vitest_1.describe)('AgentSendMessageSchema', () => {
32
+ (0, vitest_1.it)('requires thread_id', () => {
33
+ const result = schemas_1.AgentSendMessageSchema.safeParse({ content: 'Reply' });
34
+ (0, vitest_1.expect)(result.success).toBe(false);
35
+ });
36
+ (0, vitest_1.it)('accepts valid reply', () => {
37
+ const result = schemas_1.AgentSendMessageSchema.safeParse({
38
+ content: 'I found 3 files',
39
+ thread_id: '550e8400-e29b-41d4-a716-446655440000',
40
+ });
41
+ (0, vitest_1.expect)(result.success).toBe(true);
42
+ });
43
+ });
44
+ (0, vitest_1.describe)('ApproveRequestSchema with reply_message', () => {
45
+ (0, vitest_1.it)('accepts approve without reply', () => {
46
+ const result = schemas_1.ApproveRequestSchema.safeParse({ action: 'approve' });
47
+ (0, vitest_1.expect)(result.success).toBe(true);
48
+ });
49
+ (0, vitest_1.it)('accepts approve with reply_message', () => {
50
+ const result = schemas_1.ApproveRequestSchema.safeParse({
51
+ action: 'approve',
52
+ reply_message: 'Only delete files older than 7 days',
53
+ });
54
+ (0, vitest_1.expect)(result.success).toBe(true);
55
+ if (result.success) {
56
+ (0, vitest_1.expect)(result.data.reply_message).toBe('Only delete files older than 7 days');
57
+ }
58
+ });
59
+ (0, vitest_1.it)('accepts deny with reason and reply_message', () => {
60
+ const result = schemas_1.ApproveRequestSchema.safeParse({
61
+ action: 'deny',
62
+ reason: 'Too risky',
63
+ reply_message: 'Try a safer approach',
64
+ });
65
+ (0, vitest_1.expect)(result.success).toBe(true);
66
+ });
67
+ (0, vitest_1.it)('rejects reply_message over 2000 chars', () => {
68
+ const result = schemas_1.ApproveRequestSchema.safeParse({
69
+ action: 'approve',
70
+ reply_message: 'x'.repeat(2001),
71
+ });
72
+ (0, vitest_1.expect)(result.success).toBe(false);
73
+ });
74
+ });
75
+ //# sourceMappingURL=messaging.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging.test.js","sourceRoot":"","sources":["../../src/__tests__/messaging.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plans-classifier-limits.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-classifier-limits.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/plans-classifier-limits.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const plans_js_1 = require("../plans.js");
5
+ (0, vitest_1.describe)('plans — classifier quota', () => {
6
+ (0, vitest_1.it)('free plan has 0 classifier calls per month', () => {
7
+ (0, vitest_1.expect)(plans_js_1.PLANS.free.classifierCallsPerMonth).toBe(0);
8
+ (0, vitest_1.expect)((0, plans_js_1.getPlanLimits)('free').classifierCallsPerMonth).toBe(0);
9
+ });
10
+ (0, vitest_1.it)('pro plan has 1000 classifier calls per month', () => {
11
+ (0, vitest_1.expect)(plans_js_1.PLANS.pro.classifierCallsPerMonth).toBe(1000);
12
+ (0, vitest_1.expect)((0, plans_js_1.getPlanLimits)('pro').classifierCallsPerMonth).toBe(1000);
13
+ });
14
+ (0, vitest_1.it)('team plan has 10000 classifier calls per month', () => {
15
+ (0, vitest_1.expect)(plans_js_1.PLANS.team.classifierCallsPerMonth).toBe(10000);
16
+ (0, vitest_1.expect)((0, plans_js_1.getPlanLimits)('team').classifierCallsPerMonth).toBe(10000);
17
+ });
18
+ (0, vitest_1.it)('getPlanLimits falls back to free quota for unknown plans', () => {
19
+ (0, vitest_1.expect)((0, plans_js_1.getPlanLimits)('mystery').classifierCallsPerMonth).toBe(0);
20
+ });
21
+ });
22
+ //# sourceMappingURL=plans-classifier-limits.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-classifier-limits.test.js","sourceRoot":"","sources":["../../src/__tests__/plans-classifier-limits.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,0CAAmD;AAEnD,IAAA,iBAAQ,EAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,IAAA,eAAM,EAAC,gBAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnD,IAAA,eAAM,EAAC,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,IAAA,eAAM,EAAC,gBAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,IAAA,eAAM,EAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,IAAA,eAAM,EAAC,gBAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,IAAA,eAAM,EAAC,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,IAAA,eAAM,EAAC,IAAA,wBAAa,EAAC,SAAS,CAAC,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=policy-category-floor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-category-floor.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/policy-category-floor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const policy_js_1 = require("../policy.js");
5
+ const baseAction = (overrides = {}) => ({
6
+ action_type: 'read',
7
+ tool: 'unknown.tool',
8
+ payload: {},
9
+ ...overrides,
10
+ });
11
+ // The static category floor is the only anti-downgrade layer (the LLM
12
+ // classifier and its upgrade-only llmFloor option were removed 2026-06-12).
13
+ (0, vitest_1.describe)('evaluatePolicy - static category floor', () => {
14
+ (0, vitest_1.it)('keeps a known read-floor tool at read', () => {
15
+ const action = baseAction({ tool: 'mcp.list_tools' });
16
+ const result = (0, policy_js_1.evaluatePolicy)(action, policy_js_1.DEFAULT_POLICY_RULES);
17
+ (0, vitest_1.expect)(result.effective_action_type).toBe('read');
18
+ });
19
+ (0, vitest_1.it)('floors unrecognised tools to write (fail-closed)', () => {
20
+ const action = baseAction({ action_type: 'read', tool: 'unknown.tool' });
21
+ const result = (0, policy_js_1.evaluatePolicy)(action, policy_js_1.DEFAULT_POLICY_RULES);
22
+ (0, vitest_1.expect)(result.effective_action_type).toBe('write');
23
+ (0, vitest_1.expect)(result.decision).toBe('REQUIRE_APPROVAL');
24
+ (0, vitest_1.expect)(result.reason).toContain('category floored');
25
+ });
26
+ (0, vitest_1.it)('floors a declared read on a financial tool to financial', () => {
27
+ const action = baseAction({ action_type: 'read', tool: 'stripe.charge' });
28
+ const result = (0, policy_js_1.evaluatePolicy)(action, policy_js_1.DEFAULT_POLICY_RULES);
29
+ (0, vitest_1.expect)(result.effective_action_type).toBe('financial');
30
+ (0, vitest_1.expect)(result.decision).toBe('REQUIRE_APPROVAL');
31
+ });
32
+ (0, vitest_1.it)('never downgrades a declared admin action', () => {
33
+ const action = baseAction({ action_type: 'admin', tool: 'unknown.tool' });
34
+ const result = (0, policy_js_1.evaluatePolicy)(action, policy_js_1.DEFAULT_POLICY_RULES);
35
+ (0, vitest_1.expect)(result.effective_action_type).toBe('admin');
36
+ (0, vitest_1.expect)(result.decision).toBe('BLOCK');
37
+ });
38
+ (0, vitest_1.it)('skipCategoryFloor bypasses the floor (owner opt-in escape hatch)', () => {
39
+ const action = baseAction({ action_type: 'read', tool: 'stripe.charge' });
40
+ const result = (0, policy_js_1.evaluatePolicy)(action, policy_js_1.DEFAULT_POLICY_RULES, {
41
+ skipCategoryFloor: true,
42
+ });
43
+ (0, vitest_1.expect)(result.effective_action_type).toBe('read');
44
+ });
45
+ });
46
+ //# sourceMappingURL=policy-category-floor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-category-floor.test.js","sourceRoot":"","sources":["../../src/__tests__/policy-category-floor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=policy-claude-bash.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-claude-bash.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/policy-claude-bash.test.ts"],"names":[],"mappings":""}