gencode-ai 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/agent/agent.d.ts +9 -2
  2. package/dist/agent/agent.d.ts.map +1 -1
  3. package/dist/agent/agent.js +37 -8
  4. package/dist/agent/agent.js.map +1 -1
  5. package/dist/agent/types.d.ts +5 -1
  6. package/dist/agent/types.d.ts.map +1 -1
  7. package/dist/cli/components/App.d.ts.map +1 -1
  8. package/dist/cli/components/App.js +15 -9
  9. package/dist/cli/components/App.js.map +1 -1
  10. package/dist/cli/components/Messages.js +1 -1
  11. package/dist/cli/components/Messages.js.map +1 -1
  12. package/dist/cli/components/ModelSelector.d.ts +4 -3
  13. package/dist/cli/components/ModelSelector.d.ts.map +1 -1
  14. package/dist/cli/components/ModelSelector.js +54 -37
  15. package/dist/cli/components/ModelSelector.js.map +1 -1
  16. package/dist/cli/components/ProviderManager.d.ts +2 -2
  17. package/dist/cli/components/ProviderManager.d.ts.map +1 -1
  18. package/dist/cli/components/ProviderManager.js +137 -156
  19. package/dist/cli/components/ProviderManager.js.map +1 -1
  20. package/dist/cli/index.js +30 -13
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/config/index.d.ts +2 -2
  23. package/dist/config/index.d.ts.map +1 -1
  24. package/dist/config/index.js +1 -1
  25. package/dist/config/index.js.map +1 -1
  26. package/dist/config/levels.d.ts +5 -5
  27. package/dist/config/levels.d.ts.map +1 -1
  28. package/dist/config/levels.js +20 -20
  29. package/dist/config/levels.js.map +1 -1
  30. package/dist/config/merger.js +1 -1
  31. package/dist/config/merger.js.map +1 -1
  32. package/dist/config/providers-config.d.ts +8 -5
  33. package/dist/config/providers-config.d.ts.map +1 -1
  34. package/dist/config/providers-config.js +19 -22
  35. package/dist/config/providers-config.js.map +1 -1
  36. package/dist/config/test-utils.d.ts +2 -2
  37. package/dist/config/test-utils.d.ts.map +1 -1
  38. package/dist/config/test-utils.js +4 -4
  39. package/dist/config/test-utils.js.map +1 -1
  40. package/dist/config/types.d.ts +23 -17
  41. package/dist/config/types.d.ts.map +1 -1
  42. package/dist/config/types.js +14 -14
  43. package/dist/config/types.js.map +1 -1
  44. package/dist/memory/memory-manager.d.ts +25 -12
  45. package/dist/memory/memory-manager.d.ts.map +1 -1
  46. package/dist/memory/memory-manager.js +241 -112
  47. package/dist/memory/memory-manager.js.map +1 -1
  48. package/dist/memory/test-utils.d.ts +1 -1
  49. package/dist/memory/test-utils.d.ts.map +1 -1
  50. package/dist/memory/test-utils.js +3 -3
  51. package/dist/memory/test-utils.js.map +1 -1
  52. package/dist/memory/types.d.ts +20 -10
  53. package/dist/memory/types.d.ts.map +1 -1
  54. package/dist/memory/types.js +13 -13
  55. package/dist/memory/types.js.map +1 -1
  56. package/dist/migration/migrate.d.ts +24 -0
  57. package/dist/migration/migrate.d.ts.map +1 -0
  58. package/dist/migration/migrate.js +164 -0
  59. package/dist/migration/migrate.js.map +1 -0
  60. package/dist/permissions/persistence.d.ts +2 -2
  61. package/dist/permissions/persistence.js +4 -4
  62. package/dist/permissions/persistence.js.map +1 -1
  63. package/dist/planning/plan-file.d.ts +1 -1
  64. package/dist/planning/plan-file.js +2 -2
  65. package/dist/planning/plan-file.js.map +1 -1
  66. package/dist/prompts/index.d.ts +5 -4
  67. package/dist/prompts/index.d.ts.map +1 -1
  68. package/dist/prompts/index.js +11 -8
  69. package/dist/prompts/index.js.map +1 -1
  70. package/dist/providers/anthropic.d.ts +2 -1
  71. package/dist/providers/anthropic.d.ts.map +1 -1
  72. package/dist/providers/anthropic.js +7 -0
  73. package/dist/providers/anthropic.js.map +1 -1
  74. package/dist/providers/gemini.d.ts +2 -1
  75. package/dist/providers/gemini.d.ts.map +1 -1
  76. package/dist/providers/gemini.js +7 -0
  77. package/dist/providers/gemini.js.map +1 -1
  78. package/dist/providers/index.d.ts +20 -10
  79. package/dist/providers/index.d.ts.map +1 -1
  80. package/dist/providers/index.js +48 -24
  81. package/dist/providers/index.js.map +1 -1
  82. package/dist/providers/openai.d.ts +2 -1
  83. package/dist/providers/openai.d.ts.map +1 -1
  84. package/dist/providers/openai.js +7 -0
  85. package/dist/providers/openai.js.map +1 -1
  86. package/dist/providers/registry.d.ts +48 -34
  87. package/dist/providers/registry.d.ts.map +1 -1
  88. package/dist/providers/registry.js +72 -88
  89. package/dist/providers/registry.js.map +1 -1
  90. package/dist/providers/store.d.ts +43 -17
  91. package/dist/providers/store.d.ts.map +1 -1
  92. package/dist/providers/store.js +112 -19
  93. package/dist/providers/store.js.map +1 -1
  94. package/dist/providers/types.d.ts +23 -0
  95. package/dist/providers/types.d.ts.map +1 -1
  96. package/dist/providers/vertex-ai.d.ts +15 -7
  97. package/dist/providers/vertex-ai.d.ts.map +1 -1
  98. package/dist/providers/vertex-ai.js +46 -13
  99. package/dist/providers/vertex-ai.js.map +1 -1
  100. package/dist/session/types.js +1 -1
  101. package/dist/session/types.js.map +1 -1
  102. package/docs/config-system-comparison.md +50 -50
  103. package/docs/cost-tracking-comparison.md +2 -2
  104. package/docs/memory-system.md +124 -31
  105. package/docs/permissions.md +2 -2
  106. package/docs/proposals/0006-memory-system.md +4 -4
  107. package/docs/proposals/0008-checkpointing.md +109 -2
  108. package/docs/proposals/0011-custom-commands.md +2 -1
  109. package/docs/proposals/0021-skills-system.md +2 -1
  110. package/docs/proposals/0023-permission-enhancements.md +2 -2
  111. package/docs/proposals/0033-enterprise-deployment.md +1 -1
  112. package/docs/proposals/0041-configuration-system.md +17 -19
  113. package/docs/proposals/0042-prompt-optimization.md +17 -9
  114. package/docs/proposals/README.md +5 -5
  115. package/docs/providers.md +94 -9
  116. package/package.json +3 -2
  117. package/scripts/migrate.ts +449 -0
  118. package/src/agent/agent.ts +51 -9
  119. package/src/agent/types.ts +5 -1
  120. package/src/cli/components/App.tsx +17 -8
  121. package/src/cli/components/Messages.tsx +1 -1
  122. package/src/cli/components/ModelSelector.tsx +62 -43
  123. package/src/cli/components/ProviderManager.tsx +278 -323
  124. package/src/cli/index.tsx +36 -17
  125. package/src/config/index.ts +5 -3
  126. package/src/config/levels.test.ts +22 -22
  127. package/src/config/levels.ts +22 -22
  128. package/src/config/loader.test.ts +14 -14
  129. package/src/config/manager.test.ts +19 -19
  130. package/src/config/merger.test.ts +23 -23
  131. package/src/config/merger.ts +1 -1
  132. package/src/config/providers-config.ts +23 -21
  133. package/src/config/test-utils.ts +6 -6
  134. package/src/config/types.ts +30 -20
  135. package/src/memory/memory-manager.test.ts +242 -24
  136. package/src/memory/memory-manager.ts +270 -141
  137. package/src/memory/test-utils.ts +4 -4
  138. package/src/memory/types.ts +28 -17
  139. package/src/permissions/persistence.ts +4 -4
  140. package/src/planning/plan-file.ts +2 -2
  141. package/src/prompts/index.ts +13 -9
  142. package/src/providers/anthropic.ts +9 -0
  143. package/src/providers/gemini.ts +9 -0
  144. package/src/providers/index.ts +76 -33
  145. package/src/providers/openai.ts +9 -0
  146. package/src/providers/registry.ts +116 -111
  147. package/src/providers/store.ts +130 -28
  148. package/src/providers/types.ts +33 -1
  149. package/src/providers/vertex-ai.ts +49 -13
  150. package/src/session/types.ts +1 -1
