gencode-ai 0.1.1 → 0.1.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.
- package/.gencode/settings.local.json +7 -0
- package/CLAUDE.md +86 -0
- package/README.md +13 -16
- package/dist/agent/agent.d.ts +50 -1
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +96 -16
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/types.d.ts +14 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/components/App.d.ts +8 -1
- package/dist/cli/components/App.d.ts.map +1 -1
- package/dist/cli/components/App.js +266 -29
- package/dist/cli/components/App.js.map +1 -1
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
- package/dist/cli/components/CommandSuggestions.js +2 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -1
- package/dist/cli/components/Header.d.ts +1 -1
- package/dist/cli/components/Header.d.ts.map +1 -1
- package/dist/cli/components/Header.js +4 -6
- package/dist/cli/components/Header.js.map +1 -1
- package/dist/cli/components/Logo.d.ts +1 -0
- package/dist/cli/components/Logo.d.ts.map +1 -1
- package/dist/cli/components/Logo.js +16 -3
- package/dist/cli/components/Logo.js.map +1 -1
- package/dist/cli/components/Messages.d.ts +4 -4
- package/dist/cli/components/Messages.d.ts.map +1 -1
- package/dist/cli/components/Messages.js +66 -23
- package/dist/cli/components/Messages.js.map +1 -1
- package/dist/cli/components/PermissionPrompt.d.ts +60 -0
- package/dist/cli/components/PermissionPrompt.d.ts.map +1 -0
- package/dist/cli/components/PermissionPrompt.js +192 -0
- package/dist/cli/components/PermissionPrompt.js.map +1 -0
- package/dist/cli/components/ProviderManager.js +3 -3
- package/dist/cli/components/ProviderManager.js.map +1 -1
- package/dist/cli/components/QuestionPrompt.d.ts +23 -0
- package/dist/cli/components/QuestionPrompt.d.ts.map +1 -0
- package/dist/cli/components/QuestionPrompt.js +231 -0
- package/dist/cli/components/QuestionPrompt.js.map +1 -0
- package/dist/cli/components/Spinner.d.ts +7 -2
- package/dist/cli/components/Spinner.d.ts.map +1 -1
- package/dist/cli/components/Spinner.js +116 -25
- package/dist/cli/components/Spinner.js.map +1 -1
- package/dist/cli/components/TodoList.d.ts +7 -0
- package/dist/cli/components/TodoList.d.ts.map +1 -0
- package/dist/cli/components/TodoList.js +34 -0
- package/dist/cli/components/TodoList.js.map +1 -0
- package/dist/cli/components/index.d.ts +2 -0
- package/dist/cli/components/index.d.ts.map +1 -1
- package/dist/cli/components/index.js +2 -0
- package/dist/cli/components/index.js.map +1 -1
- package/dist/cli/components/theme.d.ts +7 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +11 -1
- package/dist/cli/components/theme.js.map +1 -1
- package/dist/cli/index.js +47 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +13 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +18 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config/levels.d.ts +49 -0
- package/dist/config/levels.d.ts.map +1 -0
- package/dist/config/levels.js +222 -0
- package/dist/config/levels.js.map +1 -0
- package/dist/config/loader.d.ts +46 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +153 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/manager.d.ts +115 -15
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +260 -34
- package/dist/config/manager.js.map +1 -1
- package/dist/config/manager.test.d.ts +5 -0
- package/dist/config/manager.test.d.ts.map +1 -0
- package/dist/config/manager.test.js +192 -0
- package/dist/config/manager.test.js.map +1 -0
- package/dist/config/merger.d.ts +56 -0
- package/dist/config/merger.d.ts.map +1 -0
- package/dist/config/merger.js +177 -0
- package/dist/config/merger.js.map +1 -0
- package/dist/config/test-utils.d.ts +24 -0
- package/dist/config/test-utils.d.ts.map +1 -0
- package/dist/config/test-utils.js +55 -0
- package/dist/config/test-utils.js.map +1 -0
- package/dist/config/types.d.ts +78 -9
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +52 -2
- package/dist/config/types.js.map +1 -1
- package/dist/memory/import-resolver.d.ts +46 -0
- package/dist/memory/import-resolver.d.ts.map +1 -0
- package/dist/memory/import-resolver.js +117 -0
- package/dist/memory/import-resolver.js.map +1 -0
- package/dist/memory/index.d.ts +7 -6
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +7 -5
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/init-prompt.d.ts +22 -0
- package/dist/memory/init-prompt.d.ts.map +1 -0
- package/dist/memory/init-prompt.js +103 -0
- package/dist/memory/init-prompt.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +119 -0
- package/dist/memory/memory-manager.d.ts.map +1 -0
- package/dist/memory/memory-manager.js +587 -0
- package/dist/memory/memory-manager.js.map +1 -0
- package/dist/memory/rules-parser.d.ts +38 -0
- package/dist/memory/rules-parser.d.ts.map +1 -0
- package/dist/memory/rules-parser.js +69 -0
- package/dist/memory/rules-parser.js.map +1 -0
- package/dist/memory/test-utils.d.ts +20 -0
- package/dist/memory/test-utils.d.ts.map +1 -0
- package/dist/memory/test-utils.js +44 -0
- package/dist/memory/test-utils.js.map +1 -0
- package/dist/memory/types.d.ts +70 -63
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +42 -2
- package/dist/memory/types.js.map +1 -1
- package/dist/permissions/audit.d.ts +82 -0
- package/dist/permissions/audit.d.ts.map +1 -0
- package/dist/permissions/audit.js +229 -0
- package/dist/permissions/audit.js.map +1 -0
- package/dist/permissions/index.d.ts +11 -1
- package/dist/permissions/index.d.ts.map +1 -1
- package/dist/permissions/index.js +15 -0
- package/dist/permissions/index.js.map +1 -1
- package/dist/permissions/manager.d.ts +149 -13
- package/dist/permissions/manager.d.ts.map +1 -1
- package/dist/permissions/manager.js +480 -35
- package/dist/permissions/manager.js.map +1 -1
- package/dist/permissions/manager.test.d.ts +5 -0
- package/dist/permissions/manager.test.d.ts.map +1 -0
- package/dist/permissions/manager.test.js +213 -0
- package/dist/permissions/manager.test.js.map +1 -0
- package/dist/permissions/persistence.d.ts +74 -0
- package/dist/permissions/persistence.d.ts.map +1 -0
- package/dist/permissions/persistence.js +248 -0
- package/dist/permissions/persistence.js.map +1 -0
- package/dist/permissions/persistence.test.d.ts +5 -0
- package/dist/permissions/persistence.test.d.ts.map +1 -0
- package/dist/permissions/persistence.test.js +171 -0
- package/dist/permissions/persistence.test.js.map +1 -0
- package/dist/permissions/prompt-matcher.d.ts +64 -0
- package/dist/permissions/prompt-matcher.d.ts.map +1 -0
- package/dist/permissions/prompt-matcher.js +415 -0
- package/dist/permissions/prompt-matcher.js.map +1 -0
- package/dist/permissions/prompt-matcher.test.d.ts +5 -0
- package/dist/permissions/prompt-matcher.test.d.ts.map +1 -0
- package/dist/permissions/prompt-matcher.test.js +107 -0
- package/dist/permissions/prompt-matcher.test.js.map +1 -0
- package/dist/permissions/types.d.ts +157 -0
- package/dist/permissions/types.d.ts.map +1 -1
- package/dist/permissions/types.js +45 -8
- package/dist/permissions/types.js.map +1 -1
- package/dist/prompts/index.d.ts +92 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +241 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/tools/builtin/ask-user.d.ts +64 -0
- package/dist/tools/builtin/ask-user.d.ts.map +1 -0
- package/dist/tools/builtin/ask-user.js +148 -0
- package/dist/tools/builtin/ask-user.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts.map +1 -1
- package/dist/tools/builtin/bash.js +2 -1
- package/dist/tools/builtin/bash.js.map +1 -1
- package/dist/tools/builtin/edit.d.ts.map +1 -1
- package/dist/tools/builtin/edit.js +2 -1
- package/dist/tools/builtin/edit.js.map +1 -1
- package/dist/tools/builtin/glob.d.ts.map +1 -1
- package/dist/tools/builtin/glob.js +2 -1
- package/dist/tools/builtin/glob.js.map +1 -1
- package/dist/tools/builtin/grep.d.ts.map +1 -1
- package/dist/tools/builtin/grep.js +2 -1
- package/dist/tools/builtin/grep.js.map +1 -1
- package/dist/tools/builtin/read.d.ts.map +1 -1
- package/dist/tools/builtin/read.js +2 -1
- package/dist/tools/builtin/read.js.map +1 -1
- package/dist/tools/builtin/todowrite.d.ts +15 -0
- package/dist/tools/builtin/todowrite.d.ts.map +1 -0
- package/dist/tools/builtin/todowrite.js +88 -0
- package/dist/tools/builtin/todowrite.js.map +1 -0
- package/dist/tools/builtin/webfetch.d.ts.map +1 -1
- package/dist/tools/builtin/webfetch.js +2 -5
- package/dist/tools/builtin/webfetch.js.map +1 -1
- package/dist/tools/builtin/websearch.d.ts.map +1 -1
- package/dist/tools/builtin/websearch.js +2 -16
- package/dist/tools/builtin/websearch.js.map +1 -1
- package/dist/tools/builtin/write.d.ts.map +1 -1
- package/dist/tools/builtin/write.js +2 -1
- package/dist/tools/builtin/write.js.map +1 -1
- package/dist/tools/index.d.ts +19 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/types.d.ts +39 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +8 -0
- package/dist/tools/types.js.map +1 -1
- package/docs/config-system-comparison.md +707 -0
- package/docs/memory-system.md +238 -0
- package/docs/permissions.md +368 -0
- package/docs/proposals/0005-todo-system.md +350 -85
- package/docs/proposals/0006-memory-system.md +11 -10
- package/docs/proposals/0012-ask-user-question.md +1007 -207
- package/docs/proposals/0023-permission-enhancements.md +61 -2
- package/docs/proposals/0041-configuration-system.md +33 -2
- package/docs/proposals/0042-prompt-optimization.md +866 -0
- package/docs/proposals/README.md +7 -6
- package/examples/test-ask-user.ts +167 -0
- package/jest.config.js +26 -0
- package/package.json +8 -2
- package/src/agent/agent.ts +130 -16
- package/src/agent/index.ts +1 -0
- package/src/agent/types.ts +13 -1
- package/src/cli/components/App.tsx +362 -37
- package/src/cli/components/CommandSuggestions.tsx +2 -0
- package/src/cli/components/Header.tsx +11 -17
- package/src/cli/components/Logo.tsx +76 -9
- package/src/cli/components/Messages.tsx +104 -41
- package/src/cli/components/PermissionPrompt.tsx +388 -0
- package/src/cli/components/ProviderManager.tsx +5 -5
- package/src/cli/components/QuestionPrompt.tsx +462 -0
- package/src/cli/components/Spinner.tsx +138 -25
- package/src/cli/components/TodoList.tsx +54 -0
- package/src/cli/components/index.ts +7 -0
- package/src/cli/components/theme.ts +11 -1
- package/src/cli/index.tsx +54 -6
- package/src/config/index.ts +78 -4
- package/src/config/levels.test.ts +163 -0
- package/src/config/levels.ts +285 -0
- package/src/config/loader.test.ts +120 -0
- package/src/config/loader.ts +178 -0
- package/src/config/manager.test.ts +215 -0
- package/src/config/manager.ts +328 -40
- package/src/config/merger.test.ts +360 -0
- package/src/config/merger.ts +221 -0
- package/src/config/test-utils.ts +79 -0
- package/src/config/types.ts +152 -9
- package/src/memory/import-resolver.test.ts +117 -0
- package/src/memory/import-resolver.ts +149 -0
- package/src/memory/index.ts +11 -0
- package/src/memory/init-prompt.ts +113 -0
- package/src/memory/memory-manager.test.ts +198 -0
- package/src/memory/memory-manager.ts +716 -0
- package/src/memory/rules-parser.test.ts +182 -0
- package/src/memory/rules-parser.ts +82 -0
- package/src/memory/test-utils.ts +60 -0
- package/src/memory/types.ts +119 -0
- package/src/permissions/audit.ts +284 -0
- package/src/permissions/index.ts +20 -1
- package/src/permissions/manager.test.ts +260 -0
- package/src/permissions/manager.ts +592 -40
- package/src/permissions/persistence.test.ts +220 -0
- package/src/permissions/persistence.ts +301 -0
- package/src/permissions/prompt-matcher.test.ts +213 -0
- package/src/permissions/prompt-matcher.ts +472 -0
- package/src/permissions/types.ts +238 -8
- package/src/prompts/index.test.ts +279 -0
- package/src/prompts/index.ts +306 -0
- package/src/prompts/system/anthropic.txt +29 -0
- package/src/prompts/system/base.txt +166 -0
- package/src/prompts/system/gemini.txt +35 -0
- package/src/prompts/system/generic.txt +128 -0
- package/src/prompts/system/openai.txt +29 -0
- package/src/prompts/tools/ask-user.txt +110 -0
- package/src/prompts/tools/bash.txt +60 -0
- package/src/prompts/tools/edit.txt +29 -0
- package/src/prompts/tools/glob.txt +35 -0
- package/src/prompts/tools/grep.txt +43 -0
- package/src/prompts/tools/read.txt +22 -0
- package/src/prompts/tools/todowrite.txt +71 -0
- package/src/prompts/tools/webfetch.txt +34 -0
- package/src/prompts/tools/websearch.txt +41 -0
- package/src/prompts/tools/write.txt +23 -0
- package/src/tools/builtin/ask-user.ts +185 -0
- package/src/tools/builtin/bash.ts +2 -1
- package/src/tools/builtin/edit.ts +2 -1
- package/src/tools/builtin/glob.ts +2 -1
- package/src/tools/builtin/grep.ts +2 -1
- package/src/tools/builtin/read.ts +2 -1
- package/src/tools/builtin/todowrite.ts +102 -0
- package/src/tools/builtin/webfetch.ts +2 -5
- package/src/tools/builtin/websearch.ts +2 -16
- package/src/tools/builtin/write.ts +2 -1
- package/src/tools/index.ts +19 -0
- package/src/tools/types.ts +30 -0
- package/tsconfig.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.test.d.ts","sourceRoot":"","sources":["../../src/config/manager.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SettingsManager Tests
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import * as os from 'os';
|
|
7
|
+
import { SettingsManager } from './manager.js';
|
|
8
|
+
describe('SettingsManager', () => {
|
|
9
|
+
let tempDir;
|
|
10
|
+
let globalDir;
|
|
11
|
+
let projectDir;
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
// Create temp directories for testing
|
|
14
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gencode-test-'));
|
|
15
|
+
globalDir = path.join(tempDir, 'global');
|
|
16
|
+
projectDir = path.join(tempDir, 'project');
|
|
17
|
+
await fs.mkdir(globalDir, { recursive: true });
|
|
18
|
+
await fs.mkdir(projectDir, { recursive: true });
|
|
19
|
+
});
|
|
20
|
+
afterEach(async () => {
|
|
21
|
+
// Cleanup temp directories
|
|
22
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
23
|
+
});
|
|
24
|
+
describe('load', () => {
|
|
25
|
+
it('should load settings from a single file', async () => {
|
|
26
|
+
const settingsPath = path.join(globalDir, 'settings.json');
|
|
27
|
+
await fs.writeFile(settingsPath, JSON.stringify({
|
|
28
|
+
model: 'gpt-4o',
|
|
29
|
+
provider: 'openai',
|
|
30
|
+
}));
|
|
31
|
+
const manager = new SettingsManager({
|
|
32
|
+
settingsDir: globalDir,
|
|
33
|
+
cwd: projectDir,
|
|
34
|
+
});
|
|
35
|
+
const settings = await manager.load();
|
|
36
|
+
expect(settings.model).toBe('gpt-4o');
|
|
37
|
+
expect(settings.provider).toBe('openai');
|
|
38
|
+
});
|
|
39
|
+
it('should merge settings from multiple levels', async () => {
|
|
40
|
+
// Global settings
|
|
41
|
+
const globalSettings = path.join(globalDir, 'settings.json');
|
|
42
|
+
await fs.writeFile(globalSettings, JSON.stringify({
|
|
43
|
+
model: 'gpt-4o',
|
|
44
|
+
provider: 'openai',
|
|
45
|
+
}));
|
|
46
|
+
// Project settings directory
|
|
47
|
+
const projectSettingsDir = path.join(projectDir, '.claude');
|
|
48
|
+
await fs.mkdir(projectSettingsDir, { recursive: true });
|
|
49
|
+
// Project settings
|
|
50
|
+
const projectSettings = path.join(projectSettingsDir, 'settings.json');
|
|
51
|
+
await fs.writeFile(projectSettings, JSON.stringify({
|
|
52
|
+
model: 'claude-sonnet',
|
|
53
|
+
}));
|
|
54
|
+
const manager = new SettingsManager({
|
|
55
|
+
settingsDir: globalDir,
|
|
56
|
+
cwd: projectDir,
|
|
57
|
+
});
|
|
58
|
+
const settings = await manager.load();
|
|
59
|
+
// Model should be overridden by project
|
|
60
|
+
expect(settings.model).toBe('claude-sonnet');
|
|
61
|
+
// Provider should be inherited from global
|
|
62
|
+
expect(settings.provider).toBe('openai');
|
|
63
|
+
});
|
|
64
|
+
it('should concatenate array fields (permissions)', async () => {
|
|
65
|
+
// Global settings
|
|
66
|
+
const globalSettings = path.join(globalDir, 'settings.json');
|
|
67
|
+
await fs.writeFile(globalSettings, JSON.stringify({
|
|
68
|
+
permissions: {
|
|
69
|
+
allow: ['Bash(git:*)'],
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
72
|
+
// Project settings directory
|
|
73
|
+
const projectSettingsDir = path.join(projectDir, '.claude');
|
|
74
|
+
await fs.mkdir(projectSettingsDir, { recursive: true });
|
|
75
|
+
// Project local settings
|
|
76
|
+
const projectLocal = path.join(projectSettingsDir, 'settings.local.json');
|
|
77
|
+
await fs.writeFile(projectLocal, JSON.stringify({
|
|
78
|
+
permissions: {
|
|
79
|
+
allow: ['WebSearch'],
|
|
80
|
+
},
|
|
81
|
+
}));
|
|
82
|
+
const manager = new SettingsManager({
|
|
83
|
+
settingsDir: globalDir,
|
|
84
|
+
cwd: projectDir,
|
|
85
|
+
});
|
|
86
|
+
const settings = await manager.load();
|
|
87
|
+
// Arrays should be concatenated
|
|
88
|
+
expect(settings.permissions?.allow).toContain('Bash(git:*)');
|
|
89
|
+
expect(settings.permissions?.allow).toContain('WebSearch');
|
|
90
|
+
expect(settings.permissions?.allow?.length).toBe(2);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('saveToLevel', () => {
|
|
94
|
+
it('should save to global level', async () => {
|
|
95
|
+
const manager = new SettingsManager({
|
|
96
|
+
settingsDir: globalDir,
|
|
97
|
+
cwd: projectDir,
|
|
98
|
+
});
|
|
99
|
+
await manager.saveToLevel({ model: 'test-model' }, 'global');
|
|
100
|
+
const content = await fs.readFile(path.join(globalDir, 'settings.json'), 'utf-8');
|
|
101
|
+
const saved = JSON.parse(content);
|
|
102
|
+
expect(saved.model).toBe('test-model');
|
|
103
|
+
});
|
|
104
|
+
it('should save to project local level', async () => {
|
|
105
|
+
// Create project settings directory
|
|
106
|
+
const projectSettingsDir = path.join(projectDir, '.claude');
|
|
107
|
+
await fs.mkdir(projectSettingsDir, { recursive: true });
|
|
108
|
+
const manager = new SettingsManager({
|
|
109
|
+
settingsDir: globalDir,
|
|
110
|
+
cwd: projectDir,
|
|
111
|
+
});
|
|
112
|
+
await manager.saveToLevel({ model: 'local-model' }, 'local');
|
|
113
|
+
const content = await fs.readFile(path.join(projectSettingsDir, 'settings.local.json'), 'utf-8');
|
|
114
|
+
const saved = JSON.parse(content);
|
|
115
|
+
expect(saved.model).toBe('local-model');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('addPermissionRule', () => {
|
|
119
|
+
it('should add allow rule to local level', async () => {
|
|
120
|
+
// Create project settings directory
|
|
121
|
+
const projectSettingsDir = path.join(projectDir, '.claude');
|
|
122
|
+
await fs.mkdir(projectSettingsDir, { recursive: true });
|
|
123
|
+
const manager = new SettingsManager({
|
|
124
|
+
settingsDir: globalDir,
|
|
125
|
+
cwd: projectDir,
|
|
126
|
+
});
|
|
127
|
+
await manager.addPermissionRule('Bash(npm test:*)', 'allow', 'local');
|
|
128
|
+
const content = await fs.readFile(path.join(projectSettingsDir, 'settings.local.json'), 'utf-8');
|
|
129
|
+
const saved = JSON.parse(content);
|
|
130
|
+
expect(saved.permissions?.allow).toContain('Bash(npm test:*)');
|
|
131
|
+
});
|
|
132
|
+
it('should add deny rule', async () => {
|
|
133
|
+
const manager = new SettingsManager({
|
|
134
|
+
settingsDir: globalDir,
|
|
135
|
+
cwd: projectDir,
|
|
136
|
+
});
|
|
137
|
+
await manager.addPermissionRule('Bash(rm -rf:*)', 'deny', 'global');
|
|
138
|
+
const content = await fs.readFile(path.join(globalDir, 'settings.json'), 'utf-8');
|
|
139
|
+
const saved = JSON.parse(content);
|
|
140
|
+
expect(saved.permissions?.deny).toContain('Bash(rm -rf:*)');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('directory fallback', () => {
|
|
144
|
+
it('should use .claude as primary directory', async () => {
|
|
145
|
+
// Create .claude directory (primary)
|
|
146
|
+
const claudeDir = path.join(projectDir, '.claude');
|
|
147
|
+
await fs.mkdir(claudeDir, { recursive: true });
|
|
148
|
+
// Create settings in .claude
|
|
149
|
+
await fs.writeFile(path.join(claudeDir, 'settings.json'), JSON.stringify({ model: 'claude-model' }));
|
|
150
|
+
// Also create .gencode directory (fallback)
|
|
151
|
+
const gencodeDir = path.join(projectDir, '.gencode');
|
|
152
|
+
await fs.mkdir(gencodeDir, { recursive: true });
|
|
153
|
+
await fs.writeFile(path.join(gencodeDir, 'settings.json'), JSON.stringify({ model: 'gencode-model' }));
|
|
154
|
+
const manager = new SettingsManager({
|
|
155
|
+
settingsDir: globalDir,
|
|
156
|
+
cwd: projectDir,
|
|
157
|
+
});
|
|
158
|
+
const settings = await manager.load();
|
|
159
|
+
// Should use .claude (primary)
|
|
160
|
+
expect(settings.model).toBe('claude-model');
|
|
161
|
+
});
|
|
162
|
+
it('should use .gencode when explicitly created first', async () => {
|
|
163
|
+
// Create .gencode directory first, then .claude (to test priority)
|
|
164
|
+
const gencodeDir = path.join(projectDir, '.gencode');
|
|
165
|
+
await fs.mkdir(gencodeDir, { recursive: true });
|
|
166
|
+
await fs.writeFile(path.join(gencodeDir, 'settings.json'), JSON.stringify({ model: 'gencode-model' }));
|
|
167
|
+
// Now create .claude (primary) with different model
|
|
168
|
+
const claudeDir = path.join(projectDir, '.claude');
|
|
169
|
+
await fs.mkdir(claudeDir, { recursive: true });
|
|
170
|
+
await fs.writeFile(path.join(claudeDir, 'settings.json'), JSON.stringify({ model: 'claude-model' }));
|
|
171
|
+
const manager = new SettingsManager({
|
|
172
|
+
settingsDir: globalDir,
|
|
173
|
+
cwd: projectDir,
|
|
174
|
+
});
|
|
175
|
+
// .claude is primary, so it should be used
|
|
176
|
+
expect(manager.getProjectDir()).toContain('.claude');
|
|
177
|
+
const settings = await manager.load();
|
|
178
|
+
// Should use .claude (primary) over .gencode
|
|
179
|
+
expect(settings.model).toBe('claude-model');
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('getCwd', () => {
|
|
183
|
+
it('should return the working directory', () => {
|
|
184
|
+
const manager = new SettingsManager({
|
|
185
|
+
settingsDir: globalDir,
|
|
186
|
+
cwd: projectDir,
|
|
187
|
+
});
|
|
188
|
+
expect(manager.getCwd()).toBe(projectDir);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
//# sourceMappingURL=manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.test.js","sourceRoot":"","sources":["../../src/config/manager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Merger - Merge settings from multiple sources
|
|
3
|
+
*
|
|
4
|
+
* Implements the merge strategy:
|
|
5
|
+
* - Scalar values: Higher priority replaces lower
|
|
6
|
+
* - Arrays (permissions.allow, permissions.deny): Concatenate with deduplication
|
|
7
|
+
* - Objects: Deep merge recursively
|
|
8
|
+
* - Managed deny rules: Cannot be overridden by any level
|
|
9
|
+
*/
|
|
10
|
+
import type { Settings, ConfigSource, MergedConfig } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Deep merge two objects
|
|
13
|
+
*
|
|
14
|
+
* - Arrays are concatenated and deduplicated
|
|
15
|
+
* - Objects are recursively merged
|
|
16
|
+
* - Scalars from override replace base
|
|
17
|
+
*/
|
|
18
|
+
export declare function deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T;
|
|
19
|
+
/**
|
|
20
|
+
* Merge all configuration sources into a single settings object
|
|
21
|
+
*
|
|
22
|
+
* Sources should be in priority order (lowest first).
|
|
23
|
+
* Each source is merged on top of the previous result.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mergeSettings(sources: ConfigSource[]): Settings;
|
|
26
|
+
/**
|
|
27
|
+
* Extract managed deny rules from sources
|
|
28
|
+
*
|
|
29
|
+
* These rules are extracted from managed-level sources and cannot be
|
|
30
|
+
* overridden by any lower-level configuration.
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractManagedDeny(sources: ConfigSource[]): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Apply managed restrictions to the merged settings
|
|
35
|
+
*
|
|
36
|
+
* - Ensures managed deny rules are always in the deny list
|
|
37
|
+
* - Removes managed deny patterns from allow list
|
|
38
|
+
*/
|
|
39
|
+
export declare function applyManagedRestrictions(settings: Settings, managedDeny: string[]): Settings;
|
|
40
|
+
/**
|
|
41
|
+
* Merge all configuration sources and apply restrictions
|
|
42
|
+
*
|
|
43
|
+
* This is the main entry point for configuration merging.
|
|
44
|
+
*/
|
|
45
|
+
export declare function mergeAllSources(sources: ConfigSource[]): MergedConfig;
|
|
46
|
+
/**
|
|
47
|
+
* Merge settings with CLI arguments
|
|
48
|
+
*
|
|
49
|
+
* CLI arguments have the highest priority (except managed restrictions).
|
|
50
|
+
*/
|
|
51
|
+
export declare function mergeWithCliArgs(merged: MergedConfig, cliArgs: Partial<Settings>): MergedConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Create a debug summary of the merge process
|
|
54
|
+
*/
|
|
55
|
+
export declare function createMergeSummary(merged: MergedConfig): string;
|
|
56
|
+
//# sourceMappingURL=merger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merger.d.ts","sourceRoot":"","sources":["../../src/config/merger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAC;AASxF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,GACnB,CAAC,CA8BH;AAoBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,QAAQ,CAQ/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAapE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,EAAE,GACpB,QAAQ,CAqBV;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,CAerE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GACzB,YAAY,CAoBd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAiB/D"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Merger - Merge settings from multiple sources
|
|
3
|
+
*
|
|
4
|
+
* Implements the merge strategy:
|
|
5
|
+
* - Scalar values: Higher priority replaces lower
|
|
6
|
+
* - Arrays (permissions.allow, permissions.deny): Concatenate with deduplication
|
|
7
|
+
* - Objects: Deep merge recursively
|
|
8
|
+
* - Managed deny rules: Cannot be overridden by any level
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Check if a value is a plain object
|
|
12
|
+
*/
|
|
13
|
+
function isPlainObject(value) {
|
|
14
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Deep merge two objects
|
|
18
|
+
*
|
|
19
|
+
* - Arrays are concatenated and deduplicated
|
|
20
|
+
* - Objects are recursively merged
|
|
21
|
+
* - Scalars from override replace base
|
|
22
|
+
*/
|
|
23
|
+
export function deepMerge(base, override) {
|
|
24
|
+
const result = { ...base };
|
|
25
|
+
for (const key in override) {
|
|
26
|
+
const baseValue = result[key];
|
|
27
|
+
const overrideValue = override[key];
|
|
28
|
+
if (overrideValue === undefined) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
|
|
32
|
+
// Recursively merge objects
|
|
33
|
+
result[key] = deepMerge(baseValue, overrideValue);
|
|
34
|
+
}
|
|
35
|
+
else if (Array.isArray(baseValue) && Array.isArray(overrideValue)) {
|
|
36
|
+
// Concatenate arrays and deduplicate
|
|
37
|
+
result[key] = deduplicateArray([
|
|
38
|
+
...baseValue,
|
|
39
|
+
...overrideValue,
|
|
40
|
+
]);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Override scalar values
|
|
44
|
+
result[key] = overrideValue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Deduplicate an array while preserving order
|
|
51
|
+
*/
|
|
52
|
+
function deduplicateArray(arr) {
|
|
53
|
+
const seen = new Set();
|
|
54
|
+
const result = [];
|
|
55
|
+
for (const item of arr) {
|
|
56
|
+
const key = typeof item === 'object' ? JSON.stringify(item) : String(item);
|
|
57
|
+
if (!seen.has(key)) {
|
|
58
|
+
seen.add(key);
|
|
59
|
+
result.push(item);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Merge all configuration sources into a single settings object
|
|
66
|
+
*
|
|
67
|
+
* Sources should be in priority order (lowest first).
|
|
68
|
+
* Each source is merged on top of the previous result.
|
|
69
|
+
*/
|
|
70
|
+
export function mergeSettings(sources) {
|
|
71
|
+
let merged = {};
|
|
72
|
+
for (const source of sources) {
|
|
73
|
+
merged = deepMerge(merged, source.settings);
|
|
74
|
+
}
|
|
75
|
+
return merged;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Extract managed deny rules from sources
|
|
79
|
+
*
|
|
80
|
+
* These rules are extracted from managed-level sources and cannot be
|
|
81
|
+
* overridden by any lower-level configuration.
|
|
82
|
+
*/
|
|
83
|
+
export function extractManagedDeny(sources) {
|
|
84
|
+
const managedDeny = [];
|
|
85
|
+
for (const source of sources) {
|
|
86
|
+
if (source.level === 'managed') {
|
|
87
|
+
const deny = source.settings.permissions?.deny;
|
|
88
|
+
if (deny) {
|
|
89
|
+
managedDeny.push(...deny);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return deduplicateArray(managedDeny);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Apply managed restrictions to the merged settings
|
|
97
|
+
*
|
|
98
|
+
* - Ensures managed deny rules are always in the deny list
|
|
99
|
+
* - Removes managed deny patterns from allow list
|
|
100
|
+
*/
|
|
101
|
+
export function applyManagedRestrictions(settings, managedDeny) {
|
|
102
|
+
if (managedDeny.length === 0) {
|
|
103
|
+
return settings;
|
|
104
|
+
}
|
|
105
|
+
const result = { ...settings };
|
|
106
|
+
const permissions = { ...(result.permissions || {}) };
|
|
107
|
+
// Ensure deny list includes all managed deny rules
|
|
108
|
+
const currentDeny = permissions.deny || [];
|
|
109
|
+
permissions.deny = deduplicateArray([...currentDeny, ...managedDeny]);
|
|
110
|
+
// Remove managed deny patterns from allow list
|
|
111
|
+
if (permissions.allow) {
|
|
112
|
+
permissions.allow = permissions.allow.filter((pattern) => !managedDeny.includes(pattern));
|
|
113
|
+
}
|
|
114
|
+
result.permissions = permissions;
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Merge all configuration sources and apply restrictions
|
|
119
|
+
*
|
|
120
|
+
* This is the main entry point for configuration merging.
|
|
121
|
+
*/
|
|
122
|
+
export function mergeAllSources(sources) {
|
|
123
|
+
// Extract managed deny rules first
|
|
124
|
+
const managedDeny = extractManagedDeny(sources);
|
|
125
|
+
// Merge all settings
|
|
126
|
+
let settings = mergeSettings(sources);
|
|
127
|
+
// Apply managed restrictions
|
|
128
|
+
settings = applyManagedRestrictions(settings, managedDeny);
|
|
129
|
+
return {
|
|
130
|
+
settings,
|
|
131
|
+
sources,
|
|
132
|
+
managedDeny,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Merge settings with CLI arguments
|
|
137
|
+
*
|
|
138
|
+
* CLI arguments have the highest priority (except managed restrictions).
|
|
139
|
+
*/
|
|
140
|
+
export function mergeWithCliArgs(merged, cliArgs) {
|
|
141
|
+
// Merge CLI args as a virtual source
|
|
142
|
+
const settings = deepMerge(merged.settings, cliArgs);
|
|
143
|
+
// Re-apply managed restrictions to ensure they're not overridden
|
|
144
|
+
const finalSettings = applyManagedRestrictions(settings, merged.managedDeny);
|
|
145
|
+
return {
|
|
146
|
+
...merged,
|
|
147
|
+
settings: finalSettings,
|
|
148
|
+
sources: [
|
|
149
|
+
...merged.sources,
|
|
150
|
+
{
|
|
151
|
+
level: 'cli',
|
|
152
|
+
path: '<cli>',
|
|
153
|
+
namespace: 'gencode',
|
|
154
|
+
settings: cliArgs,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create a debug summary of the merge process
|
|
161
|
+
*/
|
|
162
|
+
export function createMergeSummary(merged) {
|
|
163
|
+
const lines = ['Configuration Sources (in priority order):'];
|
|
164
|
+
for (const source of merged.sources) {
|
|
165
|
+
const marker = source.level === 'managed' ? ' [enforced]' : '';
|
|
166
|
+
lines.push(` ${source.level}:${source.namespace} - ${source.path}${marker}`);
|
|
167
|
+
}
|
|
168
|
+
if (merged.managedDeny.length > 0) {
|
|
169
|
+
lines.push('');
|
|
170
|
+
lines.push('Managed Deny Rules (cannot be overridden):');
|
|
171
|
+
for (const rule of merged.managedDeny) {
|
|
172
|
+
lines.push(` - ${rule}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return lines.join('\n');
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=merger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merger.js","sourceRoot":"","sources":["../../src/config/merger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared test utilities for config tests
|
|
3
|
+
*/
|
|
4
|
+
export interface TestProject {
|
|
5
|
+
tempDir: string;
|
|
6
|
+
projectDir: string;
|
|
7
|
+
cleanup: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a test project with temp directory and git marker
|
|
11
|
+
*/
|
|
12
|
+
export declare function createTestProject(prefix?: string): Promise<TestProject>;
|
|
13
|
+
/**
|
|
14
|
+
* Write JSON settings to a config directory
|
|
15
|
+
*/
|
|
16
|
+
export declare function writeSettings(projectDir: string, namespace: 'claude' | 'gencode', settings: Record<string, unknown>, local?: boolean): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Write memory file to a directory
|
|
19
|
+
*/
|
|
20
|
+
export declare function writeMemory(projectDir: string, namespace: 'claude' | 'gencode', content: string, options?: {
|
|
21
|
+
local?: boolean;
|
|
22
|
+
inDir?: boolean;
|
|
23
|
+
}): Promise<string>;
|
|
24
|
+
//# sourceMappingURL=test-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/config/test-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,SAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAetF;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,QAAQ,GAAG,SAAS,EAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,UAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,CASjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,QAAQ,GAAG,SAAS,EAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACjD,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared test utilities for config tests
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import * as os from 'os';
|
|
7
|
+
/**
|
|
8
|
+
* Create a test project with temp directory and git marker
|
|
9
|
+
*/
|
|
10
|
+
export async function createTestProject(prefix = 'gencode-test-') {
|
|
11
|
+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
12
|
+
const projectDir = path.join(tempDir, 'project');
|
|
13
|
+
await fs.mkdir(projectDir, { recursive: true });
|
|
14
|
+
await fs.mkdir(path.join(projectDir, '.git'));
|
|
15
|
+
return {
|
|
16
|
+
tempDir,
|
|
17
|
+
projectDir,
|
|
18
|
+
cleanup: async () => {
|
|
19
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
20
|
+
delete process.env.GENCODE_CONFIG_DIRS;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Write JSON settings to a config directory
|
|
26
|
+
*/
|
|
27
|
+
export async function writeSettings(projectDir, namespace, settings, local = false) {
|
|
28
|
+
const dir = path.join(projectDir, namespace === 'claude' ? '.claude' : '.gencode');
|
|
29
|
+
await fs.mkdir(dir, { recursive: true });
|
|
30
|
+
const filename = local ? 'settings.local.json' : 'settings.json';
|
|
31
|
+
const filePath = path.join(dir, filename);
|
|
32
|
+
await fs.writeFile(filePath, JSON.stringify(settings));
|
|
33
|
+
return filePath;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Write memory file to a directory
|
|
37
|
+
*/
|
|
38
|
+
export async function writeMemory(projectDir, namespace, content, options = {}) {
|
|
39
|
+
const { local = false, inDir = true } = options;
|
|
40
|
+
const filename = namespace === 'claude'
|
|
41
|
+
? (local ? 'CLAUDE.local.md' : 'CLAUDE.md')
|
|
42
|
+
: (local ? 'AGENT.local.md' : 'AGENT.md');
|
|
43
|
+
let filePath;
|
|
44
|
+
if (inDir) {
|
|
45
|
+
const dir = path.join(projectDir, namespace === 'claude' ? '.claude' : '.gencode');
|
|
46
|
+
await fs.mkdir(dir, { recursive: true });
|
|
47
|
+
filePath = path.join(dir, filename);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
filePath = path.join(projectDir, filename);
|
|
51
|
+
}
|
|
52
|
+
await fs.writeFile(filePath, content);
|
|
53
|
+
return filePath;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=test-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/config/test-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -1,25 +1,94 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuration Types - Multi-level configuration system (Claude Code compatible)
|
|
3
|
+
*
|
|
4
|
+
* Configuration hierarchy (priority from low to high):
|
|
5
|
+
* 1. User Level: ~/.gencode/ + ~/.claude/ (merged, gencode wins)
|
|
6
|
+
* 2. Extra Dirs: GENCODE_CONFIG_DIRS environment variable
|
|
7
|
+
* 3. Project Level: .gencode/ + .claude/ (merged, gencode wins)
|
|
8
|
+
* 4. Local Level: .gencode/*.local.* + .claude/*.local.* (merged, gencode wins)
|
|
9
|
+
* 5. CLI Arguments: Command line overrides
|
|
10
|
+
* 6. Managed Level: System-wide enforced settings (cannot be overridden)
|
|
3
11
|
*/
|
|
4
12
|
export type ProviderName = 'openai' | 'anthropic' | 'gemini' | 'vertex-ai';
|
|
5
13
|
/**
|
|
6
|
-
*
|
|
7
|
-
|
|
14
|
+
* Permission rules for tools
|
|
15
|
+
*/
|
|
16
|
+
export interface PermissionRules {
|
|
17
|
+
allow?: string[];
|
|
18
|
+
ask?: string[];
|
|
19
|
+
deny?: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Settings file structure
|
|
23
|
+
* Compatible with Claude Code's settings.json
|
|
8
24
|
*/
|
|
9
25
|
export interface Settings {
|
|
10
26
|
model?: string;
|
|
11
27
|
provider?: ProviderName;
|
|
12
|
-
permissions?:
|
|
13
|
-
|
|
14
|
-
|
|
28
|
+
permissions?: PermissionRules;
|
|
29
|
+
theme?: string;
|
|
30
|
+
language?: string;
|
|
31
|
+
alwaysThinkingEnabled?: boolean;
|
|
32
|
+
env?: Record<string, string>;
|
|
33
|
+
attribution?: {
|
|
34
|
+
commit?: string;
|
|
35
|
+
pr?: string;
|
|
15
36
|
};
|
|
37
|
+
enabledPlugins?: Record<string, boolean>;
|
|
38
|
+
extraKnownMarketplaces?: Record<string, unknown>;
|
|
39
|
+
strictKnownMarketplaces?: unknown[];
|
|
40
|
+
[key: string]: unknown;
|
|
16
41
|
}
|
|
17
|
-
|
|
18
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Configuration level identifiers
|
|
44
|
+
*/
|
|
45
|
+
export type ConfigLevelType = 'managed' | 'user' | 'extra' | 'project' | 'local' | 'cli';
|
|
46
|
+
/**
|
|
47
|
+
* Represents a configuration level with its metadata
|
|
48
|
+
*/
|
|
49
|
+
export interface ConfigLevel {
|
|
50
|
+
type: ConfigLevelType;
|
|
51
|
+
priority: number;
|
|
52
|
+
paths: string[];
|
|
53
|
+
description: string;
|
|
19
54
|
}
|
|
20
|
-
|
|
55
|
+
/**
|
|
56
|
+
* A loaded configuration source
|
|
57
|
+
*/
|
|
58
|
+
export interface ConfigSource {
|
|
59
|
+
level: ConfigLevelType;
|
|
60
|
+
path: string;
|
|
61
|
+
namespace: 'gencode' | 'claude' | 'extra';
|
|
62
|
+
settings: Settings;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Result of merging all configuration sources
|
|
66
|
+
*/
|
|
67
|
+
export interface MergedConfig {
|
|
68
|
+
settings: Settings;
|
|
69
|
+
sources: ConfigSource[];
|
|
70
|
+
managedDeny: string[];
|
|
71
|
+
}
|
|
72
|
+
export declare const GENCODE_CONFIG_DIRS_ENV = "GENCODE_CONFIG_DIRS";
|
|
21
73
|
export declare const SETTINGS_FILE_NAME = "settings.json";
|
|
74
|
+
export declare const SETTINGS_LOCAL_FILE_NAME = "settings.local.json";
|
|
75
|
+
export declare const MANAGED_SETTINGS_FILE_NAME = "managed-settings.json";
|
|
22
76
|
export declare const PROVIDERS_FILE_NAME = "providers.json";
|
|
77
|
+
export declare const GENCODE_DIR = ".gencode";
|
|
78
|
+
export declare const CLAUDE_DIR = ".claude";
|
|
79
|
+
export declare const USER_GENCODE_DIR: string;
|
|
80
|
+
export declare const USER_CLAUDE_DIR: string;
|
|
81
|
+
export declare function getManagedPaths(): {
|
|
82
|
+
gencode: string;
|
|
83
|
+
claude: string;
|
|
84
|
+
};
|
|
85
|
+
export interface SettingsManagerOptions {
|
|
86
|
+
settingsDir?: string;
|
|
87
|
+
}
|
|
88
|
+
export declare const DEFAULT_SETTINGS_DIR = "~/.claude";
|
|
89
|
+
export declare const PROJECT_SETTINGS_DIR = ".claude";
|
|
90
|
+
export declare const FALLBACK_SETTINGS_DIR = "~/.gencode";
|
|
91
|
+
export declare const FALLBACK_PROJECT_DIR = ".gencode";
|
|
23
92
|
/**
|
|
24
93
|
* Provider connection info
|
|
25
94
|
*/
|