@office-ai/aioncli-core 0.30.0 → 0.30.1
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/dist/docs/assets/theme-ansi-dark.png +0 -0
- package/dist/docs/assets/theme-atom-one-dark.png +0 -0
- package/dist/docs/assets/theme-ayu-dark.png +0 -0
- package/dist/docs/assets/theme-default-dark.png +0 -0
- package/dist/docs/assets/theme-dracula-dark.png +0 -0
- package/dist/docs/assets/theme-github-dark.png +0 -0
- package/dist/docs/assets/theme-holiday-dark.png +0 -0
- package/dist/docs/assets/theme-shades-of-purple-dark.png +0 -0
- package/dist/docs/assets/theme-solarized-dark.png +0 -0
- package/dist/docs/assets/theme-solarized-light.png +0 -0
- package/dist/docs/cli/notifications.md +58 -0
- package/dist/docs/redirects.json +20 -0
- package/dist/docs/reference/commands.md +563 -0
- package/dist/docs/reference/configuration.md +1804 -0
- package/dist/docs/reference/keyboard-shortcuts.md +168 -0
- package/dist/docs/reference/memport.md +246 -0
- package/dist/docs/reference/policy-engine.md +386 -0
- package/dist/docs/reference/tools.md +106 -0
- package/dist/docs/resources/faq.md +175 -0
- package/dist/docs/resources/quota-and-pricing.md +199 -0
- package/dist/docs/resources/tos-privacy.md +102 -0
- package/dist/docs/resources/troubleshooting.md +176 -0
- package/dist/docs/resources/uninstall.md +56 -0
- package/dist/src/agents/a2a-errors.d.ts +65 -0
- package/dist/src/agents/a2a-errors.js +164 -0
- package/dist/src/agents/a2a-errors.js.map +1 -0
- package/dist/src/agents/a2a-errors.test.d.ts +6 -0
- package/dist/src/agents/a2a-errors.test.js +183 -0
- package/dist/src/agents/a2a-errors.test.js.map +1 -0
- package/dist/src/agents/auth-provider/api-key-provider.d.ts +30 -0
- package/dist/src/agents/auth-provider/api-key-provider.js +66 -0
- package/dist/src/agents/auth-provider/api-key-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/api-key-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/api-key-provider.test.js +130 -0
- package/dist/src/agents/auth-provider/api-key-provider.test.js.map +1 -0
- package/dist/src/agents/auth-provider/http-provider.d.ts +28 -0
- package/dist/src/agents/auth-provider/http-provider.js +73 -0
- package/dist/src/agents/auth-provider/http-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/http-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/http-provider.test.js +112 -0
- package/dist/src/agents/auth-provider/http-provider.test.js.map +1 -0
- package/dist/src/agents/auth-provider/oauth2-provider.d.ts +65 -0
- package/dist/src/agents/auth-provider/oauth2-provider.js +233 -0
- package/dist/src/agents/auth-provider/oauth2-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/oauth2-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/oauth2-provider.test.js +490 -0
- package/dist/src/agents/auth-provider/oauth2-provider.test.js.map +1 -0
- package/dist/src/agents/browser/analyzeScreenshot.d.ts +35 -0
- package/dist/src/agents/browser/analyzeScreenshot.js +183 -0
- package/dist/src/agents/browser/analyzeScreenshot.js.map +1 -0
- package/dist/src/agents/browser/analyzeScreenshot.test.d.ts +6 -0
- package/dist/src/agents/browser/analyzeScreenshot.test.js +161 -0
- package/dist/src/agents/browser/analyzeScreenshot.test.js.map +1 -0
- package/dist/src/agents/browser/automationOverlay.d.ts +26 -0
- package/dist/src/agents/browser/automationOverlay.js +100 -0
- package/dist/src/agents/browser/automationOverlay.js.map +1 -0
- package/dist/src/agents/browser/browserAgentDefinition.d.ts +50 -0
- package/dist/src/agents/browser/browserAgentDefinition.js +141 -0
- package/dist/src/agents/browser/browserAgentDefinition.js.map +1 -0
- package/dist/src/agents/browser/browserAgentFactory.d.ts +42 -0
- package/dist/src/agents/browser/browserAgentFactory.js +116 -0
- package/dist/src/agents/browser/browserAgentFactory.js.map +1 -0
- package/dist/src/agents/browser/browserAgentFactory.test.d.ts +6 -0
- package/dist/src/agents/browser/browserAgentFactory.test.js +240 -0
- package/dist/src/agents/browser/browserAgentFactory.test.js.map +1 -0
- package/dist/src/agents/browser/browserAgentInvocation.d.ts +34 -0
- package/dist/src/agents/browser/browserAgentInvocation.js +386 -0
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.d.ts +6 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.js +382 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -0
- package/dist/src/agents/browser/browserManager.d.ts +115 -0
- package/dist/src/agents/browser/browserManager.js +370 -0
- package/dist/src/agents/browser/browserManager.js.map +1 -0
- package/dist/src/agents/browser/browserManager.test.d.ts +6 -0
- package/dist/src/agents/browser/browserManager.test.js +382 -0
- package/dist/src/agents/browser/browserManager.test.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapper.d.ts +45 -0
- package/dist/src/agents/browser/mcpToolWrapper.js +358 -0
- package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.d.ts +6 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.js +126 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.d.ts +6 -0
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.js +59 -0
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.js.map +1 -0
- package/dist/src/agents/browser/modelAvailability.d.ts +23 -0
- package/dist/src/agents/browser/modelAvailability.js +23 -0
- package/dist/src/agents/browser/modelAvailability.js.map +1 -0
- package/dist/src/agents/cli-help-agent.d.ts +2 -2
- package/dist/src/billing/billing.d.ts +80 -0
- package/dist/src/billing/billing.js +128 -0
- package/dist/src/billing/billing.js.map +1 -0
- package/dist/src/billing/billing.test.d.ts +6 -0
- package/dist/src/billing/billing.test.js +182 -0
- package/dist/src/billing/billing.test.js.map +1 -0
- package/dist/src/billing/index.d.ts +6 -0
- package/dist/src/billing/index.js +7 -0
- package/dist/src/billing/index.js.map +1 -0
- package/dist/src/code_assist/oauth2.d.ts +1 -1
- package/dist/src/code_assist/types.d.ts +26 -26
- package/dist/src/config/agent-loop-context.d.ts +22 -0
- package/dist/src/config/agent-loop-context.js +7 -0
- package/dist/src/config/agent-loop-context.js.map +1 -0
- package/dist/src/config/trackerFeatureFlag.test.d.ts +6 -0
- package/dist/src/config/trackerFeatureFlag.test.js +43 -0
- package/dist/src/config/trackerFeatureFlag.test.js.map +1 -0
- package/dist/src/config/userHintService.d.ts +46 -0
- package/dist/src/config/userHintService.js +81 -0
- package/dist/src/config/userHintService.js.map +1 -0
- package/dist/src/config/userHintService.test.d.ts +6 -0
- package/dist/src/config/userHintService.test.js +62 -0
- package/dist/src/config/userHintService.test.js.map +1 -0
- package/dist/src/core/localLiteRtLmClient.d.ts +24 -0
- package/dist/src/core/localLiteRtLmClient.js +77 -0
- package/dist/src/core/localLiteRtLmClient.js.map +1 -0
- package/dist/src/core/localLiteRtLmClient.test.d.ts +6 -0
- package/dist/src/core/localLiteRtLmClient.test.js +87 -0
- package/dist/src/core/localLiteRtLmClient.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator.d.ts +1 -0
- package/dist/src/core/openaiContentGenerator.js +13 -13
- package/dist/src/core/openaiContentGenerator.js.map +1 -1
- package/dist/src/hooks/runtimeHooks.test.d.ts +6 -0
- package/dist/src/hooks/runtimeHooks.test.js +100 -0
- package/dist/src/hooks/runtimeHooks.test.js.map +1 -0
- package/dist/src/ide/types.d.ts +6 -6
- package/dist/src/mcp/mcp-oauth-provider.d.ts +43 -0
- package/dist/src/mcp/mcp-oauth-provider.js +67 -0
- package/dist/src/mcp/mcp-oauth-provider.js.map +1 -0
- package/dist/src/mcp/mcp-oauth-provider.test.d.ts +6 -0
- package/dist/src/mcp/mcp-oauth-provider.test.js +63 -0
- package/dist/src/mcp/mcp-oauth-provider.test.js.map +1 -0
- package/dist/src/policy/integrity.d.ts +45 -0
- package/dist/src/policy/integrity.js +121 -0
- package/dist/src/policy/integrity.js.map +1 -0
- package/dist/src/policy/integrity.test.d.ts +6 -0
- package/dist/src/policy/integrity.test.js +132 -0
- package/dist/src/policy/integrity.test.js.map +1 -0
- package/dist/src/policy/policies/conseca.toml +6 -0
- package/dist/src/policy/workspace-policy.test.js +231 -0
- package/dist/src/policy/workspace-policy.test.js.map +1 -0
- package/dist/src/routing/strategies/approvalModeStrategy.d.ts +18 -0
- package/dist/src/routing/strategies/approvalModeStrategy.js +59 -0
- package/dist/src/routing/strategies/approvalModeStrategy.js.map +1 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.js +140 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.d.ts +14 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.js +182 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.js.map +1 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js +218 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js.map +1 -0
- package/dist/src/safety/conseca/conseca.d.ts +31 -0
- package/dist/src/safety/conseca/conseca.js +105 -0
- package/dist/src/safety/conseca/conseca.js.map +1 -0
- package/dist/src/safety/conseca/conseca.test.js +226 -0
- package/dist/src/safety/conseca/conseca.test.js.map +1 -0
- package/dist/src/safety/conseca/integration.test.js +19 -0
- package/dist/src/safety/conseca/integration.test.js.map +1 -0
- package/dist/src/safety/conseca/policy-enforcer.d.ts +13 -0
- package/dist/src/safety/conseca/policy-enforcer.js +135 -0
- package/dist/src/safety/conseca/policy-enforcer.js.map +1 -0
- package/dist/src/safety/conseca/policy-enforcer.test.js +141 -0
- package/dist/src/safety/conseca/policy-enforcer.test.js.map +1 -0
- package/dist/src/safety/conseca/policy-generator.d.ts +15 -0
- package/dist/src/safety/conseca/policy-generator.js +144 -0
- package/dist/src/safety/conseca/policy-generator.js.map +1 -0
- package/dist/src/safety/conseca/policy-generator.test.d.ts +6 -0
- package/dist/src/safety/conseca/policy-generator.test.js +84 -0
- package/dist/src/safety/conseca/policy-generator.test.js.map +1 -0
- package/dist/src/safety/conseca/types.d.ts +15 -0
- package/dist/src/safety/conseca/types.js +7 -0
- package/dist/src/safety/conseca/types.js.map +1 -0
- package/dist/src/scheduler/scheduler_parallel.test.d.ts +6 -0
- package/dist/src/scheduler/scheduler_parallel.test.js +401 -0
- package/dist/src/scheduler/scheduler_parallel.test.js.map +1 -0
- package/dist/src/services/FolderTrustDiscoveryService.d.ts +32 -0
- package/dist/src/services/FolderTrustDiscoveryService.js +169 -0
- package/dist/src/services/FolderTrustDiscoveryService.js.map +1 -0
- package/dist/src/services/FolderTrustDiscoveryService.test.d.ts +6 -0
- package/dist/src/services/FolderTrustDiscoveryService.test.js +118 -0
- package/dist/src/services/FolderTrustDiscoveryService.test.js.map +1 -0
- package/dist/src/services/fileKeychain.d.ts +24 -0
- package/dist/src/services/fileKeychain.js +123 -0
- package/dist/src/services/fileKeychain.js.map +1 -0
- package/dist/src/services/keychainService.d.ts +51 -0
- package/dist/src/services/keychainService.js +133 -0
- package/dist/src/services/keychainService.js.map +1 -0
- package/dist/src/services/keychainService.test.d.ts +6 -0
- package/dist/src/services/keychainService.test.js +150 -0
- package/dist/src/services/keychainService.test.js.map +1 -0
- package/dist/src/services/keychainTypes.d.ts +41 -0
- package/dist/src/services/keychainTypes.js +18 -0
- package/dist/src/services/keychainTypes.js.map +1 -0
- package/dist/src/services/trackerService.d.ts +49 -0
- package/dist/src/services/trackerService.js +193 -0
- package/dist/src/services/trackerService.js.map +1 -0
- package/dist/src/services/trackerService.test.d.ts +6 -0
- package/dist/src/services/trackerService.test.js +117 -0
- package/dist/src/services/trackerService.test.js.map +1 -0
- package/dist/src/services/trackerTypes.d.ts +51 -0
- package/dist/src/services/trackerTypes.js +33 -0
- package/dist/src/services/trackerTypes.js.map +1 -0
- package/dist/src/telemetry/billingEvents.d.ts +75 -0
- package/dist/src/telemetry/billingEvents.js +181 -0
- package/dist/src/telemetry/billingEvents.js.map +1 -0
- package/dist/src/telemetry/billingEvents.test.d.ts +6 -0
- package/dist/src/telemetry/billingEvents.test.js +139 -0
- package/dist/src/telemetry/billingEvents.test.js.map +1 -0
- package/dist/src/telemetry/conseca-logger.d.ts +9 -0
- package/dist/src/telemetry/conseca-logger.js +91 -0
- package/dist/src/telemetry/conseca-logger.js.map +1 -0
- package/dist/src/telemetry/conseca-logger.test.d.ts +6 -0
- package/dist/src/telemetry/conseca-logger.test.js +90 -0
- package/dist/src/telemetry/conseca-logger.test.js.map +1 -0
- package/dist/src/telemetry/trace.test.d.ts +6 -0
- package/dist/src/telemetry/trace.test.js +116 -0
- package/dist/src/telemetry/trace.test.js.map +1 -0
- package/dist/src/tools/definitions/trackerTools.d.ts +12 -0
- package/dist/src/tools/definitions/trackerTools.js +146 -0
- package/dist/src/tools/definitions/trackerTools.js.map +1 -0
- package/dist/src/tools/diff-utils.d.ts +9 -0
- package/dist/src/tools/diff-utils.js +66 -0
- package/dist/src/tools/diff-utils.js.map +1 -0
- package/dist/src/tools/diff-utils.test.d.ts +6 -0
- package/dist/src/tools/diff-utils.test.js +53 -0
- package/dist/src/tools/diff-utils.test.js.map +1 -0
- package/dist/src/tools/grep-utils.d.ts +49 -0
- package/dist/src/tools/grep-utils.js +147 -0
- package/dist/src/tools/grep-utils.js.map +1 -0
- package/dist/src/tools/omissionPlaceholderDetector.d.ts +15 -0
- package/dist/src/tools/omissionPlaceholderDetector.js +90 -0
- package/dist/src/tools/omissionPlaceholderDetector.js.map +1 -0
- package/dist/src/tools/omissionPlaceholderDetector.test.d.ts +6 -0
- package/dist/src/tools/omissionPlaceholderDetector.test.js +49 -0
- package/dist/src/tools/omissionPlaceholderDetector.test.js.map +1 -0
- package/dist/src/tools/trackerTools.d.ts +122 -0
- package/dist/src/tools/trackerTools.js +365 -0
- package/dist/src/tools/trackerTools.js.map +1 -0
- package/dist/src/tools/trackerTools.test.d.ts +6 -0
- package/dist/src/tools/trackerTools.test.js +97 -0
- package/dist/src/tools/trackerTools.test.js.map +1 -0
- package/dist/src/utils/approvalModeUtils.d.ts +14 -0
- package/dist/src/utils/approvalModeUtils.js +35 -0
- package/dist/src/utils/approvalModeUtils.js.map +1 -0
- package/dist/src/utils/approvalModeUtils.test.d.ts +6 -0
- package/dist/src/utils/approvalModeUtils.test.js +36 -0
- package/dist/src/utils/approvalModeUtils.test.js.map +1 -0
- package/dist/src/utils/cache.d.ts +63 -0
- package/dist/src/utils/cache.js +103 -0
- package/dist/src/utils/cache.js.map +1 -0
- package/dist/src/utils/cache.test.d.ts +6 -0
- package/dist/src/utils/cache.test.js +158 -0
- package/dist/src/utils/cache.test.js.map +1 -0
- package/dist/src/utils/checkpointUtils.d.ts +2 -2
- package/dist/src/utils/compatibility.d.ts +41 -0
- package/dist/src/utils/compatibility.js +112 -0
- package/dist/src/utils/compatibility.js.map +1 -0
- package/dist/src/utils/compatibility.test.d.ts +6 -0
- package/dist/src/utils/compatibility.test.js +233 -0
- package/dist/src/utils/compatibility.test.js.map +1 -0
- package/dist/src/utils/envExpansion.d.ts +18 -0
- package/dist/src/utils/envExpansion.js +46 -0
- package/dist/src/utils/envExpansion.js.map +1 -0
- package/dist/src/utils/envExpansion.test.d.ts +6 -0
- package/dist/src/utils/envExpansion.test.js +110 -0
- package/dist/src/utils/envExpansion.test.js.map +1 -0
- package/dist/src/utils/errors_timeout.test.d.ts +6 -0
- package/dist/src/utils/errors_timeout.test.js +40 -0
- package/dist/src/utils/errors_timeout.test.js.map +1 -0
- package/dist/src/utils/fetch.test.d.ts +6 -0
- package/dist/src/utils/fetch.test.js +206 -0
- package/dist/src/utils/fetch.test.js.map +1 -0
- package/dist/src/utils/markdownUtils.d.ts +22 -0
- package/dist/src/utils/markdownUtils.js +126 -0
- package/dist/src/utils/markdownUtils.js.map +1 -0
- package/dist/src/utils/markdownUtils.test.d.ts +6 -0
- package/dist/src/utils/markdownUtils.test.js +107 -0
- package/dist/src/utils/markdownUtils.test.js.map +1 -0
- package/dist/src/utils/oauth-flow.d.ts +105 -0
- package/dist/src/utils/oauth-flow.js +370 -0
- package/dist/src/utils/oauth-flow.js.map +1 -0
- package/dist/src/utils/oauth-flow.test.d.ts +6 -0
- package/dist/src/utils/oauth-flow.test.js +360 -0
- package/dist/src/utils/oauth-flow.test.js.map +1 -0
- package/dist/src/utils/sessionUtils.d.ts +14 -0
- package/dist/src/utils/sessionUtils.js +122 -0
- package/dist/src/utils/sessionUtils.js.map +1 -0
- package/dist/src/utils/sessionUtils.test.d.ts +1 -0
- package/dist/src/utils/sessionUtils.test.js +171 -0
- package/dist/src/utils/sessionUtils.test.js.map +1 -0
- package/dist/src/voice/responseFormatter.d.ts +38 -0
- package/dist/src/voice/responseFormatter.js +130 -0
- package/dist/src/voice/responseFormatter.js.map +1 -0
- package/dist/src/voice/responseFormatter.test.d.ts +6 -0
- package/dist/src/voice/responseFormatter.test.js +214 -0
- package/dist/src/voice/responseFormatter.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/docs/CONTRIBUTING.md +0 -555
- package/dist/src/agents/executor.d.ts +0 -114
- package/dist/src/agents/executor.js +0 -779
- package/dist/src/agents/executor.js.map +0 -1
- package/dist/src/agents/executor.test.js +0 -1362
- package/dist/src/agents/executor.test.js.map +0 -1
- package/dist/src/agents/invocation.d.ts +0 -46
- package/dist/src/agents/invocation.js +0 -102
- package/dist/src/agents/invocation.js.map +0 -1
- package/dist/src/agents/invocation.test.js +0 -215
- package/dist/src/agents/invocation.test.js.map +0 -1
- package/dist/src/core/subagent.d.ts +0 -236
- package/dist/src/core/subagent.js +0 -482
- package/dist/src/core/subagent.js.map +0 -1
- package/dist/src/core/subagent.test.js +0 -530
- package/dist/src/core/subagent.test.js.map +0 -1
- package/dist/src/tools/smart-edit.d.ts +0 -78
- package/dist/src/tools/smart-edit.js +0 -717
- package/dist/src/tools/smart-edit.js.map +0 -1
- package/dist/src/tools/smart-edit.test.js +0 -592
- package/dist/src/tools/smart-edit.test.js.map +0 -1
- /package/dist/src/{agents/executor.test.d.ts → policy/workspace-policy.test.d.ts} +0 -0
- /package/dist/src/{agents/invocation.test.d.ts → safety/conseca/conseca.test.d.ts} +0 -0
- /package/dist/src/{core/subagent.test.d.ts → safety/conseca/integration.test.d.ts} +0 -0
- /package/dist/src/{tools/smart-edit.test.d.ts → safety/conseca/policy-enforcer.test.d.ts} +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export declare enum IntegrityStatus {
|
|
7
|
+
MATCH = "MATCH",
|
|
8
|
+
MISMATCH = "MISMATCH",
|
|
9
|
+
NEW = "NEW"
|
|
10
|
+
}
|
|
11
|
+
export interface IntegrityResult {
|
|
12
|
+
status: IntegrityStatus;
|
|
13
|
+
hash: string;
|
|
14
|
+
fileCount: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class PolicyIntegrityManager {
|
|
17
|
+
/**
|
|
18
|
+
* Checks the integrity of policies in a given directory against the stored hash.
|
|
19
|
+
*
|
|
20
|
+
* @param scope The scope of the policy (e.g., 'project', 'user').
|
|
21
|
+
* @param identifier A unique identifier for the policy scope (e.g., project path).
|
|
22
|
+
* @param policyDir The directory containing the policy files.
|
|
23
|
+
* @returns IntegrityResult indicating if the current policies match the stored hash.
|
|
24
|
+
*/
|
|
25
|
+
checkIntegrity(scope: string, identifier: string, policyDir: string): Promise<IntegrityResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Accepts and persists the current integrity hash for a given policy scope.
|
|
28
|
+
*
|
|
29
|
+
* @param scope The scope of the policy.
|
|
30
|
+
* @param identifier A unique identifier for the policy scope (e.g., project path).
|
|
31
|
+
* @param hash The hash to persist.
|
|
32
|
+
*/
|
|
33
|
+
acceptIntegrity(scope: string, identifier: string, hash: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Calculates a SHA-256 hash of all policy files in the directory.
|
|
36
|
+
* The hash includes the relative file path and content to detect renames and modifications.
|
|
37
|
+
*
|
|
38
|
+
* @param policyDir The directory containing the policy files.
|
|
39
|
+
* @returns The calculated hash and file count
|
|
40
|
+
*/
|
|
41
|
+
private static calculateIntegrityHash;
|
|
42
|
+
private getIntegrityKey;
|
|
43
|
+
private loadIntegrityData;
|
|
44
|
+
private saveIntegrityData;
|
|
45
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import * as crypto from 'node:crypto';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { Storage } from '../config/storage.js';
|
|
10
|
+
import { readPolicyFiles } from './toml-loader.js';
|
|
11
|
+
import { debugLogger } from '../utils/debugLogger.js';
|
|
12
|
+
import { isNodeError } from '../utils/errors.js';
|
|
13
|
+
export var IntegrityStatus;
|
|
14
|
+
(function (IntegrityStatus) {
|
|
15
|
+
IntegrityStatus["MATCH"] = "MATCH";
|
|
16
|
+
IntegrityStatus["MISMATCH"] = "MISMATCH";
|
|
17
|
+
IntegrityStatus["NEW"] = "NEW";
|
|
18
|
+
})(IntegrityStatus || (IntegrityStatus = {}));
|
|
19
|
+
export class PolicyIntegrityManager {
|
|
20
|
+
/**
|
|
21
|
+
* Checks the integrity of policies in a given directory against the stored hash.
|
|
22
|
+
*
|
|
23
|
+
* @param scope The scope of the policy (e.g., 'project', 'user').
|
|
24
|
+
* @param identifier A unique identifier for the policy scope (e.g., project path).
|
|
25
|
+
* @param policyDir The directory containing the policy files.
|
|
26
|
+
* @returns IntegrityResult indicating if the current policies match the stored hash.
|
|
27
|
+
*/
|
|
28
|
+
async checkIntegrity(scope, identifier, policyDir) {
|
|
29
|
+
const { hash: currentHash, fileCount } = await PolicyIntegrityManager.calculateIntegrityHash(policyDir);
|
|
30
|
+
const storedData = await this.loadIntegrityData();
|
|
31
|
+
const key = this.getIntegrityKey(scope, identifier);
|
|
32
|
+
const storedHash = storedData[key];
|
|
33
|
+
if (!storedHash) {
|
|
34
|
+
return { status: IntegrityStatus.NEW, hash: currentHash, fileCount };
|
|
35
|
+
}
|
|
36
|
+
if (storedHash === currentHash) {
|
|
37
|
+
return { status: IntegrityStatus.MATCH, hash: currentHash, fileCount };
|
|
38
|
+
}
|
|
39
|
+
return { status: IntegrityStatus.MISMATCH, hash: currentHash, fileCount };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Accepts and persists the current integrity hash for a given policy scope.
|
|
43
|
+
*
|
|
44
|
+
* @param scope The scope of the policy.
|
|
45
|
+
* @param identifier A unique identifier for the policy scope (e.g., project path).
|
|
46
|
+
* @param hash The hash to persist.
|
|
47
|
+
*/
|
|
48
|
+
async acceptIntegrity(scope, identifier, hash) {
|
|
49
|
+
const storedData = await this.loadIntegrityData();
|
|
50
|
+
const key = this.getIntegrityKey(scope, identifier);
|
|
51
|
+
storedData[key] = hash;
|
|
52
|
+
await this.saveIntegrityData(storedData);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Calculates a SHA-256 hash of all policy files in the directory.
|
|
56
|
+
* The hash includes the relative file path and content to detect renames and modifications.
|
|
57
|
+
*
|
|
58
|
+
* @param policyDir The directory containing the policy files.
|
|
59
|
+
* @returns The calculated hash and file count
|
|
60
|
+
*/
|
|
61
|
+
static async calculateIntegrityHash(policyDir) {
|
|
62
|
+
try {
|
|
63
|
+
const files = await readPolicyFiles(policyDir);
|
|
64
|
+
// Sort files by path to ensure deterministic hashing
|
|
65
|
+
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
66
|
+
const hash = crypto.createHash('sha256');
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
const relativePath = path.relative(policyDir, file.path);
|
|
69
|
+
// Include relative path and content in the hash
|
|
70
|
+
hash.update(relativePath);
|
|
71
|
+
hash.update('\0'); // Separator
|
|
72
|
+
hash.update(file.content);
|
|
73
|
+
hash.update('\0'); // Separator
|
|
74
|
+
}
|
|
75
|
+
return { hash: hash.digest('hex'), fileCount: files.length };
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
debugLogger.error('Failed to calculate policy integrity hash', error);
|
|
79
|
+
// Return a unique hash (random) to force a mismatch if calculation fails?
|
|
80
|
+
// Or throw? Throwing is better so we don't accidentally accept/deny corrupted state.
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
getIntegrityKey(scope, identifier) {
|
|
85
|
+
return `${scope}:${identifier}`;
|
|
86
|
+
}
|
|
87
|
+
async loadIntegrityData() {
|
|
88
|
+
const storagePath = Storage.getPolicyIntegrityStoragePath();
|
|
89
|
+
try {
|
|
90
|
+
const content = await fs.readFile(storagePath, 'utf-8');
|
|
91
|
+
const parsed = JSON.parse(content);
|
|
92
|
+
if (typeof parsed === 'object' &&
|
|
93
|
+
parsed !== null &&
|
|
94
|
+
Object.values(parsed).every((v) => typeof v === 'string')) {
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
96
|
+
return parsed;
|
|
97
|
+
}
|
|
98
|
+
debugLogger.warn('Invalid policy integrity data format');
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (isNodeError(error) && error.code === 'ENOENT') {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
debugLogger.error('Failed to load policy integrity data', error);
|
|
106
|
+
return {};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async saveIntegrityData(data) {
|
|
110
|
+
const storagePath = Storage.getPolicyIntegrityStoragePath();
|
|
111
|
+
try {
|
|
112
|
+
await fs.mkdir(path.dirname(storagePath), { recursive: true });
|
|
113
|
+
await fs.writeFile(storagePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
debugLogger.error('Failed to save policy integrity data', error);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../../src/policy/integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
|
|
7
|
+
import { PolicyIntegrityManager, IntegrityStatus } from './integrity.js';
|
|
8
|
+
import * as fs from 'node:fs/promises';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
import { Storage } from '../config/storage.js';
|
|
12
|
+
describe('PolicyIntegrityManager', () => {
|
|
13
|
+
let integrityManager;
|
|
14
|
+
let tempDir;
|
|
15
|
+
let integrityStoragePath;
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gemini-cli-test-'));
|
|
18
|
+
integrityStoragePath = path.join(tempDir, 'policy_integrity.json');
|
|
19
|
+
vi.spyOn(Storage, 'getPolicyIntegrityStoragePath').mockReturnValue(integrityStoragePath);
|
|
20
|
+
integrityManager = new PolicyIntegrityManager();
|
|
21
|
+
});
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
24
|
+
vi.restoreAllMocks();
|
|
25
|
+
});
|
|
26
|
+
describe('checkIntegrity', () => {
|
|
27
|
+
it('should return NEW if no stored hash', async () => {
|
|
28
|
+
const policyDir = path.join(tempDir, 'policies');
|
|
29
|
+
await fs.mkdir(policyDir);
|
|
30
|
+
await fs.writeFile(path.join(policyDir, 'a.toml'), 'contentA');
|
|
31
|
+
const result = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
32
|
+
expect(result.status).toBe(IntegrityStatus.NEW);
|
|
33
|
+
expect(result.hash).toBeDefined();
|
|
34
|
+
expect(result.hash).toHaveLength(64);
|
|
35
|
+
expect(result.fileCount).toBe(1);
|
|
36
|
+
});
|
|
37
|
+
it('should return MATCH if stored hash matches', async () => {
|
|
38
|
+
const policyDir = path.join(tempDir, 'policies');
|
|
39
|
+
await fs.mkdir(policyDir);
|
|
40
|
+
await fs.writeFile(path.join(policyDir, 'a.toml'), 'contentA');
|
|
41
|
+
// First run to get the hash
|
|
42
|
+
const resultNew = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
43
|
+
const currentHash = resultNew.hash;
|
|
44
|
+
// Save the hash to mock storage
|
|
45
|
+
await fs.writeFile(integrityStoragePath, JSON.stringify({ 'workspace:id': currentHash }));
|
|
46
|
+
const result = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
47
|
+
expect(result.status).toBe(IntegrityStatus.MATCH);
|
|
48
|
+
expect(result.hash).toBe(currentHash);
|
|
49
|
+
});
|
|
50
|
+
it('should return MISMATCH if stored hash differs', async () => {
|
|
51
|
+
const policyDir = path.join(tempDir, 'policies');
|
|
52
|
+
await fs.mkdir(policyDir);
|
|
53
|
+
await fs.writeFile(path.join(policyDir, 'a.toml'), 'contentA');
|
|
54
|
+
const resultNew = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
55
|
+
const currentHash = resultNew.hash;
|
|
56
|
+
// Save a different hash
|
|
57
|
+
await fs.writeFile(integrityStoragePath, JSON.stringify({ 'workspace:id': 'different_hash' }));
|
|
58
|
+
const result = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
59
|
+
expect(result.status).toBe(IntegrityStatus.MISMATCH);
|
|
60
|
+
expect(result.hash).toBe(currentHash);
|
|
61
|
+
});
|
|
62
|
+
it('should result in different hash if filename changes', async () => {
|
|
63
|
+
const policyDir1 = path.join(tempDir, 'policies1');
|
|
64
|
+
await fs.mkdir(policyDir1);
|
|
65
|
+
await fs.writeFile(path.join(policyDir1, 'a.toml'), 'contentA');
|
|
66
|
+
const result1 = await integrityManager.checkIntegrity('workspace', 'id', policyDir1);
|
|
67
|
+
const policyDir2 = path.join(tempDir, 'policies2');
|
|
68
|
+
await fs.mkdir(policyDir2);
|
|
69
|
+
await fs.writeFile(path.join(policyDir2, 'b.toml'), 'contentA');
|
|
70
|
+
const result2 = await integrityManager.checkIntegrity('workspace', 'id', policyDir2);
|
|
71
|
+
expect(result1.hash).not.toBe(result2.hash);
|
|
72
|
+
});
|
|
73
|
+
it('should result in different hash if content changes', async () => {
|
|
74
|
+
const policyDir = path.join(tempDir, 'policies');
|
|
75
|
+
await fs.mkdir(policyDir);
|
|
76
|
+
await fs.writeFile(path.join(policyDir, 'a.toml'), 'contentA');
|
|
77
|
+
const result1 = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
78
|
+
await fs.writeFile(path.join(policyDir, 'a.toml'), 'contentB');
|
|
79
|
+
const result2 = await integrityManager.checkIntegrity('workspace', 'id', policyDir);
|
|
80
|
+
expect(result1.hash).not.toBe(result2.hash);
|
|
81
|
+
});
|
|
82
|
+
it('should be deterministic (sort order)', async () => {
|
|
83
|
+
const policyDir1 = path.join(tempDir, 'policies1');
|
|
84
|
+
await fs.mkdir(policyDir1);
|
|
85
|
+
await fs.writeFile(path.join(policyDir1, 'a.toml'), 'contentA');
|
|
86
|
+
await fs.writeFile(path.join(policyDir1, 'b.toml'), 'contentB');
|
|
87
|
+
const result1 = await integrityManager.checkIntegrity('workspace', 'id', policyDir1);
|
|
88
|
+
// Re-read with same files but they might be in different order in readdir
|
|
89
|
+
// PolicyIntegrityManager should sort them.
|
|
90
|
+
const result2 = await integrityManager.checkIntegrity('workspace', 'id', policyDir1);
|
|
91
|
+
expect(result1.hash).toBe(result2.hash);
|
|
92
|
+
});
|
|
93
|
+
it('should handle multiple projects correctly', async () => {
|
|
94
|
+
const dirA = path.join(tempDir, 'dirA');
|
|
95
|
+
await fs.mkdir(dirA);
|
|
96
|
+
await fs.writeFile(path.join(dirA, 'p.toml'), 'contentA');
|
|
97
|
+
const dirB = path.join(tempDir, 'dirB');
|
|
98
|
+
await fs.mkdir(dirB);
|
|
99
|
+
await fs.writeFile(path.join(dirB, 'p.toml'), 'contentB');
|
|
100
|
+
const { hash: hashA } = await integrityManager.checkIntegrity('workspace', 'idA', dirA);
|
|
101
|
+
const { hash: hashB } = await integrityManager.checkIntegrity('workspace', 'idB', dirB);
|
|
102
|
+
// Save to storage
|
|
103
|
+
await fs.writeFile(integrityStoragePath, JSON.stringify({
|
|
104
|
+
'workspace:idA': hashA,
|
|
105
|
+
'workspace:idB': 'oldHashB',
|
|
106
|
+
}));
|
|
107
|
+
// Project A should match
|
|
108
|
+
const resultA = await integrityManager.checkIntegrity('workspace', 'idA', dirA);
|
|
109
|
+
expect(resultA.status).toBe(IntegrityStatus.MATCH);
|
|
110
|
+
expect(resultA.hash).toBe(hashA);
|
|
111
|
+
// Project B should mismatch
|
|
112
|
+
const resultB = await integrityManager.checkIntegrity('workspace', 'idB', dirB);
|
|
113
|
+
expect(resultB.status).toBe(IntegrityStatus.MISMATCH);
|
|
114
|
+
expect(resultB.hash).toBe(hashB);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
describe('acceptIntegrity', () => {
|
|
118
|
+
it('should save the hash to storage', async () => {
|
|
119
|
+
await integrityManager.acceptIntegrity('workspace', 'id', 'hash123');
|
|
120
|
+
const stored = JSON.parse(await fs.readFile(integrityStoragePath, 'utf-8'));
|
|
121
|
+
expect(stored['workspace:id']).toBe('hash123');
|
|
122
|
+
});
|
|
123
|
+
it('should update existing hash', async () => {
|
|
124
|
+
await fs.writeFile(integrityStoragePath, JSON.stringify({ 'other:id': 'otherhash' }));
|
|
125
|
+
await integrityManager.acceptIntegrity('workspace', 'id', 'hash123');
|
|
126
|
+
const stored = JSON.parse(await fs.readFile(integrityStoragePath, 'utf-8'));
|
|
127
|
+
expect(stored['other:id']).toBe('otherhash');
|
|
128
|
+
expect(stored['workspace:id']).toBe('hash123');
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=integrity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.test.js","sourceRoot":"","sources":["../../../src/policy/integrity.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
|
|
7
|
+
import nodePath from 'node:path';
|
|
8
|
+
import { ApprovalMode } from './types.js';
|
|
9
|
+
import { isDirectorySecure } from '../utils/security.js';
|
|
10
|
+
// Mock dependencies
|
|
11
|
+
vi.mock('../utils/security.js', () => ({
|
|
12
|
+
isDirectorySecure: vi.fn().mockResolvedValue({ secure: true }),
|
|
13
|
+
}));
|
|
14
|
+
describe('Workspace-Level Policies', () => {
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
vi.resetModules();
|
|
17
|
+
const { Storage } = await import('../config/storage.js');
|
|
18
|
+
vi.spyOn(Storage, 'getUserPoliciesDir').mockReturnValue('/mock/user/policies');
|
|
19
|
+
vi.spyOn(Storage, 'getSystemPoliciesDir').mockReturnValue('/mock/system/policies');
|
|
20
|
+
// Ensure security check always returns secure
|
|
21
|
+
vi.mocked(isDirectorySecure).mockResolvedValue({ secure: true });
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
vi.doUnmock('node:fs/promises');
|
|
27
|
+
});
|
|
28
|
+
it('should load workspace policies with correct priority (Tier 3)', async () => {
|
|
29
|
+
const workspacePoliciesDir = '/mock/workspace/policies';
|
|
30
|
+
const defaultPoliciesDir = '/mock/default/policies';
|
|
31
|
+
// Mock FS
|
|
32
|
+
const actualFs = await vi.importActual('node:fs/promises');
|
|
33
|
+
const mockStat = vi.fn(async (path) => {
|
|
34
|
+
if (typeof path === 'string' && path.startsWith('/mock/')) {
|
|
35
|
+
return {
|
|
36
|
+
isDirectory: () => true,
|
|
37
|
+
isFile: () => false,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return actualFs.stat(path);
|
|
41
|
+
});
|
|
42
|
+
// Mock readdir to return a policy file for each tier
|
|
43
|
+
const mockReaddir = vi.fn(async (path) => {
|
|
44
|
+
const normalizedPath = nodePath.normalize(path);
|
|
45
|
+
if (normalizedPath.endsWith('default/policies'))
|
|
46
|
+
return [
|
|
47
|
+
{
|
|
48
|
+
name: 'default.toml',
|
|
49
|
+
isFile: () => true,
|
|
50
|
+
isDirectory: () => false,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
if (normalizedPath.endsWith('user/policies'))
|
|
54
|
+
return [
|
|
55
|
+
{ name: 'user.toml', isFile: () => true, isDirectory: () => false },
|
|
56
|
+
];
|
|
57
|
+
if (normalizedPath.endsWith('workspace/policies'))
|
|
58
|
+
return [
|
|
59
|
+
{
|
|
60
|
+
name: 'workspace.toml',
|
|
61
|
+
isFile: () => true,
|
|
62
|
+
isDirectory: () => false,
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
if (normalizedPath.endsWith('system/policies'))
|
|
66
|
+
return [
|
|
67
|
+
{ name: 'admin.toml', isFile: () => true, isDirectory: () => false },
|
|
68
|
+
];
|
|
69
|
+
return [];
|
|
70
|
+
});
|
|
71
|
+
// Mock readFile to return content with distinct priorities/decisions
|
|
72
|
+
const mockReadFile = vi.fn(async (path) => {
|
|
73
|
+
if (path.includes('default.toml')) {
|
|
74
|
+
return `[[rule]]
|
|
75
|
+
toolName = "test_tool"
|
|
76
|
+
decision = "allow"
|
|
77
|
+
priority = 10
|
|
78
|
+
`; // Tier 1 -> 1.010
|
|
79
|
+
}
|
|
80
|
+
if (path.includes('user.toml')) {
|
|
81
|
+
return `[[rule]]
|
|
82
|
+
toolName = "test_tool"
|
|
83
|
+
decision = "deny"
|
|
84
|
+
priority = 10
|
|
85
|
+
`; // Tier 4 -> 4.010
|
|
86
|
+
}
|
|
87
|
+
if (path.includes('workspace.toml')) {
|
|
88
|
+
return `[[rule]]
|
|
89
|
+
toolName = "test_tool"
|
|
90
|
+
decision = "allow"
|
|
91
|
+
priority = 10
|
|
92
|
+
`; // Tier 3 -> 3.010
|
|
93
|
+
}
|
|
94
|
+
if (path.includes('admin.toml')) {
|
|
95
|
+
return `[[rule]]
|
|
96
|
+
toolName = "test_tool"
|
|
97
|
+
decision = "deny"
|
|
98
|
+
priority = 10
|
|
99
|
+
`; // Tier 5 -> 5.010
|
|
100
|
+
}
|
|
101
|
+
return '';
|
|
102
|
+
});
|
|
103
|
+
vi.doMock('node:fs/promises', () => ({
|
|
104
|
+
...actualFs,
|
|
105
|
+
default: {
|
|
106
|
+
...actualFs,
|
|
107
|
+
readdir: mockReaddir,
|
|
108
|
+
readFile: mockReadFile,
|
|
109
|
+
stat: mockStat,
|
|
110
|
+
},
|
|
111
|
+
readdir: mockReaddir,
|
|
112
|
+
readFile: mockReadFile,
|
|
113
|
+
stat: mockStat,
|
|
114
|
+
}));
|
|
115
|
+
const { createPolicyEngineConfig } = await import('./config.js');
|
|
116
|
+
// Test 1: Workspace vs User (User should win)
|
|
117
|
+
const config = await createPolicyEngineConfig({ workspacePoliciesDir }, ApprovalMode.DEFAULT, defaultPoliciesDir);
|
|
118
|
+
const rules = config.rules?.filter((r) => r.toolName === 'test_tool');
|
|
119
|
+
expect(rules).toBeDefined();
|
|
120
|
+
// Check for all 4 rules
|
|
121
|
+
const defaultRule = rules?.find((r) => r.priority === 1.01);
|
|
122
|
+
const workspaceRule = rules?.find((r) => r.priority === 3.01);
|
|
123
|
+
const userRule = rules?.find((r) => r.priority === 4.01);
|
|
124
|
+
const adminRule = rules?.find((r) => r.priority === 5.01);
|
|
125
|
+
expect(defaultRule).toBeDefined();
|
|
126
|
+
expect(userRule).toBeDefined();
|
|
127
|
+
expect(workspaceRule).toBeDefined();
|
|
128
|
+
expect(adminRule).toBeDefined();
|
|
129
|
+
// Verify Hierarchy: Admin > User > Workspace > Default
|
|
130
|
+
expect(adminRule.priority).toBeGreaterThan(userRule.priority);
|
|
131
|
+
expect(userRule.priority).toBeGreaterThan(workspaceRule.priority);
|
|
132
|
+
expect(workspaceRule.priority).toBeGreaterThan(defaultRule.priority);
|
|
133
|
+
});
|
|
134
|
+
it('should ignore workspace policies if workspacePoliciesDir is undefined', async () => {
|
|
135
|
+
const defaultPoliciesDir = '/mock/default/policies';
|
|
136
|
+
// Mock FS (simplified)
|
|
137
|
+
const actualFs = await vi.importActual('node:fs/promises');
|
|
138
|
+
const mockStat = vi.fn(async (path) => {
|
|
139
|
+
if (typeof path === 'string' && path.startsWith('/mock/')) {
|
|
140
|
+
return {
|
|
141
|
+
isDirectory: () => true,
|
|
142
|
+
isFile: () => false,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return actualFs.stat(path);
|
|
146
|
+
});
|
|
147
|
+
const mockReaddir = vi.fn(async (path) => {
|
|
148
|
+
const normalizedPath = nodePath.normalize(path);
|
|
149
|
+
if (normalizedPath.endsWith('default/policies'))
|
|
150
|
+
return [
|
|
151
|
+
{
|
|
152
|
+
name: 'default.toml',
|
|
153
|
+
isFile: () => true,
|
|
154
|
+
isDirectory: () => false,
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
return [];
|
|
158
|
+
});
|
|
159
|
+
const mockReadFile = vi.fn(async () => `[[rule]]
|
|
160
|
+
toolName="t"
|
|
161
|
+
decision="allow"
|
|
162
|
+
priority=10`);
|
|
163
|
+
vi.doMock('node:fs/promises', () => ({
|
|
164
|
+
...actualFs,
|
|
165
|
+
default: {
|
|
166
|
+
...actualFs,
|
|
167
|
+
readdir: mockReaddir,
|
|
168
|
+
readFile: mockReadFile,
|
|
169
|
+
stat: mockStat,
|
|
170
|
+
},
|
|
171
|
+
readdir: mockReaddir,
|
|
172
|
+
readFile: mockReadFile,
|
|
173
|
+
stat: mockStat,
|
|
174
|
+
}));
|
|
175
|
+
const { createPolicyEngineConfig } = await import('./config.js');
|
|
176
|
+
const config = await createPolicyEngineConfig({ workspacePoliciesDir: undefined }, ApprovalMode.DEFAULT, defaultPoliciesDir);
|
|
177
|
+
// Should only have default tier rule (1.01)
|
|
178
|
+
const rules = config.rules;
|
|
179
|
+
expect(rules).toHaveLength(1);
|
|
180
|
+
expect(rules[0].priority).toBe(1.01);
|
|
181
|
+
});
|
|
182
|
+
it('should load workspace policies and correctly transform to Tier 3', async () => {
|
|
183
|
+
const workspacePoliciesDir = '/mock/workspace/policies';
|
|
184
|
+
// Mock FS
|
|
185
|
+
const actualFs = await vi.importActual('node:fs/promises');
|
|
186
|
+
const mockStat = vi.fn(async (path) => {
|
|
187
|
+
if (typeof path === 'string' && path.startsWith('/mock/')) {
|
|
188
|
+
return {
|
|
189
|
+
isDirectory: () => true,
|
|
190
|
+
isFile: () => false,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return actualFs.stat(path);
|
|
194
|
+
});
|
|
195
|
+
const mockReaddir = vi.fn(async (path) => {
|
|
196
|
+
const normalizedPath = nodePath.normalize(path);
|
|
197
|
+
if (normalizedPath.endsWith('workspace/policies'))
|
|
198
|
+
return [
|
|
199
|
+
{
|
|
200
|
+
name: 'workspace.toml',
|
|
201
|
+
isFile: () => true,
|
|
202
|
+
isDirectory: () => false,
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
return [];
|
|
206
|
+
});
|
|
207
|
+
const mockReadFile = vi.fn(async () => `[[rule]]
|
|
208
|
+
toolName="p_tool"
|
|
209
|
+
decision="allow"
|
|
210
|
+
priority=500`);
|
|
211
|
+
vi.doMock('node:fs/promises', () => ({
|
|
212
|
+
...actualFs,
|
|
213
|
+
default: {
|
|
214
|
+
...actualFs,
|
|
215
|
+
readdir: mockReaddir,
|
|
216
|
+
readFile: mockReadFile,
|
|
217
|
+
stat: mockStat,
|
|
218
|
+
},
|
|
219
|
+
readdir: mockReaddir,
|
|
220
|
+
readFile: mockReadFile,
|
|
221
|
+
stat: mockStat,
|
|
222
|
+
}));
|
|
223
|
+
const { createPolicyEngineConfig } = await import('./config.js');
|
|
224
|
+
const config = await createPolicyEngineConfig({ workspacePoliciesDir }, ApprovalMode.DEFAULT);
|
|
225
|
+
const rule = config.rules?.find((r) => r.toolName === 'p_tool');
|
|
226
|
+
expect(rule).toBeDefined();
|
|
227
|
+
// Workspace Tier (3) + 500/1000 = 3.5
|
|
228
|
+
expect(rule?.priority).toBe(3.5);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=workspace-policy.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-policy.test.js","sourceRoot":"","sources":["../../../src/policy/workspace-policy.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Config } from '../../config/config.js';
|
|
7
|
+
import type { BaseLlmClient } from '../../core/baseLlmClient.js';
|
|
8
|
+
import type { RoutingContext, RoutingDecision, RoutingStrategy } from '../routingStrategy.js';
|
|
9
|
+
/**
|
|
10
|
+
* A strategy that routes based on the current ApprovalMode and plan status.
|
|
11
|
+
*
|
|
12
|
+
* - In PLAN mode: Routes to the PRO model for high-quality planning.
|
|
13
|
+
* - In other modes with an approved plan: Routes to the FLASH model for efficient implementation.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ApprovalModeStrategy implements RoutingStrategy {
|
|
16
|
+
readonly name = "approval-mode";
|
|
17
|
+
route(context: RoutingContext, config: Config, _baseLlmClient: BaseLlmClient): Promise<RoutingDecision | null>;
|
|
18
|
+
}
|