package/src/cli/index.tsx CHANGED
@@ -9,7 +9,9 @@ import { render } from 'ink';
9
9
  import React from 'react';
10
10
  import { App } from './components/App.js';
11
11
  import type { AgentConfig } from '../agent/types.js';
12
- import { SettingsManager, ProvidersConfigManager, type Settings, type ProviderName } from '../config/index.js';
12
+ import { SettingsManager, ProvidersConfigManager, type Settings, type Provider } from '../config/index.js';
13
+ import type { AuthMethod } from '../providers/types.js';
14
+ import { inferProvider, inferAuthMethod } from '../providers/index.js';
13
15
 
14
16
  // ============================================================================
15
17
  // Proxy Setup
@@ -32,32 +34,43 @@ async function setupProxy(): Promise<void> {
32
34
  // Configuration
33
35
  // ============================================================================
34
36
  function detectConfig(settings: Settings, providersConfig: ProvidersConfigManager): AgentConfig {
35
- let provider: ProviderName = 'gemini';
37
+ let provider: Provider = 'gemini';
38
+ let authMethod: AuthMethod | undefined;
36
39
  let model = 'gemini-2.0-flash';
37
40
 
38
- // Check for explicit Vertex AI enablement first (highest priority for auto-detect)
39
- if (process.env.GENCODE_USE_VERTEX === '1' || process.env.CLAUDE_CODE_USE_VERTEX === '1') {
40
- provider = 'vertex-ai';
41
- model = process.env.VERTEX_AI_MODEL ?? 'claude-sonnet-4-5@20250929';
42
- }
43
- // Auto-detect from API keys
44
- else if (process.env.ANTHROPIC_API_KEY) {
41
+ // Auto-detect from environment variables
42
+ // Check Vertex AI first (requires explicit opt-in)
43
+ const useVertex = process.env.CLAUDE_CODE_USE_VERTEX === '1' || process.env.CLAUDE_CODE_USE_VERTEX === 'true';
44
+ const hasVertexProject = !!(
45
+ process.env.ANTHROPIC_VERTEX_PROJECT_ID ||
46
+ process.env.GCLOUD_PROJECT ||
47
+ process.env.GOOGLE_CLOUD_PROJECT
48
+ );
49
+
50
+ if (useVertex && hasVertexProject) {
51
+ provider = 'anthropic';
52
+ authMethod = 'vertex';
53
+ model = 'claude-sonnet-4-5@20250929';
54
+ } else if (process.env.ANTHROPIC_API_KEY) {
45
55
  provider = 'anthropic';
56
+ authMethod = 'api_key';
46
57
  model = 'claude-sonnet-4-20250514';
47
58
  } else if (process.env.OPENAI_API_KEY) {
48
59
  provider = 'openai';
60
+ authMethod = 'api_key';
49
61
  model = 'gpt-4o';
50
62
  } else if (process.env.GOOGLE_API_KEY) {
51
63
  provider = 'gemini';
64
+ authMethod = 'api_key';
52
65
  model = 'gemini-2.0-flash';
53
66
  }
54
67
 
55
68
  // Override from env vars
56
- if (process.env.GENCODE_PROVIDER) {
57
- provider = process.env.GENCODE_PROVIDER as ProviderName;
69
+ if (process.env.GEN_PROVIDER) {
70
+ provider = process.env.GEN_PROVIDER as Provider;
58
71
  }
59
- if (process.env.GENCODE_MODEL) {
60
- model = process.env.GENCODE_MODEL;
72
+ if (process.env.GEN_MODEL) {
73
+ model = process.env.GEN_MODEL;
61
74
  }
62
75
 
63
76
  // Override from saved settings (highest priority)
@@ -66,17 +79,23 @@ function detectConfig(settings: Settings, providersConfig: ProvidersConfigManage
66
79
  }
67
80
  if (settings.model) {
68
81
  model = settings.model;
69
- // Auto-infer provider from model using providers.json (if not explicitly set)
82
+ // Try to infer provider and authMethod from cached models first
70
83
  if (!settings.provider) {
71
- const inferredProvider = providersConfig.inferProvider(model);
72
- if (inferredProvider) {
73
- provider = inferredProvider;
84
+ const cached = providersConfig.inferProviderFromCache(model);
85
+ if (cached) {
86
+ provider = cached.provider;
87
+ authMethod = cached.authMethod;
88
+ } else {
89
+ // Fall back to model name inference
90
+ provider = inferProvider(model);
91
+ authMethod = inferAuthMethod(model);
74
92
  }
75
93
  }
76
94
  }
77
95
 
78
96
  return {
79
97
  provider,
98
+ authMethod,
80
99
  model,
81
100
  cwd: process.cwd(),
82
101
  maxTurns: 20,
@@ -12,6 +12,8 @@
12
12
  export type {
13
13
  Settings,
14
14
  SettingsManagerOptions,
15
+ Provider,
16
+ AuthMethod,
15
17
  ProviderName,
16
18
  PermissionRules,
17
19
  ConfigLevelType,
@@ -34,11 +36,11 @@ export {
34
36
  SETTINGS_LOCAL_FILE_NAME,
35
37
  MANAGED_SETTINGS_FILE_NAME,
36
38
  PROVIDERS_FILE_NAME,
37
- GENCODE_DIR,
39
+ GEN_DIR,
38
40
  CLAUDE_DIR,
39
- USER_GENCODE_DIR,
41
+ USER_GEN_DIR,
40
42
  USER_CLAUDE_DIR,
41
- GENCODE_CONFIG_DIRS_ENV,
43
+ GEN_CONFIG_ENV,
42
44
  getManagedPaths,
43
45
  } from './types.js';
44
46
 
@@ -31,10 +31,10 @@ describe('findProjectRoot', () => {
31
31
  expect(await findProjectRoot(subDir)).toBe(test.projectDir);
32
32
  });
33
33
 
34
- it('should find .gencode directory as project root', async () => {
35
- // Remove .git, add .gencode
34
+ it('should find .gen directory as project root', async () => {
35
+ // Remove .git, add .gen
36
36
  await fs.rm(path.join(test.projectDir, '.git'), { recursive: true });
37
- await fs.mkdir(path.join(test.projectDir, '.gencode'));
37
+ await fs.mkdir(path.join(test.projectDir, '.gen'));
38
38
  const subDir = path.join(test.projectDir, 'src');
39
39
  await fs.mkdir(subDir, { recursive: true });
40
40
 
@@ -59,38 +59,38 @@ describe('findProjectRoot', () => {
59
59
  });
60
60
 
61
61
  describe('parseExtraConfigDirs', () => {
62
- const originalEnv = process.env.GENCODE_CONFIG_DIRS;
62
+ const originalEnv = process.env.GEN_CONFIG;
63
63
 
64
64
  afterEach(() => {
65
65
  if (originalEnv === undefined) {
66
- delete process.env.GENCODE_CONFIG_DIRS;
66
+ delete process.env.GEN_CONFIG;
67
67
  } else {
68
- process.env.GENCODE_CONFIG_DIRS = originalEnv;
68
+ process.env.GEN_CONFIG = originalEnv;
69
69
  }
70
70
  });
71
71
 
72
72
  it('should return empty array when env var not set', () => {
73
- delete process.env.GENCODE_CONFIG_DIRS;
73
+ delete process.env.GEN_CONFIG;
74
74
  expect(parseExtraConfigDirs()).toEqual([]);
75
75
  });
76
76
 
77
77
  it('should parse single directory', () => {
78
- process.env.GENCODE_CONFIG_DIRS = '/team/config';
78
+ process.env.GEN_CONFIG = '/team/config';
79
79
  expect(parseExtraConfigDirs()).toEqual(['/team/config']);
80
80
  });
81
81
 
82
82
  it('should parse multiple directories', () => {
83
- process.env.GENCODE_CONFIG_DIRS = '/team/config:/shared/rules';
83
+ process.env.GEN_CONFIG = '/team/config:/shared/rules';
84
84
  expect(parseExtraConfigDirs()).toEqual(['/team/config', '/shared/rules']);
85
85
  });
86
86
 
87
87
  it('should expand tilde to home directory', () => {
88
- process.env.GENCODE_CONFIG_DIRS = '~/my-config';
88
+ process.env.GEN_CONFIG = '~/my-config';
89
89
  expect(parseExtraConfigDirs()[0]).toBe(path.join(os.homedir(), 'my-config'));
90
90
  });
91
91
 
92
92
  it('should trim whitespace and filter empty strings', () => {
93
- process.env.GENCODE_CONFIG_DIRS = ' /path/one : : /path/two ';
93
+ process.env.GEN_CONFIG = ' /path/one : : /path/two ';
94
94
  expect(parseExtraConfigDirs()).toEqual(['/path/one', '/path/two']);
95
95
  });
96
96
  });
@@ -117,11 +117,11 @@ describe('getConfigLevels', () => {
117
117
 
118
118
  expect(userLevel?.paths.length).toBe(2);
119
119
  expect(userLevel?.paths.some((p) => p.namespace === 'claude')).toBe(true);
120
- expect(userLevel?.paths.some((p) => p.namespace === 'gencode')).toBe(true);
120
+ expect(userLevel?.paths.some((p) => p.namespace === 'gen')).toBe(true);
121
121
  });
122
122
 
123
123
  it('should include extra dirs when env var is set', async () => {
124
- process.env.GENCODE_CONFIG_DIRS = '/team/config';
124
+ process.env.GEN_CONFIG = '/team/config';
125
125
  const extraLevels = (await getConfigLevels(test.projectDir)).filter((l) => l.type === 'extra');
126
126
 
127
127
  expect(extraLevels.length).toBeGreaterThan(0);
@@ -131,7 +131,7 @@ describe('getConfigLevels', () => {
131
131
  for (const level of await getConfigLevels(test.projectDir)) {
132
132
  if (level.paths.length >= 2) {
133
133
  const claudeIdx = level.paths.findIndex((p) => p.namespace === 'claude');
134
- const gencodeIdx = level.paths.findIndex((p) => p.namespace === 'gencode');
134
+ const gencodeIdx = level.paths.findIndex((p) => p.namespace === 'gen');
135
135
  if (claudeIdx !== -1 && gencodeIdx !== -1) {
136
136
  expect(claudeIdx).toBeLessThan(gencodeIdx);
137
137
  }
@@ -141,23 +141,23 @@ describe('getConfigLevels', () => {
141
141
  });
142
142
 
143
143
  describe('getPrimarySettingsDir', () => {
144
- it('should return ~/.gencode for user level', () => {
145
- expect(getPrimarySettingsDir('user', '/project')).toBe(path.join(os.homedir(), '.gencode'));
144
+ it('should return ~/.gen for user level', () => {
145
+ expect(getPrimarySettingsDir('user', '/project')).toBe(path.join(os.homedir(), '.gen'));
146
146
  });
147
147
 
148
- it('should return project/.gencode for project and local levels', () => {
149
- expect(getPrimarySettingsDir('project', '/my/project')).toBe('/my/project/.gencode');
150
- expect(getPrimarySettingsDir('local', '/my/project')).toBe('/my/project/.gencode');
148
+ it('should return project/.gen for project and local levels', () => {
149
+ expect(getPrimarySettingsDir('project', '/my/project')).toBe('/my/project/.gen');
150
+ expect(getPrimarySettingsDir('local', '/my/project')).toBe('/my/project/.gen');
151
151
  });
152
152
  });
153
153
 
154
154
  describe('getSettingsFilePath', () => {
155
155
  it('should return correct paths for each level', () => {
156
156
  expect(getSettingsFilePath('user', '/project'))
157
- .toBe(path.join(os.homedir(), '.gencode', 'settings.json'));
157
+ .toBe(path.join(os.homedir(), '.gen', 'settings.json'));
158
158
  expect(getSettingsFilePath('project', '/my/project'))
159
- .toBe('/my/project/.gencode/settings.json');
159
+ .toBe('/my/project/.gen/settings.json');
160
160
  expect(getSettingsFilePath('local', '/my/project'))
161
- .toBe('/my/project/.gencode/settings.local.json');
161
+ .toBe('/my/project/.gen/settings.local.json');
162
162
  });
163
163
  });
@@ -2,8 +2,8 @@
2
2
  * Configuration Levels - Path resolution for multi-level config
3
3
  *
4
4
  * Defines the configuration hierarchy and resolves paths for each level.
5
- * At each level, both .gencode and .claude directories are loaded and merged,
6
- * with .gencode taking higher priority.
5
+ * At each level, both .gen and .claude directories are loaded and merged,
6
+ * with .gen taking higher priority.
7
7
  */
8
8
 
9
9
  import * as path from 'path';
@@ -11,12 +11,12 @@ import * as os from 'os';
11
11
  import * as fs from 'fs/promises';
12
12
  import {
13
13
  ConfigLevelType,
14
- GENCODE_DIR,
14
+ GEN_DIR,
15
15
  CLAUDE_DIR,
16
16
  SETTINGS_FILE_NAME,
17
17
  SETTINGS_LOCAL_FILE_NAME,
18
18
  MANAGED_SETTINGS_FILE_NAME,
19
- GENCODE_CONFIG_DIRS_ENV,
19
+ GEN_CONFIG_ENV,
20
20
  getManagedPaths,
21
21
  } from './types.js';
22
22
 
@@ -27,7 +27,7 @@ export interface ConfigPathInfo {
27
27
  settingsPath: string;
28
28
  localSettingsPath?: string;
29
29
  dir: string;
30
- namespace: 'gencode' | 'claude' | 'extra';
30
+ namespace: 'gen' | 'claude' | 'extra';
31
31
  exists: boolean;
32
32
  }
33
33
 
@@ -57,9 +57,9 @@ export async function findProjectRoot(cwd: string): Promise<string> {
57
57
  // Not a git root, continue
58
58
  }
59
59
 
60
- // Check for .gencode or .claude directories
60
+ // Check for .gen or .claude directories
61
61
  try {
62
- await fs.access(path.join(current, GENCODE_DIR));
62
+ await fs.access(path.join(current, GEN_DIR));
63
63
  return current;
64
64
  } catch {
65
65
  // Continue
@@ -93,10 +93,10 @@ async function pathExists(filePath: string): Promise<boolean> {
93
93
  }
94
94
 
95
95
  /**
96
- * Parse GENCODE_CONFIG_DIRS environment variable
96
+ * Parse GEN_CONFIG environment variable
97
97
  */
98
98
  export function parseExtraConfigDirs(): string[] {
99
- const value = process.env[GENCODE_CONFIG_DIRS_ENV];
99
+ const value = process.env[GEN_CONFIG_ENV];
100
100
  if (!value) return [];
101
101
 
102
102
  return value
@@ -130,11 +130,11 @@ export async function getConfigLevels(cwd: string): Promise<ResolvedLevel[]> {
130
130
  });
131
131
 
132
132
  // GenCode second (higher priority within level)
133
- const userGencodeDir = path.join(home, GENCODE_DIR);
133
+ const userGencodeDir = path.join(home, GEN_DIR);
134
134
  userPaths.push({
135
135
  settingsPath: path.join(userGencodeDir, SETTINGS_FILE_NAME),
136
136
  dir: userGencodeDir,
137
- namespace: 'gencode',
137
+ namespace: 'gen',
138
138
  exists: await pathExists(path.join(userGencodeDir, SETTINGS_FILE_NAME)),
139
139
  });
140
140
 
@@ -180,11 +180,11 @@ export async function getConfigLevels(cwd: string): Promise<ResolvedLevel[]> {
180
180
  });
181
181
 
182
182
  // GenCode second (higher priority within level)
183
- const projectGencodeDir = path.join(projectRoot, GENCODE_DIR);
183
+ const projectGencodeDir = path.join(projectRoot, GEN_DIR);
184
184
  projectPaths.push({
185
185
  settingsPath: path.join(projectGencodeDir, SETTINGS_FILE_NAME),
186
186
  dir: projectGencodeDir,
187
- namespace: 'gencode',
187
+ namespace: 'gen',
188
188
  exists: await pathExists(path.join(projectGencodeDir, SETTINGS_FILE_NAME)),
189
189
  });
190
190
 
@@ -210,7 +210,7 @@ export async function getConfigLevels(cwd: string): Promise<ResolvedLevel[]> {
210
210
  localPaths.push({
211
211
  settingsPath: path.join(projectGencodeDir, SETTINGS_LOCAL_FILE_NAME),
212
212
  dir: projectGencodeDir,
213
- namespace: 'gencode',
213
+ namespace: 'gen',
214
214
  exists: await pathExists(path.join(projectGencodeDir, SETTINGS_LOCAL_FILE_NAME)),
215
215
  });
216
216
 
@@ -234,10 +234,10 @@ export async function getConfigLevels(cwd: string): Promise<ResolvedLevel[]> {
234
234
 
235
235
  // GenCode second (higher priority within level)
236
236
  managedPathsList.push({
237
- settingsPath: path.join(managedPaths.gencode, MANAGED_SETTINGS_FILE_NAME),
238
- dir: managedPaths.gencode,
239
- namespace: 'gencode',
240
- exists: await pathExists(path.join(managedPaths.gencode, MANAGED_SETTINGS_FILE_NAME)),
237
+ settingsPath: path.join(managedPaths.gen, MANAGED_SETTINGS_FILE_NAME),
238
+ dir: managedPaths.gen,
239
+ namespace: 'gen',
240
+ exists: await pathExists(path.join(managedPaths.gen, MANAGED_SETTINGS_FILE_NAME)),
241
241
  });
242
242
 
243
243
  levels.push({
@@ -253,7 +253,7 @@ export async function getConfigLevels(cwd: string): Promise<ResolvedLevel[]> {
253
253
 
254
254
  /**
255
255
  * Get the primary settings directory for saving
256
- * Prefers .gencode if it exists, otherwise creates it
256
+ * Prefers .gen if it exists, otherwise creates it
257
257
  */
258
258
  export function getPrimarySettingsDir(
259
259
  level: 'user' | 'project' | 'local',
@@ -263,12 +263,12 @@ export function getPrimarySettingsDir(
263
263
 
264
264
  switch (level) {
265
265
  case 'user':
266
- return path.join(home, GENCODE_DIR);
266
+ return path.join(home, GEN_DIR);
267
267
  case 'project':
268
268
  case 'local':
269
- return path.join(projectRoot, GENCODE_DIR);
269
+ return path.join(projectRoot, GEN_DIR);
270
270
  default:
271
- return path.join(home, GENCODE_DIR);
271
+ return path.join(home, GEN_DIR);
272
272
  }
273
273
  }
274
274
 
@@ -31,28 +31,28 @@ describe('Config Loader', () => {
31
31
  expect(source?.settings.provider).toBe('openai');
32
32
  });
33
33
 
34
- it('should load settings from project .gencode directory', async () => {
35
- await writeSettings(test.projectDir, 'gencode', { provider: 'anthropic' });
34
+ it('should load settings from project .gen directory', async () => {
35
+ await writeSettings(test.projectDir, 'gen', { provider: 'anthropic' });
36
36
  const sources = await loadAllSources(test.projectDir);
37
37
 
38
- const source = sources.find((s) => s.level === 'project' && s.namespace === 'gencode');
38
+ const source = sources.find((s) => s.level === 'project' && s.namespace === 'gen');
39
39
  expect(source?.settings.provider).toBe('anthropic');
40
40
  });
41
41
 
42
- it('should load both .claude and .gencode settings at same level', async () => {
42
+ it('should load both .claude and .gen settings at same level', async () => {
43
43
  await writeSettings(test.projectDir, 'claude', { provider: 'openai', model: 'gpt-4' });
44
- await writeSettings(test.projectDir, 'gencode', { provider: 'anthropic' });
44
+ await writeSettings(test.projectDir, 'gen', { provider: 'anthropic' });
45
45
 
46
46
  const sources = await loadAllSources(test.projectDir);
47
47
  const claude = sources.find((s) => s.level === 'project' && s.namespace === 'claude');
48
- const gencode = sources.find((s) => s.level === 'project' && s.namespace === 'gencode');
48
+ const gencode = sources.find((s) => s.level === 'project' && s.namespace === 'gen');
49
49
 
50
50
  expect(claude?.settings.provider).toBe('openai');
51
51
  expect(gencode?.settings.provider).toBe('anthropic');
52
52
  });
53
53
 
54
54
  it('should load local settings', async () => {
55
- await writeSettings(test.projectDir, 'gencode', { alwaysThinkingEnabled: true }, true);
55
+ await writeSettings(test.projectDir, 'gen', { alwaysThinkingEnabled: true }, true);
56
56
  const sources = await loadAllSources(test.projectDir);
57
57
 
58
58
  const local = sources.find((s) => s.level === 'local');
@@ -63,7 +63,7 @@ describe('Config Loader', () => {
63
63
  const extraDir = path.join(test.tempDir, 'extra-config');
64
64
  await fs.mkdir(extraDir, { recursive: true });
65
65
  await fs.writeFile(path.join(extraDir, 'settings.json'), JSON.stringify({ theme: 'dark' }));
66
- process.env.GENCODE_CONFIG_DIRS = extraDir;
66
+ process.env.GEN_CONFIG = extraDir;
67
67
 
68
68
  const sources = await loadAllSources(test.projectDir);
69
69
  const extra = sources.find((s) => s.level === 'extra');
@@ -74,7 +74,7 @@ describe('Config Loader', () => {
74
74
  describe('loadSourcesByLevel', () => {
75
75
  it('should group sources by level', async () => {
76
76
  await writeSettings(test.projectDir, 'claude', { model: 'gpt-4' });
77
- await writeSettings(test.projectDir, 'gencode', { model: 'claude-sonnet' });
77
+ await writeSettings(test.projectDir, 'gen', { model: 'claude-sonnet' });
78
78
 
79
79
  const sourcesByLevel = await loadSourcesByLevel(test.projectDir);
80
80
 
@@ -85,8 +85,8 @@ describe('Config Loader', () => {
85
85
 
86
86
  describe('loadProjectSettings', () => {
87
87
  it('should only load project-level settings', async () => {
88
- await writeSettings(test.projectDir, 'gencode', { model: 'claude-sonnet' });
89
- await writeSettings(test.projectDir, 'gencode', { theme: 'dark' }, true);
88
+ await writeSettings(test.projectDir, 'gen', { model: 'claude-sonnet' });
89
+ await writeSettings(test.projectDir, 'gen', { theme: 'dark' }, true);
90
90
 
91
91
  const sources = await loadProjectSettings(test.projectDir);
92
92
 
@@ -99,14 +99,14 @@ describe('Config Loader', () => {
99
99
  describe('getExistingConfigFiles', () => {
100
100
  it('should list all existing config files', async () => {
101
101
  await writeSettings(test.projectDir, 'claude', {});
102
- await writeSettings(test.projectDir, 'gencode', {});
103
- await writeSettings(test.projectDir, 'gencode', {}, true);
102
+ await writeSettings(test.projectDir, 'gen', {});
103
+ await writeSettings(test.projectDir, 'gen', {}, true);
104
104
 
105
105
  const files = await getExistingConfigFiles(test.projectDir);
106
106
 
107
107
  expect(files.length).toBeGreaterThanOrEqual(3);
108
108
  expect(files.some((f) => f.includes('.claude/settings.json'))).toBe(true);
109
- expect(files.some((f) => f.includes('.gencode/settings.json'))).toBe(true);
109
+ expect(files.some((f) => f.includes('.gen/settings.json'))).toBe(true);
110
110
  expect(files.some((f) => f.includes('settings.local.json'))).toBe(true);
111
111
  });
112
112
 
@@ -18,8 +18,8 @@ describe('ConfigManager', () => {
18
18
  afterEach(() => test.cleanup());
19
19
 
20
20
  describe('load', () => {
21
- it('should load settings from .gencode directory', async () => {
22
- await writeSettings(test.projectDir, 'gencode', { provider: 'anthropic', model: 'claude-sonnet' });
21
+ it('should load settings from .gen directory', async () => {
22
+ await writeSettings(test.projectDir, 'gen', { provider: 'anthropic', model: 'claude-sonnet' });
23
23
 
24
24
  const config = await new ConfigManager({ cwd: test.projectDir }).load();
25
25
 
@@ -36,9 +36,9 @@ describe('ConfigManager', () => {
36
36
  expect(config.settings.model).toBe('gpt-4');
37
37
  });
38
38
 
39
- it('should merge both .claude and .gencode with gencode winning', async () => {
39
+ it('should merge both .claude and .gen with gencode winning', async () => {
40
40
  await writeSettings(test.projectDir, 'claude', { provider: 'openai', model: 'gpt-4', theme: 'dark' });
41
- await writeSettings(test.projectDir, 'gencode', { provider: 'anthropic' });
41
+ await writeSettings(test.projectDir, 'gen', { provider: 'anthropic' });
42
42
 
43
43
  const config = await new ConfigManager({ cwd: test.projectDir }).load();
44
44
 
@@ -51,7 +51,7 @@ describe('ConfigManager', () => {
51
51
  await writeSettings(test.projectDir, 'claude', {
52
52
  permissions: { allow: ['Bash(git:*)'], deny: ['WebFetch'] },
53
53
  });
54
- await writeSettings(test.projectDir, 'gencode', {
54
+ await writeSettings(test.projectDir, 'gen', {
55
55
  permissions: { allow: ['Bash(npm:*)'], deny: ['Bash(rm -rf:*)'] },
56
56
  });
57
57
 
@@ -64,8 +64,8 @@ describe('ConfigManager', () => {
64
64
  });
65
65
 
66
66
  it('should load local settings with higher priority', async () => {
67
- await writeSettings(test.projectDir, 'gencode', { model: 'claude-sonnet', theme: 'light' });
68
- await writeSettings(test.projectDir, 'gencode', { model: 'claude-opus' }, true);
67
+ await writeSettings(test.projectDir, 'gen', { model: 'claude-sonnet', theme: 'light' });
68
+ await writeSettings(test.projectDir, 'gen', { model: 'claude-opus' }, true);
69
69
 
70
70
  const { settings } = await new ConfigManager({ cwd: test.projectDir }).load();
71
71
 
@@ -77,7 +77,7 @@ describe('ConfigManager', () => {
77
77
  const extraDir = path.join(test.tempDir, 'team-config');
78
78
  await fs.mkdir(extraDir, { recursive: true });
79
79
  await fs.writeFile(path.join(extraDir, 'settings.json'), JSON.stringify({ teamSetting: 'enabled' }));
80
- process.env.GENCODE_CONFIG_DIRS = extraDir;
80
+ process.env.GEN_CONFIG = extraDir;
81
81
 
82
82
  const { settings } = await new ConfigManager({ cwd: test.projectDir }).load();
83
83
 
@@ -87,7 +87,7 @@ describe('ConfigManager', () => {
87
87
 
88
88
  describe('setCliArgs', () => {
89
89
  it('should apply CLI args with highest priority', async () => {
90
- await writeSettings(test.projectDir, 'gencode', { model: 'claude-sonnet', provider: 'anthropic' });
90
+ await writeSettings(test.projectDir, 'gen', { model: 'claude-sonnet', provider: 'anthropic' });
91
91
 
92
92
  const manager = new ConfigManager({ cwd: test.projectDir });
93
93
  manager.setCliArgs({ model: 'gpt-4o' });
@@ -107,10 +107,10 @@ describe('ConfigManager', () => {
107
107
  await manager.saveToLevel({ debug: true }, 'local');
108
108
 
109
109
  const projectContent = JSON.parse(await fs.readFile(
110
- path.join(test.projectDir, '.gencode', 'settings.json'), 'utf-8'
110
+ path.join(test.projectDir, '.gen', 'settings.json'), 'utf-8'
111
111
  ));
112
112
  const localContent = JSON.parse(await fs.readFile(
113
- path.join(test.projectDir, '.gencode', 'settings.local.json'), 'utf-8'
113
+ path.join(test.projectDir, '.gen', 'settings.local.json'), 'utf-8'
114
114
  ));
115
115
 
116
116
  expect(projectContent.model).toBe('project-model');
@@ -118,14 +118,14 @@ describe('ConfigManager', () => {
118
118
  });
119
119
 
120
120
  it('should merge with existing settings', async () => {
121
- await writeSettings(test.projectDir, 'gencode', { model: 'old', theme: 'dark' });
121
+ await writeSettings(test.projectDir, 'gen', { model: 'old', theme: 'dark' });
122
122
 
123
123
  const manager = new ConfigManager({ cwd: test.projectDir });
124
124
  await manager.load();
125
125
  await manager.saveToLevel({ model: 'new' }, 'project');
126
126
 
127
127
  const saved = JSON.parse(await fs.readFile(
128
- path.join(test.projectDir, '.gencode', 'settings.json'), 'utf-8'
128
+ path.join(test.projectDir, '.gen', 'settings.json'), 'utf-8'
129
129
  ));
130
130
 
131
131
  expect(saved.model).toBe('new');
@@ -142,7 +142,7 @@ describe('ConfigManager', () => {
142
142
  await manager.addPermissionRule('Bash(rm:*)', 'deny', 'project');
143
143
 
144
144
  const saved = JSON.parse(await fs.readFile(
145
- path.join(test.projectDir, '.gencode', 'settings.json'), 'utf-8'
145
+ path.join(test.projectDir, '.gen', 'settings.json'), 'utf-8'
146
146
  ));
147
147
 
148
148
  expect(saved.permissions?.allow).toContain('Bash(npm:*)');
@@ -152,7 +152,7 @@ describe('ConfigManager', () => {
152
152
 
153
153
  describe('getEffectivePermissions', () => {
154
154
  it('should return all permission lists', async () => {
155
- await writeSettings(test.projectDir, 'gencode', {
155
+ await writeSettings(test.projectDir, 'gen', {
156
156
  permissions: { allow: ['A'], ask: ['B'], deny: ['C'] },
157
157
  });
158
158
 
@@ -168,7 +168,7 @@ describe('ConfigManager', () => {
168
168
 
169
169
  describe('isAllowed and shouldAsk', () => {
170
170
  it('should check permissions correctly', async () => {
171
- await writeSettings(test.projectDir, 'gencode', {
171
+ await writeSettings(test.projectDir, 'gen', {
172
172
  permissions: { allow: ['Bash(git:*)'], deny: ['Bash(rm:*)'], ask: ['WebFetch'] },
173
173
  });
174
174
 
@@ -189,14 +189,14 @@ describe('ConfigManager', () => {
189
189
  describe('getSources', () => {
190
190
  it('should return all loaded sources', async () => {
191
191
  await writeSettings(test.projectDir, 'claude', { model: 'gpt-4' });
192
- await writeSettings(test.projectDir, 'gencode', { provider: 'anthropic' });
192
+ await writeSettings(test.projectDir, 'gen', { provider: 'anthropic' });
193
193
 
194
194
  const manager = new ConfigManager({ cwd: test.projectDir });
195
195
  await manager.load();
196
196
  const sources = manager.getSources();
197
197
 
198
198
  expect(sources.find((s) => s.namespace === 'claude')).toBeDefined();
199
- expect(sources.find((s) => s.namespace === 'gencode')).toBeDefined();
199
+ expect(sources.find((s) => s.namespace === 'gen')).toBeDefined();
200
200
  });
201
201
  });
202
202
 
@@ -206,7 +206,7 @@ describe('ConfigManager', () => {
206
206
 
207
207
  expect(manager.getDebugSummary()).toBe('Configuration not loaded');
208
208
 
209
- await writeSettings(test.projectDir, 'gencode', { model: 'test' });
209
+ await writeSettings(test.projectDir, 'gen', { model: 'test' });
210
210
  await manager.load();
211
211
 
212
212
  expect(manager.getDebugSummary()).toContain('Configuration Sources');