@google/gemini-cli-core 0.40.0-preview.2 → 0.40.0-preview.3

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 (52) hide show
  1. package/dist/docs/cli/cli-reference.md +1 -0
  2. package/dist/docs/cli/trusted-folders.md +28 -0
  3. package/dist/docs/reference/configuration.md +14 -0
  4. package/dist/google-gemini-cli-core-0.40.0-preview.2.tgz +0 -0
  5. package/dist/src/config/storage.d.ts +2 -0
  6. package/dist/src/config/storage.js +7 -0
  7. package/dist/src/config/storage.js.map +1 -1
  8. package/dist/src/generated/git-commit.d.ts +2 -2
  9. package/dist/src/generated/git-commit.js +2 -2
  10. package/dist/src/index.d.ts +1 -0
  11. package/dist/src/index.js +2 -0
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/policy/config.d.ts +2 -0
  14. package/dist/src/policy/config.js +64 -10
  15. package/dist/src/policy/config.js.map +1 -1
  16. package/dist/src/policy/core-tools-mapping.test.d.ts +6 -0
  17. package/dist/src/policy/core-tools-mapping.test.js +44 -0
  18. package/dist/src/policy/core-tools-mapping.test.js.map +1 -0
  19. package/dist/src/policy/policy-engine.d.ts +1 -1
  20. package/dist/src/policy/policy-engine.js +57 -66
  21. package/dist/src/policy/policy-engine.js.map +1 -1
  22. package/dist/src/policy/policy-engine.test.js +32 -2
  23. package/dist/src/policy/policy-engine.test.js.map +1 -1
  24. package/dist/src/policy/shell-safety-regression.test.d.ts +6 -0
  25. package/dist/src/policy/shell-safety-regression.test.js +86 -0
  26. package/dist/src/policy/shell-safety-regression.test.js.map +1 -0
  27. package/dist/src/policy/shell-safety.test.js +24 -0
  28. package/dist/src/policy/shell-safety.test.js.map +1 -1
  29. package/dist/src/policy/shell-substitution.test.d.ts +6 -0
  30. package/dist/src/policy/shell-substitution.test.js +75 -0
  31. package/dist/src/policy/shell-substitution.test.js.map +1 -0
  32. package/dist/src/policy/types.d.ts +2 -0
  33. package/dist/src/policy/types.js.map +1 -1
  34. package/dist/src/tools/ripGrep.test.js +2 -2
  35. package/dist/src/tools/ripGrep.test.js.map +1 -1
  36. package/dist/src/utils/errors.d.ts +3 -0
  37. package/dist/src/utils/errors.js +6 -0
  38. package/dist/src/utils/errors.js.map +1 -1
  39. package/dist/src/utils/paths.d.ts +1 -0
  40. package/dist/src/utils/paths.js +1 -0
  41. package/dist/src/utils/paths.js.map +1 -1
  42. package/dist/src/utils/shell-utils.d.ts +1 -0
  43. package/dist/src/utils/shell-utils.js +13 -1
  44. package/dist/src/utils/shell-utils.js.map +1 -1
  45. package/dist/src/utils/trust.d.ts +64 -0
  46. package/dist/src/utils/trust.js +276 -0
  47. package/dist/src/utils/trust.js.map +1 -0
  48. package/dist/src/utils/trust.test.d.ts +6 -0
  49. package/dist/src/utils/trust.test.js +159 -0
  50. package/dist/src/utils/trust.test.js.map +1 -0
  51. package/dist/tsconfig.tsbuildinfo +1 -1
  52. package/package.json +1 -1
