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
@@ -7,24 +7,27 @@ import TextInput from 'ink-text-input';
7
7
  import { colors, icons } from './theme.js';
8
8
  import { LoadingSpinner } from './Spinner.js';
9
9
  import { getProviderStore, type ModelInfo } from '../../providers/store.js';
10
- import { getProvider } from '../../providers/registry.js';
11
- import type { ProviderName } from '../../providers/index.js';
10
+ import { getProviderMeta } from '../../providers/registry.js';
11
+ import type { Provider, AuthMethod } from '../../providers/index.js';
12
12
 
13
13
  interface ModelItem {
14
- providerId: ProviderName;
14
+ providerId: Provider;
15
15
  providerName: string;
16
+ authMethod: AuthMethod;
16
17
  model: ModelInfo;
17
18
  }
18
19
 
19
20
  interface ModelSelectorProps {
20
21
  currentModel: string;
21
- onSelect: (modelId: string, providerId: ProviderName) => void;
22
+ currentProvider?: Provider; // Current provider for adding missing model placeholder
23
+ onSelect: (modelId: string, providerId: Provider, authMethod?: AuthMethod) => void;
22
24
  onCancel: () => void;
23
25
  listModels: () => Promise<{ id: string; name: string }[]>; // Fallback for current provider
24
26
  }
25
27
 
26
28
  export function ModelSelector({
27
29
  currentModel,
30
+ currentProvider,
28
31
  onSelect,
29
32
  onCancel,
30
33
  listModels,
@@ -42,14 +45,17 @@ export function ModelSelector({
42
45
  const items: ModelItem[] = [];
43
46
 
44
47
  for (const providerId of connectedProviders) {
48
+ const connection = store.getConnection(providerId);
49
+ const authMethod = connection?.authMethod || 'api_key';
45
50
  const cachedModels = store.getModels(providerId);
46
- const providerDef = getProvider(providerId);
47
- const providerName = providerDef?.name || providerId;
51
+ const providerMeta = getProviderMeta(providerId);
52
+ const providerName = providerMeta?.name || providerId;
48
53
 
49
54
  for (const model of cachedModels) {
50
55
  items.push({
51
56
  providerId,
52
57
  providerName,
58
+ authMethod,
53
59
  model,
54
60
  });
55
61
  }
@@ -61,8 +67,9 @@ export function ModelSelector({
61
67
  const models = await listModels();
62
68
  for (const model of models) {
63
69
  items.push({
64
- providerId: 'anthropic' as ProviderName, // Default, will be overridden
70
+ providerId: 'anthropic' as Provider, // Default, will be overridden
65
71
  providerName: 'Current Provider',
72
+ authMethod: 'api_key', // Default
66
73
  model,
67
74
  });
68
75
  }
@@ -71,12 +78,32 @@ export function ModelSelector({
71
78
  }
72
79
  }
73
80
 
81
+ // Add current model if not in list (e.g., experimental models not cached)
82
+ const hasCurrentModel = items.some((item) => item.model.id === currentModel);
83
+
84
+ if (!hasCurrentModel && currentModel && currentProvider) {
85
+ const connection = store.getConnection(currentProvider);
86
+ const authMethod = connection?.authMethod || 'api_key';
87
+ const providerMeta = getProviderMeta(currentProvider);
88
+ const providerName = providerMeta?.name || currentProvider;
89
+
90
+ items.unshift({
91
+ providerId: currentProvider,
92
+ providerName,
93
+ authMethod,
94
+ model: {
95
+ id: currentModel,
96
+ name: currentModel, // Display logic will add "(current)" marker
97
+ },
98
+ });
99
+ }
100
+
74
101
  setAllModels(items);
75
102
  setLoading(false);
76
103
  };
77
104
 
78
105
  loadModels();
79
- }, [store, listModels]);
106
+ }, [store, listModels, currentModel, currentProvider]);
80
107
 
81
108
  // Filter models
82
109
  const filterLower = filter.toLowerCase();
@@ -101,14 +128,21 @@ export function ModelSelector({
101
128
  return groups;
102
129
  }, [filtered]);
103
130
 
104
- // Flat list for navigation
131
+ // Flat list for navigation - sort to put current model first
105
132
  const flatList = useMemo(() => {
106
133
  const items: ModelItem[] = [];
107
134
  for (const providerId of Object.keys(groupedModels)) {
108
135
  items.push(...groupedModels[providerId]);
109
136
  }
110
- return items;
111
- }, [groupedModels]);
137
+ // Sort: current model first, then alphabetically
138
+ return items.sort((a, b) => {
139
+ const aIsCurrent = a.model.id === currentModel;
140
+ const bIsCurrent = b.model.id === currentModel;
141
+ if (aIsCurrent && !bIsCurrent) return -1;
142
+ if (!aIsCurrent && bIsCurrent) return 1;
143
+ return (a.model.name || a.model.id).localeCompare(b.model.name || b.model.id);
144
+ });
145
+ }, [groupedModels, currentModel]);
112
146
 
