@google/gemini-cli-core 0.5.0-preview.1 → 0.7.0-nightly.20250912.68035591
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +12 -2
- package/dist/google-gemini-cli-core-0.6.0-nightly.tgz +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/config/config.d.ts +24 -1
- package/dist/src/config/config.js +58 -15
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +11 -15
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +14 -0
- package/dist/src/config/models.js +26 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.d.ts +6 -0
- package/dist/src/config/models.test.js +55 -0
- package/dist/src/config/models.test.js.map +1 -0
- package/dist/src/confirmation-bus/index.d.ts +7 -0
- package/dist/src/confirmation-bus/index.js +8 -0
- package/dist/src/confirmation-bus/index.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.d.ts +17 -0
- package/dist/src/confirmation-bus/message-bus.js +81 -0
- package/dist/src/confirmation-bus/message-bus.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.test.d.ts +6 -0
- package/dist/src/confirmation-bus/message-bus.test.js +164 -0
- package/dist/src/confirmation-bus/message-bus.test.js.map +1 -0
- package/dist/src/confirmation-bus/types.d.ts +38 -0
- package/dist/src/confirmation-bus/types.js +15 -0
- package/dist/src/confirmation-bus/types.js.map +1 -0
- package/dist/src/core/client.d.ts +4 -1
- package/dist/src/core/client.js +46 -18
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +156 -46
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +0 -1
- package/dist/src/core/contentGenerator.js +0 -4
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +0 -3
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +4 -3
- package/dist/src/core/coreToolScheduler.js +42 -5
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +34 -0
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +1 -22
- package/dist/src/core/geminiChat.js +15 -135
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +59 -312
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +48 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/subagent.js +1 -1
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/core/subagent.test.js +9 -8
- package/dist/src/core/subagent.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +2 -1
- package/dist/src/core/turn.js +2 -2
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +18 -18
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +27 -0
- package/dist/src/ide/ide-client.js +85 -5
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.js +53 -0
- package/dist/src/ide/ide-client.test.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +34 -20
- package/dist/src/ide/ideContext.js +20 -33
- package/dist/src/ide/ideContext.js.map +1 -1
- package/dist/src/ide/ideContext.test.js +37 -39
- package/dist/src/ide/ideContext.test.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +3 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/json-formatter.d.ts +11 -0
- package/dist/src/output/json-formatter.js +30 -0
- package/dist/src/output/json-formatter.js.map +1 -0
- package/dist/src/output/json-formatter.test.d.ts +6 -0
- package/dist/src/output/json-formatter.test.js +266 -0
- package/dist/src/output/json-formatter.test.js.map +1 -0
- package/dist/src/output/types.d.ts +20 -0
- package/dist/src/output/types.js +11 -0
- package/dist/src/output/types.js.map +1 -0
- package/dist/src/policy/index.d.ts +7 -0
- package/dist/src/policy/index.js +8 -0
- package/dist/src/policy/index.js.map +1 -0
- package/dist/src/policy/policy-engine.d.ts +30 -0
- package/dist/src/policy/policy-engine.js +83 -0
- package/dist/src/policy/policy-engine.js.map +1 -0
- package/dist/src/policy/policy-engine.test.d.ts +6 -0
- package/dist/src/policy/policy-engine.test.js +470 -0
- package/dist/src/policy/policy-engine.test.js.map +1 -0
- package/dist/src/policy/stable-stringify.d.ts +58 -0
- package/dist/src/policy/stable-stringify.js +122 -0
- package/dist/src/policy/stable-stringify.js.map +1 -0
- package/dist/src/policy/types.d.ts +47 -0
- package/dist/src/policy/types.js +12 -0
- package/dist/src/policy/types.js.map +1 -0
- package/dist/src/routing/modelRouterService.d.ts +23 -0
- package/dist/src/routing/modelRouterService.js +36 -0
- package/dist/src/routing/modelRouterService.js.map +1 -0
- package/dist/src/routing/modelRouterService.test.d.ts +6 -0
- package/dist/src/routing/modelRouterService.test.js +72 -0
- package/dist/src/routing/modelRouterService.test.js.map +1 -0
- package/dist/src/routing/routingStrategy.d.ts +62 -0
- package/dist/src/routing/routingStrategy.js +7 -0
- package/dist/src/routing/routingStrategy.js.map +1 -0
- package/dist/src/routing/strategies/compositeStrategy.d.ts +26 -0
- package/dist/src/routing/strategies/compositeStrategy.js +67 -0
- package/dist/src/routing/strategies/compositeStrategy.js.map +1 -0
- package/dist/src/routing/strategies/compositeStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/compositeStrategy.test.js +123 -0
- package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/defaultStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/defaultStrategy.js +20 -0
- package/dist/src/routing/strategies/defaultStrategy.js.map +1 -0
- package/dist/src/routing/strategies/defaultStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/defaultStrategy.test.js +26 -0
- package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/fallbackStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/fallbackStrategy.js +25 -0
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js +55 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/overrideStrategy.d.ts +15 -0
- package/dist/src/routing/strategies/overrideStrategy.js +27 -0
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -0
- package/dist/src/routing/strategies/overrideStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js +41 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -0
- package/dist/src/services/fileDiscoveryService.d.ts +10 -0
- package/dist/src/services/fileDiscoveryService.js +31 -17
- package/dist/src/services/fileDiscoveryService.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +5 -0
- package/dist/src/services/loopDetectionService.js +13 -2
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +15 -0
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.d.ts +34 -2
- package/dist/src/services/shellExecutionService.js +177 -43
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +153 -56
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +4 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +31 -4
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +6 -2
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +14 -2
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +2 -2
- package/dist/src/telemetry/index.js +2 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +2 -1
- package/dist/src/telemetry/loggers.js +20 -5
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +50 -35
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +1 -1
- package/dist/src/telemetry/metrics.js +2 -2
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +23 -3
- package/dist/src/telemetry/types.js +25 -3
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/edit.js +2 -3
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +2 -8
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +5 -1
- package/dist/src/tools/glob.js +24 -17
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +51 -0
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/ls.js +19 -32
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +140 -280
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +1 -1
- package/dist/src/tools/read-many-files.js +17 -49
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +4 -0
- package/dist/src/tools/ripGrep.js +11 -1
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +51 -1
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +12 -2
- package/dist/src/tools/shell.js +12 -16
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +2 -33
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.js +2 -3
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/smart-edit.test.js +2 -8
- package/dist/src/tools/smart-edit.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +6 -4
- package/dist/src/tools/tools.js +2 -2
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/write-file.js +2 -3
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +78 -0
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.js +11 -5
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/errors.d.ts +6 -0
- package/dist/src/utils/errors.js +10 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/geminiIgnoreParser.d.ts +18 -0
- package/dist/src/utils/geminiIgnoreParser.js +61 -0
- package/dist/src/utils/geminiIgnoreParser.js.map +1 -0
- package/dist/src/utils/geminiIgnoreParser.test.d.ts +6 -0
- package/dist/src/utils/geminiIgnoreParser.test.js +50 -0
- package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.d.ts +3 -9
- package/dist/src/utils/gitIgnoreParser.js +60 -69
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +18 -53
- package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
- package/dist/src/utils/terminalSerializer.d.ts +28 -0
- package/dist/src/utils/terminalSerializer.js +432 -0
- package/dist/src/utils/terminalSerializer.js.map +1 -0
- package/dist/src/utils/terminalSerializer.test.d.ts +6 -0
- package/dist/src/utils/terminalSerializer.test.js +176 -0
- package/dist/src/utils/terminalSerializer.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/google-gemini-cli-core-0.5.0-preview.tgz +0 -0
- package/dist/src/utils/ide-trust.d.ts +0 -10
- package/dist/src/utils/ide-trust.js +0 -14
- package/dist/src/utils/ide-trust.js.map +0 -1
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
7
|
+
import { PolicyEngine } from './policy-engine.js';
|
|
8
|
+
import { PolicyDecision, } from './types.js';
|
|
9
|
+
describe('PolicyEngine', () => {
|
|
10
|
+
let engine;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
engine = new PolicyEngine();
|
|
13
|
+
});
|
|
14
|
+
describe('constructor', () => {
|
|
15
|
+
it('should use default config when none provided', () => {
|
|
16
|
+
const decision = engine.check({ name: 'test' });
|
|
17
|
+
expect(decision).toBe(PolicyDecision.ASK_USER);
|
|
18
|
+
});
|
|
19
|
+
it('should respect custom default decision', () => {
|
|
20
|
+
engine = new PolicyEngine({ defaultDecision: PolicyDecision.DENY });
|
|
21
|
+
const decision = engine.check({ name: 'test' });
|
|
22
|
+
expect(decision).toBe(PolicyDecision.DENY);
|
|
23
|
+
});
|
|
24
|
+
it('should sort rules by priority', () => {
|
|
25
|
+
const rules = [
|
|
26
|
+
{ toolName: 'tool1', decision: PolicyDecision.DENY, priority: 1 },
|
|
27
|
+
{ toolName: 'tool2', decision: PolicyDecision.ALLOW, priority: 10 },
|
|
28
|
+
{ toolName: 'tool3', decision: PolicyDecision.ASK_USER, priority: 5 },
|
|
29
|
+
];
|
|
30
|
+
engine = new PolicyEngine({ rules });
|
|
31
|
+
const sortedRules = engine.getRules();
|
|
32
|
+
expect(sortedRules[0].priority).toBe(10);
|
|
33
|
+
expect(sortedRules[1].priority).toBe(5);
|
|
34
|
+
expect(sortedRules[2].priority).toBe(1);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('check', () => {
|
|
38
|
+
it('should match tool by name', () => {
|
|
39
|
+
const rules = [
|
|
40
|
+
{ toolName: 'shell', decision: PolicyDecision.ALLOW },
|
|
41
|
+
{ toolName: 'edit', decision: PolicyDecision.DENY },
|
|
42
|
+
];
|
|
43
|
+
engine = new PolicyEngine({ rules });
|
|
44
|
+
expect(engine.check({ name: 'shell' })).toBe(PolicyDecision.ALLOW);
|
|
45
|
+
expect(engine.check({ name: 'edit' })).toBe(PolicyDecision.DENY);
|
|
46
|
+
expect(engine.check({ name: 'other' })).toBe(PolicyDecision.ASK_USER);
|
|
47
|
+
});
|
|
48
|
+
it('should match by args pattern', () => {
|
|
49
|
+
const rules = [
|
|
50
|
+
{
|
|
51
|
+
toolName: 'shell',
|
|
52
|
+
argsPattern: /rm -rf/,
|
|
53
|
+
decision: PolicyDecision.DENY,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
toolName: 'shell',
|
|
57
|
+
decision: PolicyDecision.ALLOW,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
engine = new PolicyEngine({ rules });
|
|
61
|
+
const dangerousCall = {
|
|
62
|
+
name: 'shell',
|
|
63
|
+
args: { command: 'rm -rf /' },
|
|
64
|
+
};
|
|
65
|
+
const safeCall = {
|
|
66
|
+
name: 'shell',
|
|
67
|
+
args: { command: 'ls -la' },
|
|
68
|
+
};
|
|
69
|
+
expect(engine.check(dangerousCall)).toBe(PolicyDecision.DENY);
|
|
70
|
+
expect(engine.check(safeCall)).toBe(PolicyDecision.ALLOW);
|
|
71
|
+
});
|
|
72
|
+
it('should apply rules by priority', () => {
|
|
73
|
+
const rules = [
|
|
74
|
+
{ toolName: 'shell', decision: PolicyDecision.DENY, priority: 1 },
|
|
75
|
+
{ toolName: 'shell', decision: PolicyDecision.ALLOW, priority: 10 },
|
|
76
|
+
];
|
|
77
|
+
engine = new PolicyEngine({ rules });
|
|
78
|
+
// Higher priority rule (ALLOW) should win
|
|
79
|
+
expect(engine.check({ name: 'shell' })).toBe(PolicyDecision.ALLOW);
|
|
80
|
+
});
|
|
81
|
+
it('should apply wildcard rules (no toolName)', () => {
|
|
82
|
+
const rules = [
|
|
83
|
+
{ decision: PolicyDecision.DENY }, // Applies to all tools
|
|
84
|
+
{ toolName: 'safe-tool', decision: PolicyDecision.ALLOW, priority: 10 },
|
|
85
|
+
];
|
|
86
|
+
engine = new PolicyEngine({ rules });
|
|
87
|
+
expect(engine.check({ name: 'safe-tool' })).toBe(PolicyDecision.ALLOW);
|
|
88
|
+
expect(engine.check({ name: 'any-other-tool' })).toBe(PolicyDecision.DENY);
|
|
89
|
+
});
|
|
90
|
+
it('should handle non-interactive mode', () => {
|
|
91
|
+
const config = {
|
|
92
|
+
nonInteractive: true,
|
|
93
|
+
rules: [
|
|
94
|
+
{ toolName: 'interactive-tool', decision: PolicyDecision.ASK_USER },
|
|
95
|
+
{ toolName: 'allowed-tool', decision: PolicyDecision.ALLOW },
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
engine = new PolicyEngine(config);
|
|
99
|
+
// ASK_USER should become DENY in non-interactive mode
|
|
100
|
+
expect(engine.check({ name: 'interactive-tool' })).toBe(PolicyDecision.DENY);
|
|
101
|
+
// ALLOW should remain ALLOW
|
|
102
|
+
expect(engine.check({ name: 'allowed-tool' })).toBe(PolicyDecision.ALLOW);
|
|
103
|
+
// Default ASK_USER should also become DENY
|
|
104
|
+
expect(engine.check({ name: 'unknown-tool' })).toBe(PolicyDecision.DENY);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe('addRule', () => {
|
|
108
|
+
it('should add a new rule and maintain priority order', () => {
|
|
109
|
+
engine.addRule({
|
|
110
|
+
toolName: 'tool1',
|
|
111
|
+
decision: PolicyDecision.ALLOW,
|
|
112
|
+
priority: 5,
|
|
113
|
+
});
|
|
114
|
+
engine.addRule({
|
|
115
|
+
toolName: 'tool2',
|
|
116
|
+
decision: PolicyDecision.DENY,
|
|
117
|
+
priority: 10,
|
|
118
|
+
});
|
|
119
|
+
engine.addRule({
|
|
120
|
+
toolName: 'tool3',
|
|
121
|
+
decision: PolicyDecision.ASK_USER,
|
|
122
|
+
priority: 1,
|
|
123
|
+
});
|
|
124
|
+
const rules = engine.getRules();
|
|
125
|
+
expect(rules).toHaveLength(3);
|
|
126
|
+
expect(rules[0].priority).toBe(10);
|
|
127
|
+
expect(rules[1].priority).toBe(5);
|
|
128
|
+
expect(rules[2].priority).toBe(1);
|
|
129
|
+
});
|
|
130
|
+
it('should apply newly added rules', () => {
|
|
131
|
+
expect(engine.check({ name: 'new-tool' })).toBe(PolicyDecision.ASK_USER);
|
|
132
|
+
engine.addRule({ toolName: 'new-tool', decision: PolicyDecision.ALLOW });
|
|
133
|
+
expect(engine.check({ name: 'new-tool' })).toBe(PolicyDecision.ALLOW);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('removeRulesForTool', () => {
|
|
137
|
+
it('should remove rules for specific tool', () => {
|
|
138
|
+
engine.addRule({ toolName: 'tool1', decision: PolicyDecision.ALLOW });
|
|
139
|
+
engine.addRule({ toolName: 'tool2', decision: PolicyDecision.DENY });
|
|
140
|
+
engine.addRule({
|
|
141
|
+
toolName: 'tool1',
|
|
142
|
+
decision: PolicyDecision.ASK_USER,
|
|
143
|
+
priority: 10,
|
|
144
|
+
});
|
|
145
|
+
expect(engine.getRules()).toHaveLength(3);
|
|
146
|
+
engine.removeRulesForTool('tool1');
|
|
147
|
+
const remainingRules = engine.getRules();
|
|
148
|
+
expect(remainingRules).toHaveLength(1);
|
|
149
|
+
expect(remainingRules.some((r) => r.toolName === 'tool1')).toBe(false);
|
|
150
|
+
expect(remainingRules.some((r) => r.toolName === 'tool2')).toBe(true);
|
|
151
|
+
});
|
|
152
|
+
it('should handle removing non-existent tool', () => {
|
|
153
|
+
engine.addRule({ toolName: 'existing', decision: PolicyDecision.ALLOW });
|
|
154
|
+
expect(() => engine.removeRulesForTool('non-existent')).not.toThrow();
|
|
155
|
+
expect(engine.getRules()).toHaveLength(1);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
describe('getRules', () => {
|
|
159
|
+
it('should return readonly array of rules', () => {
|
|
160
|
+
const rules = [
|
|
161
|
+
{ toolName: 'tool1', decision: PolicyDecision.ALLOW },
|
|
162
|
+
{ toolName: 'tool2', decision: PolicyDecision.DENY },
|
|
163
|
+
];
|
|
164
|
+
engine = new PolicyEngine({ rules });
|
|
165
|
+
const retrievedRules = engine.getRules();
|
|
166
|
+
expect(retrievedRules).toHaveLength(2);
|
|
167
|
+
expect(retrievedRules[0].toolName).toBe('tool1');
|
|
168
|
+
expect(retrievedRules[1].toolName).toBe('tool2');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
describe('complex scenarios', () => {
|
|
172
|
+
it('should handle multiple matching rules with different priorities', () => {
|
|
173
|
+
const rules = [
|
|
174
|
+
{ decision: PolicyDecision.DENY, priority: 0 }, // Default deny all
|
|
175
|
+
{ toolName: 'shell', decision: PolicyDecision.ASK_USER, priority: 5 },
|
|
176
|
+
{
|
|
177
|
+
toolName: 'shell',
|
|
178
|
+
argsPattern: /"command":"ls/,
|
|
179
|
+
decision: PolicyDecision.ALLOW,
|
|
180
|
+
priority: 10,
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
engine = new PolicyEngine({ rules });
|
|
184
|
+
// Matches highest priority rule (ls command)
|
|
185
|
+
expect(engine.check({ name: 'shell', args: { command: 'ls -la' } })).toBe(PolicyDecision.ALLOW);
|
|
186
|
+
// Matches middle priority rule (shell without ls)
|
|
187
|
+
expect(engine.check({ name: 'shell', args: { command: 'pwd' } })).toBe(PolicyDecision.ASK_USER);
|
|
188
|
+
// Matches lowest priority rule (not shell)
|
|
189
|
+
expect(engine.check({ name: 'edit' })).toBe(PolicyDecision.DENY);
|
|
190
|
+
});
|
|
191
|
+
it('should handle tools with no args', () => {
|
|
192
|
+
const rules = [
|
|
193
|
+
{
|
|
194
|
+
toolName: 'read',
|
|
195
|
+
argsPattern: /secret/,
|
|
196
|
+
decision: PolicyDecision.DENY,
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
engine = new PolicyEngine({ rules });
|
|
200
|
+
// Tool call without args should not match pattern
|
|
201
|
+
expect(engine.check({ name: 'read' })).toBe(PolicyDecision.ASK_USER);
|
|
202
|
+
// Tool call with args not matching pattern
|
|
203
|
+
expect(engine.check({ name: 'read', args: { file: 'public.txt' } })).toBe(PolicyDecision.ASK_USER);
|
|
204
|
+
// Tool call with args matching pattern
|
|
205
|
+
expect(engine.check({ name: 'read', args: { file: 'secret.txt' } })).toBe(PolicyDecision.DENY);
|
|
206
|
+
});
|
|
207
|
+
it('should match args pattern regardless of property order', () => {
|
|
208
|
+
const rules = [
|
|
209
|
+
{
|
|
210
|
+
toolName: 'shell',
|
|
211
|
+
// Pattern matches the stable stringified format
|
|
212
|
+
argsPattern: /"command":"rm[^"]*-rf/,
|
|
213
|
+
decision: PolicyDecision.DENY,
|
|
214
|
+
},
|
|
215
|
+
];
|
|
216
|
+
engine = new PolicyEngine({ rules });
|
|
217
|
+
// Same args with different property order should both match
|
|
218
|
+
const args1 = { command: 'rm -rf /', path: '/home' };
|
|
219
|
+
const args2 = { path: '/home', command: 'rm -rf /' };
|
|
220
|
+
expect(engine.check({ name: 'shell', args: args1 })).toBe(PolicyDecision.DENY);
|
|
221
|
+
expect(engine.check({ name: 'shell', args: args2 })).toBe(PolicyDecision.DENY);
|
|
222
|
+
// Verify safe command doesn't match
|
|
223
|
+
const safeArgs = { command: 'ls -la', path: '/home' };
|
|
224
|
+
expect(engine.check({ name: 'shell', args: safeArgs })).toBe(PolicyDecision.ASK_USER);
|
|
225
|
+
});
|
|
226
|
+
it('should handle nested objects in args with stable stringification', () => {
|
|
227
|
+
const rules = [
|
|
228
|
+
{
|
|
229
|
+
toolName: 'api',
|
|
230
|
+
argsPattern: /"sensitive":true/,
|
|
231
|
+
decision: PolicyDecision.DENY,
|
|
232
|
+
},
|
|
233
|
+
];
|
|
234
|
+
engine = new PolicyEngine({ rules });
|
|
235
|
+
// Nested objects with different key orders should match consistently
|
|
236
|
+
const args1 = {
|
|
237
|
+
data: { sensitive: true, value: 'secret' },
|
|
238
|
+
method: 'POST',
|
|
239
|
+
};
|
|
240
|
+
const args2 = {
|
|
241
|
+
method: 'POST',
|
|
242
|
+
data: { value: 'secret', sensitive: true },
|
|
243
|
+
};
|
|
244
|
+
expect(engine.check({ name: 'api', args: args1 })).toBe(PolicyDecision.DENY);
|
|
245
|
+
expect(engine.check({ name: 'api', args: args2 })).toBe(PolicyDecision.DENY);
|
|
246
|
+
});
|
|
247
|
+
it('should handle circular references without stack overflow', () => {
|
|
248
|
+
const rules = [
|
|
249
|
+
{
|
|
250
|
+
toolName: 'test',
|
|
251
|
+
argsPattern: /\[Circular\]/,
|
|
252
|
+
decision: PolicyDecision.DENY,
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
engine = new PolicyEngine({ rules });
|
|
256
|
+
const circularArgs = {
|
|
257
|
+
name: 'test',
|
|
258
|
+
data: {},
|
|
259
|
+
};
|
|
260
|
+
// Create circular reference - TypeScript allows this since data is Record<string, unknown>
|
|
261
|
+
circularArgs.data['self'] =
|
|
262
|
+
circularArgs.data;
|
|
263
|
+
// Should not throw stack overflow error
|
|
264
|
+
expect(() => engine.check({ name: 'test', args: circularArgs })).not.toThrow();
|
|
265
|
+
// Should detect the circular reference pattern
|
|
266
|
+
expect(engine.check({ name: 'test', args: circularArgs })).toBe(PolicyDecision.DENY);
|
|
267
|
+
// Non-circular object should not match
|
|
268
|
+
const normalArgs = { name: 'test', data: { value: 'normal' } };
|
|
269
|
+
expect(engine.check({ name: 'test', args: normalArgs })).toBe(PolicyDecision.ASK_USER);
|
|
270
|
+
});
|
|
271
|
+
it('should handle deep circular references', () => {
|
|
272
|
+
const rules = [
|
|
273
|
+
{
|
|
274
|
+
toolName: 'deep',
|
|
275
|
+
argsPattern: /\[Circular\]/,
|
|
276
|
+
decision: PolicyDecision.DENY,
|
|
277
|
+
},
|
|
278
|
+
];
|
|
279
|
+
engine = new PolicyEngine({ rules });
|
|
280
|
+
const deepCircular = {
|
|
281
|
+
level1: {
|
|
282
|
+
level2: {
|
|
283
|
+
level3: {},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
// Create circular reference with proper type assertions
|
|
288
|
+
const level3 = deepCircular.level1.level2.level3;
|
|
289
|
+
level3['back'] = deepCircular.level1;
|
|
290
|
+
// Should handle without stack overflow
|
|
291
|
+
expect(() => engine.check({ name: 'deep', args: deepCircular })).not.toThrow();
|
|
292
|
+
// Should detect the circular reference
|
|
293
|
+
expect(engine.check({ name: 'deep', args: deepCircular })).toBe(PolicyDecision.DENY);
|
|
294
|
+
});
|
|
295
|
+
it('should handle repeated non-circular objects correctly', () => {
|
|
296
|
+
const rules = [
|
|
297
|
+
{
|
|
298
|
+
toolName: 'test',
|
|
299
|
+
argsPattern: /\[Circular\]/,
|
|
300
|
+
decision: PolicyDecision.DENY,
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
toolName: 'test',
|
|
304
|
+
argsPattern: /"value":"shared"/,
|
|
305
|
+
decision: PolicyDecision.ALLOW,
|
|
306
|
+
priority: 10,
|
|
307
|
+
},
|
|
308
|
+
];
|
|
309
|
+
engine = new PolicyEngine({ rules });
|
|
310
|
+
// Create an object with repeated references but no cycles
|
|
311
|
+
const sharedObj = { value: 'shared' };
|
|
312
|
+
const args = {
|
|
313
|
+
first: sharedObj,
|
|
314
|
+
second: sharedObj,
|
|
315
|
+
third: { nested: sharedObj },
|
|
316
|
+
};
|
|
317
|
+
// Should NOT mark repeated objects as circular, and should match the shared value pattern
|
|
318
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ALLOW);
|
|
319
|
+
});
|
|
320
|
+
it('should omit undefined and function values from objects', () => {
|
|
321
|
+
const rules = [
|
|
322
|
+
{
|
|
323
|
+
toolName: 'test',
|
|
324
|
+
argsPattern: /"definedValue":"test"/,
|
|
325
|
+
decision: PolicyDecision.ALLOW,
|
|
326
|
+
},
|
|
327
|
+
];
|
|
328
|
+
engine = new PolicyEngine({ rules });
|
|
329
|
+
const args = {
|
|
330
|
+
definedValue: 'test',
|
|
331
|
+
undefinedValue: undefined,
|
|
332
|
+
functionValue: () => 'hello',
|
|
333
|
+
nullValue: null,
|
|
334
|
+
};
|
|
335
|
+
// Should match pattern with defined value, undefined and functions omitted
|
|
336
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ALLOW);
|
|
337
|
+
// Check that the pattern would NOT match if undefined was included
|
|
338
|
+
const rulesWithUndefined = [
|
|
339
|
+
{
|
|
340
|
+
toolName: 'test',
|
|
341
|
+
argsPattern: /undefinedValue/,
|
|
342
|
+
decision: PolicyDecision.DENY,
|
|
343
|
+
},
|
|
344
|
+
];
|
|
345
|
+
engine = new PolicyEngine({ rules: rulesWithUndefined });
|
|
346
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ASK_USER);
|
|
347
|
+
// Check that the pattern would NOT match if function was included
|
|
348
|
+
const rulesWithFunction = [
|
|
349
|
+
{
|
|
350
|
+
toolName: 'test',
|
|
351
|
+
argsPattern: /functionValue/,
|
|
352
|
+
decision: PolicyDecision.DENY,
|
|
353
|
+
},
|
|
354
|
+
];
|
|
355
|
+
engine = new PolicyEngine({ rules: rulesWithFunction });
|
|
356
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ASK_USER);
|
|
357
|
+
});
|
|
358
|
+
it('should convert undefined and functions to null in arrays', () => {
|
|
359
|
+
const rules = [
|
|
360
|
+
{
|
|
361
|
+
toolName: 'test',
|
|
362
|
+
argsPattern: /\["value",null,null,null\]/,
|
|
363
|
+
decision: PolicyDecision.ALLOW,
|
|
364
|
+
},
|
|
365
|
+
];
|
|
366
|
+
engine = new PolicyEngine({ rules });
|
|
367
|
+
const args = {
|
|
368
|
+
array: ['value', undefined, () => 'hello', null],
|
|
369
|
+
};
|
|
370
|
+
// Should match pattern with undefined and functions converted to null
|
|
371
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ALLOW);
|
|
372
|
+
});
|
|
373
|
+
it('should produce valid JSON for all inputs', () => {
|
|
374
|
+
const testCases = [
|
|
375
|
+
{ input: { simple: 'string' }, desc: 'simple object' },
|
|
376
|
+
{
|
|
377
|
+
input: { nested: { deep: { value: 123 } } },
|
|
378
|
+
desc: 'nested object',
|
|
379
|
+
},
|
|
380
|
+
{ input: { data: [1, 2, 3] }, desc: 'simple array' },
|
|
381
|
+
{ input: { mixed: [1, { a: 'b' }, null] }, desc: 'mixed array' },
|
|
382
|
+
{
|
|
383
|
+
input: { undef: undefined, func: () => { }, normal: 'value' },
|
|
384
|
+
desc: 'object with undefined and function',
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
input: { data: ['a', undefined, () => { }, null] },
|
|
388
|
+
desc: 'array with undefined and function',
|
|
389
|
+
},
|
|
390
|
+
];
|
|
391
|
+
for (const { input } of testCases) {
|
|
392
|
+
const rules = [
|
|
393
|
+
{
|
|
394
|
+
toolName: 'test',
|
|
395
|
+
argsPattern: /.*/,
|
|
396
|
+
decision: PolicyDecision.ALLOW,
|
|
397
|
+
},
|
|
398
|
+
];
|
|
399
|
+
engine = new PolicyEngine({ rules });
|
|
400
|
+
// Should not throw when checking (which internally uses stableStringify)
|
|
401
|
+
expect(() => engine.check({ name: 'test', args: input })).not.toThrow();
|
|
402
|
+
// The check should succeed
|
|
403
|
+
expect(engine.check({ name: 'test', args: input })).toBe(PolicyDecision.ALLOW);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
it('should respect toJSON methods on objects', () => {
|
|
407
|
+
const rules = [
|
|
408
|
+
{
|
|
409
|
+
toolName: 'test',
|
|
410
|
+
argsPattern: /"sanitized":"safe"/,
|
|
411
|
+
decision: PolicyDecision.ALLOW,
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
toolName: 'test',
|
|
415
|
+
argsPattern: /"dangerous":"data"/,
|
|
416
|
+
decision: PolicyDecision.DENY,
|
|
417
|
+
},
|
|
418
|
+
];
|
|
419
|
+
engine = new PolicyEngine({ rules });
|
|
420
|
+
// Object with toJSON that sanitizes output
|
|
421
|
+
const args = {
|
|
422
|
+
data: {
|
|
423
|
+
dangerous: 'data',
|
|
424
|
+
toJSON: () => ({ sanitized: 'safe' }),
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
// Should match the sanitized pattern, not the dangerous one
|
|
428
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ALLOW);
|
|
429
|
+
});
|
|
430
|
+
it('should handle toJSON that returns primitives', () => {
|
|
431
|
+
const rules = [
|
|
432
|
+
{
|
|
433
|
+
toolName: 'test',
|
|
434
|
+
argsPattern: /"value":"string-value"/,
|
|
435
|
+
decision: PolicyDecision.ALLOW,
|
|
436
|
+
},
|
|
437
|
+
];
|
|
438
|
+
engine = new PolicyEngine({ rules });
|
|
439
|
+
const args = {
|
|
440
|
+
value: {
|
|
441
|
+
complex: 'object',
|
|
442
|
+
toJSON: () => 'string-value',
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
// toJSON returns a string, which should be properly stringified
|
|
446
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ALLOW);
|
|
447
|
+
});
|
|
448
|
+
it('should handle toJSON that throws an error', () => {
|
|
449
|
+
const rules = [
|
|
450
|
+
{
|
|
451
|
+
toolName: 'test',
|
|
452
|
+
argsPattern: /"fallback":"value"/,
|
|
453
|
+
decision: PolicyDecision.ALLOW,
|
|
454
|
+
},
|
|
455
|
+
];
|
|
456
|
+
engine = new PolicyEngine({ rules });
|
|
457
|
+
const args = {
|
|
458
|
+
data: {
|
|
459
|
+
fallback: 'value',
|
|
460
|
+
toJSON: () => {
|
|
461
|
+
throw new Error('toJSON error');
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
// Should fall back to regular object serialization when toJSON throws
|
|
466
|
+
expect(engine.check({ name: 'test', args })).toBe(PolicyDecision.ALLOW);
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
//# sourceMappingURL=policy-engine.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.test.js","sourceRoot":"","sources":["../../../src/policy/policy-engine.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Produces a stable, deterministic JSON string representation with sorted keys.
|
|
8
|
+
*
|
|
9
|
+
* This method is critical for security policy matching. It ensures that the same
|
|
10
|
+
* object always produces the same string representation, regardless of property
|
|
11
|
+
* insertion order, which could vary across different JavaScript engines or
|
|
12
|
+
* runtime conditions.
|
|
13
|
+
*
|
|
14
|
+
* Key behaviors:
|
|
15
|
+
* 1. **Sorted Keys**: Object properties are always serialized in alphabetical order,
|
|
16
|
+
* ensuring deterministic output for pattern matching.
|
|
17
|
+
*
|
|
18
|
+
* 2. **Circular Reference Protection**: Uses ancestor chain tracking (not just
|
|
19
|
+
* object identity) to detect true circular references while correctly handling
|
|
20
|
+
* repeated non-circular object references. Circular references are replaced
|
|
21
|
+
* with "[Circular]" to prevent stack overflow attacks.
|
|
22
|
+
*
|
|
23
|
+
* 3. **JSON Spec Compliance**:
|
|
24
|
+
* - undefined values: Omitted from objects, converted to null in arrays
|
|
25
|
+
* - Functions: Omitted from objects, converted to null in arrays
|
|
26
|
+
* - toJSON methods: Respected and called when present (per JSON.stringify spec)
|
|
27
|
+
*
|
|
28
|
+
* 4. **Security Considerations**:
|
|
29
|
+
* - Prevents DoS via circular references that would cause infinite recursion
|
|
30
|
+
* - Ensures consistent policy rule matching by normalizing property order
|
|
31
|
+
* - Respects toJSON for objects that sanitize their output
|
|
32
|
+
* - Handles toJSON methods that throw errors gracefully
|
|
33
|
+
*
|
|
34
|
+
* @param obj - The object to stringify (typically toolCall.args)
|
|
35
|
+
* @returns A deterministic JSON string representation
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Different property orders produce the same output:
|
|
39
|
+
* stableStringify({b: 2, a: 1}) === stableStringify({a: 1, b: 2})
|
|
40
|
+
* // Returns: '{"a":1,"b":2}'
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Circular references are handled safely:
|
|
44
|
+
* const obj = {a: 1};
|
|
45
|
+
* obj.self = obj;
|
|
46
|
+
* stableStringify(obj)
|
|
47
|
+
* // Returns: '{"a":1,"self":"[Circular]"}'
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // toJSON methods are respected:
|
|
51
|
+
* const obj = {
|
|
52
|
+
* sensitive: 'secret',
|
|
53
|
+
* toJSON: () => ({ safe: 'data' })
|
|
54
|
+
* };
|
|
55
|
+
* stableStringify(obj)
|
|
56
|
+
* // Returns: '{"safe":"data"}'
|
|
57
|
+
*/
|
|
58
|
+
export declare function stableStringify(obj: unknown): string;
|