@@ -0,0 +1,159 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import * as os from 'node:os';
10
+ import { TrustLevel, loadTrustedFolders, resetTrustedFoldersForTesting, checkPathTrust, } from './trust.js';
11
+ import { Storage } from '../config/storage.js';
12
+ import { lock } from 'proper-lockfile';
13
+ import { ideContextStore } from '../ide/ideContext.js';
14
+ import * as headless from './headless.js';
15
+ import { coreEvents } from './events.js';
16
+ vi.mock('proper-lockfile');
17
+ vi.mock('./headless.js', async (importOriginal) => {
18
+ const original = await importOriginal();
19
+ return {
20
+ ...original,
21
+ isHeadlessMode: vi.fn(),
22
+ };
23
+ });
24
+ describe('Trust Utility (Core)', () => {
25
+ const tempDir = path.join(os.tmpdir(), 'gemini-trust-test-' + Math.random().toString(36).slice(2));
26
+ const trustedFoldersPath = path.join(tempDir, 'trustedFolders.json');
27
+ beforeEach(() => {
28
+ fs.mkdirSync(tempDir, { recursive: true });
29
+ vi.spyOn(Storage, 'getTrustedFoldersPath').mockReturnValue(trustedFoldersPath);
30
+ vi.mocked(lock).mockResolvedValue(vi.fn().mockResolvedValue(undefined));
31
+ vi.mocked(headless.isHeadlessMode).mockReturnValue(false);
32
+ ideContextStore.clear();
33
+ resetTrustedFoldersForTesting();
34
+ delete process.env['GEMINI_CLI_TRUST_WORKSPACE'];
35
+ });
36
+ afterEach(() => {
37
+ fs.rmSync(tempDir, { recursive: true, force: true });
38
+ vi.restoreAllMocks();
39
+ });
40
+ it('should load empty config if file does not exist', () => {
41
+ const folders = loadTrustedFolders();
42
+ expect(folders.user.config).toEqual({});
43
+ expect(folders.errors).toEqual([]);
44
+ });
45
+ it('should load config from file', () => {
46
+ const config = {
47
+ [path.resolve('/trusted/path')]: TrustLevel.TRUST_FOLDER,
48
+ };
49
+ fs.writeFileSync(trustedFoldersPath, JSON.stringify(config));
50
+ const folders = loadTrustedFolders();
51
+ // Use path.resolve for platform consistency in tests
52
+ const normalizedKey = path.resolve('/trusted/path').replace(/\\/g, '/');
53
+ const isWindows = process.platform === 'win32';
54
+ const finalKey = isWindows ? normalizedKey.toLowerCase() : normalizedKey;
55
+ expect(folders.user.config[finalKey]).toBe(TrustLevel.TRUST_FOLDER);
56
+ });
57
+ it('should handle isPathTrusted with longest match', () => {
58
+ const config = {
59
+ [path.resolve('/a')]: TrustLevel.TRUST_FOLDER,
60
+ [path.resolve('/a/b')]: TrustLevel.DO_NOT_TRUST,
61
+ [path.resolve('/a/b/c')]: TrustLevel.TRUST_FOLDER,
62
+ };
63
+ fs.writeFileSync(trustedFoldersPath, JSON.stringify(config));
64
+ const folders = loadTrustedFolders();
65
+ expect(folders.isPathTrusted(path.resolve('/a/file.txt'))).toBe(true);
66
+ expect(folders.isPathTrusted(path.resolve('/a/b/file.txt'))).toBe(false);
67
+ expect(folders.isPathTrusted(path.resolve('/a/b/c/file.txt'))).toBe(true);
68
+ expect(folders.isPathTrusted(path.resolve('/other'))).toBeUndefined();
69
+ });
70
+ it('should handle TRUST_PARENT', () => {
71
+ const config = {
72
+ [path.resolve('/project/.gemini')]: TrustLevel.TRUST_PARENT,
73
+ };
74
+ fs.writeFileSync(trustedFoldersPath, JSON.stringify(config));
75
+ const folders = loadTrustedFolders();
76
+ expect(folders.isPathTrusted(path.resolve('/project/file.txt'))).toBe(true);
77
+ expect(folders.isPathTrusted(path.resolve('/project/.gemini/config.yaml'))).toBe(true);
78
+ });
79
+ it('should save config correctly', async () => {
80
+ const folders = loadTrustedFolders();
81
+ const testPath = path.resolve('/new/trusted/path');
82
+ await folders.setValue(testPath, TrustLevel.TRUST_FOLDER);
83
+ const savedContent = JSON.parse(fs.readFileSync(trustedFoldersPath, 'utf-8'));
84
+ const normalizedKey = testPath.replace(/\\/g, '/');
85
+ const isWindows = process.platform === 'win32';
86
+ const finalKey = isWindows ? normalizedKey.toLowerCase() : normalizedKey;
87
+ expect(savedContent[finalKey]).toBe(TrustLevel.TRUST_FOLDER);
88
+ });
89
+ it('should handle comments in JSON', () => {
90
+ const content = `
91
+ {
92
+ // This is a comment
93
+ "path": "TRUST_FOLDER"
94
+ }
95
+ `;
96
+ fs.writeFileSync(trustedFoldersPath, content);
97
+ const folders = loadTrustedFolders();
98
+ expect(folders.errors).toHaveLength(0);
99
+ });
100
+ describe('checkPathTrust', () => {
101
+ it('should NOT return trusted if headless mode is on by default', () => {
102
+ const result = checkPathTrust({
103
+ path: '/any',
104
+ isFolderTrustEnabled: true,
105
+ isHeadless: true,
106
+ });
107
+ expect(result).toEqual({ isTrusted: undefined, source: undefined });
108
+ });
109
+ it('should return trusted if folder trust is disabled', () => {
110
+ const result = checkPathTrust({
111
+ path: '/any',
112
+ isFolderTrustEnabled: false,
113
+ });
114
+ expect(result).toEqual({ isTrusted: true, source: undefined });
115
+ });
116
+ it('should return IDE trust if available', () => {
117
+ ideContextStore.set({
118
+ workspaceState: { isTrusted: true },
119
+ });
120
+ const result = checkPathTrust({
121
+ path: '/any',
122
+ isFolderTrustEnabled: true,
123
+ });
124
+ expect(result).toEqual({ isTrusted: true, source: 'ide' });
125
+ });
126
+ it('should fall back to file trust', () => {
127
+ const config = {
128
+ [path.resolve('/trusted')]: TrustLevel.TRUST_FOLDER,
129
+ };
130
+ fs.writeFileSync(trustedFoldersPath, JSON.stringify(config));
131
+ const result = checkPathTrust({
132
+ path: path.resolve('/trusted/file.txt'),
133
+ isFolderTrustEnabled: true,
134
+ });
135
+ expect(result).toEqual({ isTrusted: true, source: 'file' });
136
+ });
137
+ it('should return undefined trust if no rule matches', () => {
138
+ const result = checkPathTrust({
139
+ path: '/any',
140
+ isFolderTrustEnabled: true,
141
+ });
142
+ expect(result).toEqual({ isTrusted: undefined, source: undefined });
143
+ });
144
+ });
145
+ describe('coreEvents.emitFeedback', () => {
146
+ it('should report corrupted config via coreEvents.emitFeedback in setValue', async () => {
147
+ const folders = loadTrustedFolders();
148
+ const testPath = path.resolve('/new/path');
149
+ // Initialize with valid JSON
150
+ fs.writeFileSync(trustedFoldersPath, '{}', 'utf-8');
151
+ // Corrupt the file after initial load
152
+ fs.writeFileSync(trustedFoldersPath, 'invalid json', 'utf-8');
153
+ const spy = vi.spyOn(coreEvents, 'emitFeedback');
154
+ await folders.setValue(testPath, TrustLevel.TRUST_FOLDER);
155
+ expect(spy).toHaveBeenCalledWith('error', expect.stringContaining('may be corrupted'), expect.any(Error));
156
+ });
157
+ });
158
+ });
159
+ //# sourceMappingURL=trust.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust.test.js","sourceRoot":"","sources":["../../../src/utils/trust.test.ts"],"names":[],"mappings":"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"}