113
147
  // Reset selection when filter changes
114
148
  useEffect(() => {
@@ -124,7 +158,7 @@ export function ModelSelector({
124
158
  } else if (key.return) {
125
159
  if (flatList.length > 0) {
126
160
  const selected = flatList[selectedIndex];
127
- onSelect(selected.model.id, selected.providerId);
161
+ onSelect(selected.model.id, selected.providerId, selected.authMethod);
128
162
  }
129
163
  } else if (key.escape) {
130
164
  onCancel();
@@ -152,41 +186,24 @@ export function ModelSelector({
152
186
  );
153
187
  const endIndex = Math.min(startIndex + maxVisible, flatList.length);
154
188
 
155
- // Build visible items with provider headers
156
- let currentIdx = 0;
189
+ // Build visible items with provider headers from sorted flatList
157
190
  const renderItems: Array<{ type: 'header' | 'model'; content: string; item?: ModelItem }> = [];
191
+ let lastProviderId: string | null = null;
158
192
 
159
- for (const providerId of Object.keys(groupedModels)) {
160
- const models = groupedModels[providerId];
161
- const firstIdx = currentIdx;
162
- const lastIdx = currentIdx + models.length - 1;
163
-
164
- // Check if any model from this provider is in visible range
165
- if (lastIdx >= startIndex && firstIdx < endIndex) {
166
- // Add header if first visible item is from this provider
167
- const providerDef = getProvider(providerId as ProviderName);
168
- const connection = store.getConnection(providerId as ProviderName);
169
- const headerText = `${providerDef?.name || providerId}${connection ? ` (${connection.method})` : ''}:`;
170
-
171
- // Only add header if we're showing models from this provider
172
- const visibleModelsFromProvider = models.filter((_, i) => {
173
- const globalIdx = currentIdx + i;
174
- return globalIdx >= startIndex && globalIdx < endIndex;
175
- });
176
-
177
- if (visibleModelsFromProvider.length > 0 && (firstIdx >= startIndex || renderItems.length === 0)) {
178
- renderItems.push({ type: 'header', content: headerText });
179
- }
193
+ for (let i = startIndex; i < endIndex; i++) {
194
+ const item = flatList[i];
195
+ if (!item) continue;
180
196
 
181
- for (let i = 0; i < models.length; i++) {
182
- const globalIdx = currentIdx + i;
183
- if (globalIdx >= startIndex && globalIdx < endIndex) {
184
- renderItems.push({ type: 'model', content: '', item: models[i] });
185
- }
186
- }
197
+ // Add provider header when provider changes
198
+ const providerKey = `${item.providerId}:${item.authMethod}`;
199
+ if (providerKey !== lastProviderId) {
200
+ const providerMeta = getProviderMeta(item.providerId);
201
+ const headerText = `${providerMeta?.name || item.providerId} (${item.authMethod}):`;
202
+ renderItems.push({ type: 'header', content: headerText });
203
+ lastProviderId = providerKey;
187
204
  }
188
205
 
189
- currentIdx += models.length;
206
+ renderItems.push({ type: 'model', content: '', item });
190
207
  }
191
208
 
192
209
  return (
@@ -228,11 +245,13 @@ export function ModelSelector({
228
245
  <Text color={isSelected ? colors.primary : colors.textMuted}>
229
246
  {isSelected ? icons.arrow : ' '}
230
247
  </Text>
248
+ <Text> </Text>
231
249
  <Text color={isCurrent ? colors.primary : colors.textMuted}>
232
250
  {isCurrent ? icons.radio : icons.radioEmpty}
233
251
  </Text>
252
+ <Text> </Text>
234
253
  <Text color={isSelected ? colors.text : colors.textSecondary} bold={isSelected}>
235
- {' '}{item.model.name || item.model.id}
254
+ {item.model.name || item.model.id}
236
255
  </Text>
237
256
  {isCurrent && <Text color={colors.success}> (current)</Text>}
238
257
  </Box>