gencode-ai 0.1.3 → 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 (260) hide show
  1. package/README.md +2 -1
  2. package/dist/agent/agent.d.ts +44 -2
  3. package/dist/agent/agent.d.ts.map +1 -1
  4. package/dist/agent/agent.js +130 -11
  5. package/dist/agent/agent.js.map +1 -1
  6. package/dist/agent/types.d.ts +11 -1
  7. package/dist/agent/types.d.ts.map +1 -1
  8. package/dist/checkpointing/checkpoint-manager.d.ts +87 -0
  9. package/dist/checkpointing/checkpoint-manager.d.ts.map +1 -0
  10. package/dist/checkpointing/checkpoint-manager.js +281 -0
  11. package/dist/checkpointing/checkpoint-manager.js.map +1 -0
  12. package/dist/checkpointing/index.d.ts +29 -0
  13. package/dist/checkpointing/index.d.ts.map +1 -0
  14. package/dist/checkpointing/index.js +29 -0
  15. package/dist/checkpointing/index.js.map +1 -0
  16. package/dist/checkpointing/types.d.ts +98 -0
  17. package/dist/checkpointing/types.d.ts.map +1 -0
  18. package/dist/checkpointing/types.js +7 -0
  19. package/dist/checkpointing/types.js.map +1 -0
  20. package/dist/cli/components/App.d.ts.map +1 -1
  21. package/dist/cli/components/App.js +171 -14
  22. package/dist/cli/components/App.js.map +1 -1
  23. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
  24. package/dist/cli/components/CommandSuggestions.js +5 -0
  25. package/dist/cli/components/CommandSuggestions.js.map +1 -1
  26. package/dist/cli/components/Messages.d.ts +7 -1
  27. package/dist/cli/components/Messages.d.ts.map +1 -1
  28. package/dist/cli/components/Messages.js +12 -3
  29. package/dist/cli/components/Messages.js.map +1 -1
  30. package/dist/cli/components/ModeIndicator.d.ts +42 -0
  31. package/dist/cli/components/ModeIndicator.d.ts.map +1 -0
  32. package/dist/cli/components/ModeIndicator.js +52 -0
  33. package/dist/cli/components/ModeIndicator.js.map +1 -0
  34. package/dist/cli/components/ModelSelector.d.ts +4 -3
  35. package/dist/cli/components/ModelSelector.d.ts.map +1 -1
  36. package/dist/cli/components/ModelSelector.js +54 -37
  37. package/dist/cli/components/ModelSelector.js.map +1 -1
  38. package/dist/cli/components/PlanApproval.d.ts +36 -0
  39. package/dist/cli/components/PlanApproval.d.ts.map +1 -0
  40. package/dist/cli/components/PlanApproval.js +154 -0
  41. package/dist/cli/components/PlanApproval.js.map +1 -0
  42. package/dist/cli/components/ProviderManager.d.ts +2 -2
  43. package/dist/cli/components/ProviderManager.d.ts.map +1 -1
  44. package/dist/cli/components/ProviderManager.js +137 -156
  45. package/dist/cli/components/ProviderManager.js.map +1 -1
  46. package/dist/cli/components/theme.d.ts +2 -0
  47. package/dist/cli/components/theme.d.ts.map +1 -1
  48. package/dist/cli/components/theme.js +3 -0
  49. package/dist/cli/components/theme.js.map +1 -1
  50. package/dist/cli/index.js +30 -13
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/config/index.d.ts +2 -2
  53. package/dist/config/index.d.ts.map +1 -1
  54. package/dist/config/index.js +1 -1
  55. package/dist/config/index.js.map +1 -1
  56. package/dist/config/levels.d.ts +5 -5
  57. package/dist/config/levels.d.ts.map +1 -1
  58. package/dist/config/levels.js +20 -20
  59. package/dist/config/levels.js.map +1 -1
  60. package/dist/config/merger.js +1 -1
  61. package/dist/config/merger.js.map +1 -1
  62. package/dist/config/providers-config.d.ts +8 -5
  63. package/dist/config/providers-config.d.ts.map +1 -1
  64. package/dist/config/providers-config.js +19 -22
  65. package/dist/config/providers-config.js.map +1 -1
  66. package/dist/config/test-utils.d.ts +2 -2
  67. package/dist/config/test-utils.d.ts.map +1 -1
  68. package/dist/config/test-utils.js +4 -4
  69. package/dist/config/test-utils.js.map +1 -1
  70. package/dist/config/types.d.ts +23 -17
  71. package/dist/config/types.d.ts.map +1 -1
  72. package/dist/config/types.js +14 -14
  73. package/dist/config/types.js.map +1 -1
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/memory/memory-manager.d.ts +25 -12
  79. package/dist/memory/memory-manager.d.ts.map +1 -1
  80. package/dist/memory/memory-manager.js +241 -112
  81. package/dist/memory/memory-manager.js.map +1 -1
  82. package/dist/memory/test-utils.d.ts +1 -1
  83. package/dist/memory/test-utils.d.ts.map +1 -1
  84. package/dist/memory/test-utils.js +3 -3
  85. package/dist/memory/test-utils.js.map +1 -1
  86. package/dist/memory/types.d.ts +20 -10
  87. package/dist/memory/types.d.ts.map +1 -1
  88. package/dist/memory/types.js +13 -13
  89. package/dist/memory/types.js.map +1 -1
  90. package/dist/migration/migrate.d.ts +24 -0
  91. package/dist/migration/migrate.d.ts.map +1 -0
  92. package/dist/migration/migrate.js +164 -0
  93. package/dist/migration/migrate.js.map +1 -0
  94. package/dist/permissions/persistence.d.ts +2 -2
  95. package/dist/permissions/persistence.js +4 -4
  96. package/dist/permissions/persistence.js.map +1 -1
  97. package/dist/planning/index.d.ts +13 -0
  98. package/dist/planning/index.d.ts.map +1 -0
  99. package/dist/planning/index.js +15 -0
  100. package/dist/planning/index.js.map +1 -0
  101. package/dist/planning/plan-file.d.ts +59 -0
  102. package/dist/planning/plan-file.d.ts.map +1 -0
  103. package/dist/planning/plan-file.js +278 -0
  104. package/dist/planning/plan-file.js.map +1 -0
  105. package/dist/planning/state.d.ts +127 -0
  106. package/dist/planning/state.d.ts.map +1 -0
  107. package/dist/planning/state.js +261 -0
  108. package/dist/planning/state.js.map +1 -0
  109. package/dist/planning/tools/enter-plan-mode.d.ts +25 -0
  110. package/dist/planning/tools/enter-plan-mode.d.ts.map +1 -0
  111. package/dist/planning/tools/enter-plan-mode.js +98 -0
  112. package/dist/planning/tools/enter-plan-mode.js.map +1 -0
  113. package/dist/planning/tools/exit-plan-mode.d.ts +24 -0
  114. package/dist/planning/tools/exit-plan-mode.d.ts.map +1 -0
  115. package/dist/planning/tools/exit-plan-mode.js +149 -0
  116. package/dist/planning/tools/exit-plan-mode.js.map +1 -0
  117. package/dist/planning/types.d.ts +100 -0
  118. package/dist/planning/types.d.ts.map +1 -0
  119. package/dist/planning/types.js +28 -0
  120. package/dist/planning/types.js.map +1 -0
  121. package/dist/pricing/calculator.d.ts +21 -0
  122. package/dist/pricing/calculator.d.ts.map +1 -0
  123. package/dist/pricing/calculator.js +59 -0
  124. package/dist/pricing/calculator.js.map +1 -0
  125. package/dist/pricing/index.d.ts +7 -0
  126. package/dist/pricing/index.d.ts.map +1 -0
  127. package/dist/pricing/index.js +7 -0
  128. package/dist/pricing/index.js.map +1 -0
  129. package/dist/pricing/models.d.ts +20 -0
  130. package/dist/pricing/models.d.ts.map +1 -0
  131. package/dist/pricing/models.js +322 -0
  132. package/dist/pricing/models.js.map +1 -0
  133. package/dist/pricing/types.d.ts +30 -0
  134. package/dist/pricing/types.d.ts.map +1 -0
  135. package/dist/pricing/types.js +5 -0
  136. package/dist/pricing/types.js.map +1 -0
  137. package/dist/prompts/index.d.ts +5 -4
  138. package/dist/prompts/index.d.ts.map +1 -1
  139. package/dist/prompts/index.js +11 -8
  140. package/dist/prompts/index.js.map +1 -1
  141. package/dist/providers/anthropic.d.ts +2 -1
  142. package/dist/providers/anthropic.d.ts.map +1 -1
  143. package/dist/providers/anthropic.js +24 -10
  144. package/dist/providers/anthropic.js.map +1 -1
  145. package/dist/providers/gemini.d.ts +2 -1
  146. package/dist/providers/gemini.d.ts.map +1 -1
  147. package/dist/providers/gemini.js +28 -14
  148. package/dist/providers/gemini.js.map +1 -1
  149. package/dist/providers/index.d.ts +20 -10
  150. package/dist/providers/index.d.ts.map +1 -1
  151. package/dist/providers/index.js +48 -24
  152. package/dist/providers/index.js.map +1 -1
  153. package/dist/providers/openai.d.ts +2 -1
  154. package/dist/providers/openai.d.ts.map +1 -1
  155. package/dist/providers/openai.js +19 -8
  156. package/dist/providers/openai.js.map +1 -1
  157. package/dist/providers/registry.d.ts +48 -34
  158. package/dist/providers/registry.d.ts.map +1 -1
  159. package/dist/providers/registry.js +72 -88
  160. package/dist/providers/registry.js.map +1 -1
  161. package/dist/providers/store.d.ts +43 -17
  162. package/dist/providers/store.d.ts.map +1 -1
  163. package/dist/providers/store.js +112 -19
  164. package/dist/providers/store.js.map +1 -1
  165. package/dist/providers/types.d.ts +25 -0
  166. package/dist/providers/types.d.ts.map +1 -1
  167. package/dist/providers/vertex-ai.d.ts +15 -7
  168. package/dist/providers/vertex-ai.d.ts.map +1 -1
  169. package/dist/providers/vertex-ai.js +63 -23
  170. package/dist/providers/vertex-ai.js.map +1 -1
  171. package/dist/session/manager.d.ts +4 -0
  172. package/dist/session/manager.d.ts.map +1 -1
  173. package/dist/session/manager.js +8 -0
  174. package/dist/session/manager.js.map +1 -1
  175. package/dist/session/types.js +1 -1
  176. package/dist/session/types.js.map +1 -1
  177. package/dist/tools/index.d.ts +7 -1
  178. package/dist/tools/index.d.ts.map +1 -1
  179. package/dist/tools/index.js +7 -0
  180. package/dist/tools/index.js.map +1 -1
  181. package/dist/tools/registry.d.ts +13 -0
  182. package/dist/tools/registry.d.ts.map +1 -1
  183. package/dist/tools/registry.js +79 -2
  184. package/dist/tools/registry.js.map +1 -1
  185. package/docs/config-system-comparison.md +50 -50
  186. package/docs/cost-tracking-comparison.md +904 -0
  187. package/docs/memory-system.md +124 -31
  188. package/docs/operating-modes.md +96 -0
  189. package/docs/permissions.md +2 -2
  190. package/docs/proposals/0006-memory-system.md +4 -4
  191. package/docs/proposals/0008-checkpointing.md +109 -2
  192. package/docs/proposals/0011-custom-commands.md +2 -1
  193. package/docs/proposals/0021-skills-system.md +2 -1
  194. package/docs/proposals/0023-permission-enhancements.md +2 -2
  195. package/docs/proposals/0025-cost-tracking.md +60 -2
  196. package/docs/proposals/0033-enterprise-deployment.md +1 -1
  197. package/docs/proposals/0041-configuration-system.md +17 -19
  198. package/docs/proposals/0042-prompt-optimization.md +17 -9
  199. package/docs/proposals/README.md +6 -6
  200. package/docs/providers.md +94 -9
  201. package/examples/test-checkpointing.ts +121 -0
  202. package/examples/test-cost-tracking.ts +77 -0
  203. package/examples/test-interrupt-cleanup.ts +94 -0
  204. package/package.json +3 -2
  205. package/scripts/migrate.ts +449 -0
  206. package/src/agent/agent.ts +161 -12
  207. package/src/agent/types.ts +11 -1
  208. package/src/checkpointing/checkpoint-manager.ts +327 -0
  209. package/src/checkpointing/index.ts +45 -0
  210. package/src/checkpointing/types.ts +104 -0
  211. package/src/cli/components/App.tsx +221 -13
  212. package/src/cli/components/CommandSuggestions.tsx +5 -0
  213. package/src/cli/components/Messages.tsx +24 -5
  214. package/src/cli/components/ModeIndicator.tsx +174 -0
  215. package/src/cli/components/ModelSelector.tsx +62 -43
  216. package/src/cli/components/PlanApproval.tsx +327 -0
  217. package/src/cli/components/ProviderManager.tsx +278 -323
  218. package/src/cli/components/theme.ts +3 -0
  219. package/src/cli/index.tsx +36 -17
  220. package/src/config/index.ts +5 -3
  221. package/src/config/levels.test.ts +22 -22
  222. package/src/config/levels.ts +22 -22
  223. package/src/config/loader.test.ts +14 -14
  224. package/src/config/manager.test.ts +19 -19
  225. package/src/config/merger.test.ts +23 -23
  226. package/src/config/merger.ts +1 -1
  227. package/src/config/providers-config.ts +23 -21
  228. package/src/config/test-utils.ts +6 -6
  229. package/src/config/types.ts +30 -20
  230. package/src/index.ts +15 -0
  231. package/src/memory/memory-manager.test.ts +242 -24
  232. package/src/memory/memory-manager.ts +270 -141
  233. package/src/memory/test-utils.ts +4 -4
  234. package/src/memory/types.ts +28 -17
  235. package/src/permissions/persistence.ts +4 -4
  236. package/src/planning/index.ts +53 -0
  237. package/src/planning/plan-file.ts +326 -0
  238. package/src/planning/state.ts +305 -0
  239. package/src/planning/tools/enter-plan-mode.ts +111 -0
  240. package/src/planning/tools/exit-plan-mode.ts +170 -0
  241. package/src/planning/types.ts +150 -0
  242. package/src/pricing/calculator.ts +71 -0
  243. package/src/pricing/index.ts +7 -0
  244. package/src/pricing/models.ts +334 -0
  245. package/src/pricing/types.ts +32 -0
  246. package/src/prompts/index.ts +13 -9
  247. package/src/providers/anthropic.ts +30 -10
  248. package/src/providers/gemini.ts +34 -14
  249. package/src/providers/index.ts +76 -33
  250. package/src/providers/openai.ts +26 -8
  251. package/src/providers/registry.ts +116 -111
  252. package/src/providers/store.ts +130 -28
  253. package/src/providers/types.ts +36 -1
  254. package/src/providers/vertex-ai.ts +70 -23
  255. package/src/session/manager.ts +9 -0
  256. package/src/session/types.ts +1 -1
  257. package/src/tools/index.ts +8 -0
  258. package/src/tools/registry.ts +95 -2
  259. package/.gencode/settings.local.json +0 -7
  260. package/CLAUDE.md +0 -86
@@ -49,9 +49,7 @@ Claude Code supports extensive environment variables:
49
49
 
50
50
  **Cloud Providers:**
51
51
  - `CLAUDE_CODE_USE_BEDROCK` - Enable AWS Bedrock
52
- - `CLAUDE_CODE_USE_VERTEX` - Enable Google Vertex AI
53
52
  - `CLAUDE_CODE_SKIP_BEDROCK_AUTH` - Bypass AWS auth
54
- - `CLAUDE_CODE_SKIP_VERTEX_AUTH` - Bypass Vertex auth
55
53
 
56
54
  **Operational:**
57
55
  - `CLAUDE_CODE_MAX_OUTPUT_TOKENS` - Token limit
@@ -121,7 +119,7 @@ OpenCode provides additional patterns worth adopting:
121
119
  ### Directory Structure
122
120
 
123
121
  ```
124
- ~/.gencode/ # User-level configuration
122
+ ~/.gen/ # User-level configuration
125
123
  ├── settings.json # Main user config
126
124
  ├── settings.local.json # User local overrides (gitignored pattern)
127
125
  ├── GENCODE.md # User context (like CLAUDE.md)
@@ -135,7 +133,7 @@ OpenCode provides additional patterns worth adopting:
135
133
  └── sessions/ # Session data
136
134
 
137
135
  ./gencode.json # Project config (like opencode.json)
138
- ./.gencode/ # Project directory
136
+ ./.gen/ # Project directory
139
137
  ├── settings.local.json # Project local overrides (gitignored)
140
138
  ├── GENCODE.md # Project context
141
139
  ├── rules/ # Path-scoped rules
@@ -146,10 +144,10 @@ OpenCode provides additional patterns worth adopting:
146
144
 
147
145
  1. **Environment variables** (`GENCODE_*`, provider API keys)
148
146
  2. **CLI arguments** (`--model`, `--provider`)
149
- 3. **Project local** (`./.gencode/settings.local.json`)
147
+ 3. **Project local** (`./.gen/settings.local.json`)
150
148
  4. **Project shared** (`./gencode.json`)
151
- 5. **User local** (`~/.gencode/settings.local.json`)
152
- 6. **User global** (`~/.gencode/settings.json`)
149
+ 5. **User local** (`~/.gen/settings.local.json`)
150
+ 6. **User global** (`~/.gen/settings.json`)
153
151
  7. **Defaults**
154
152
 
155
153
  ### API Design
@@ -227,8 +225,8 @@ interface EnvHandler {
227
225
  ### Environment Variables
228
226
 
229
227
  **Provider Selection:**
230
- - `GENCODE_PROVIDER` - Provider name (anthropic, openai, gemini, bedrock, vertex)
231
- - `GENCODE_MODEL` - Model ID
228
+ - `GEN_PROVIDER` - Provider name (anthropic, openai, gemini, bedrock, vertex)
229
+ - `GEN_MODEL` - Model ID
232
230
  - `GENCODE_CONFIG` - Custom config file path
233
231
 
234
232
  **Provider API Keys (Auto-detect):**
@@ -300,7 +298,7 @@ const ConfigSchema = z.object({
300
298
  });
301
299
 
302
300
  export class ConfigLoader {
303
- private userConfigDir = path.join(os.homedir(), '.gencode');
301
+ private userConfigDir = path.join(os.homedir(), '.gen');
304
302
 
305
303
  async load(): Promise<GencodeConfig> {
306
304
  const configs = await Promise.all([
@@ -349,7 +347,7 @@ export class EnvHandler {
349
347
  };
350
348
 
351
349
  getProviderFromEnv(): string | undefined {
352
- return process.env.GENCODE_PROVIDER;
350
+ return process.env.GEN_PROVIDER;
353
351
  }
354
352
 
355
353
  getApiKey(provider: string): string | undefined {
@@ -442,7 +440,7 @@ $ gencode
442
440
  # Uses OpenAI automatically
443
441
 
444
442
  # Or specify explicitly
445
- $ export GENCODE_PROVIDER=anthropic
443
+ $ export GEN_PROVIDER=anthropic
446
444
  $ export ANTHROPIC_API_KEY=sk-ant-...
447
445
  $ gencode
448
446
  ```
@@ -480,7 +478,7 @@ $ gencode config deny "Read(.env)"
480
478
 
481
479
  ### Single Config File
482
480
 
483
- A single `~/.gencoderc` file would be simpler but lacks:
481
+ A single `~/.genrc` file would be simpler but lacks:
484
482
  - Project-specific overrides
485
483
  - Team-shareable settings
486
484
  - Local-only sensitive settings
@@ -526,7 +524,7 @@ Simpler implementation but:
526
524
 
527
525
  ## Migration Path
528
526
 
529
- 1. **From mycode**: Migrate `~/.mycode/` to `~/.gencode/`
527
+ 1. **From mycode**: Migrate `~/.mycode/` to `~/.gen/`
530
528
  2. **Version Detection**: Check for legacy config locations and prompt migration
531
529
  3. **Backward Compatibility**: Support reading old config format for one major version
532
530
 
@@ -570,9 +568,9 @@ Simpler implementation but:
570
568
 
571
569
  ### Key Implementation Details
572
570
 
573
- 1. **Multi-level Loading**: User (`~/.gencode/`) → Project (`./.gencode/`) with proper merge
571
+ 1. **Multi-level Loading**: User (`~/.gen/`) → Project (`./.gen/`) with proper merge
574
572
  2. **Claude Code Compatibility**: Supports both `GENCODE.md` and `CLAUDE.md` for memory files
575
- 3. **Environment Variables**: `GENCODE_PROVIDER`, `GENCODE_MODEL`, and provider API key auto-detection
573
+ 3. **Environment Variables**: `GEN_PROVIDER`, `GEN_MODEL`, and provider API key auto-detection
576
574
  4. **Deep Merge**: Arrays concatenate, objects merge recursively
577
575
  5. **JSONC Support**: Configuration files support comments and trailing commas
578
576
 
@@ -580,8 +578,8 @@ Simpler implementation but:
580
578
 
581
579
  1. Environment variables (`GENCODE_*`)
582
580
  2. CLI arguments
583
- 3. Project local (`./.gencode/settings.local.json`)
581
+ 3. Project local (`./.gen/settings.local.json`)
584
582
  4. Project shared (`./gencode.json`)
585
- 5. User local (`~/.gencode/settings.local.json`)
586
- 6. User global (`~/.gencode/settings.json`)
583
+ 5. User local (`~/.gen/settings.local.json`)
584
+ 6. User global (`~/.gen/settings.json`)
587
585
  7. Defaults
@@ -199,7 +199,7 @@ src/prompts/
199
199
 
200
200
  ### 4.2 Prompt Loading Strategy
201
201
 
202
- The prompt loading system uses a **model → provider → prompt** flow, leveraging the `~/.gencode/providers.json` configuration to automatically determine which prompt to use.
202
+ The prompt loading system uses a **model → provider → prompt** flow, leveraging the `~/.gen/providers.json` configuration to automatically determine which prompt to use.
203
203
 
204
204
  #### 4.2.1 Loading Flow
205
205
 
@@ -209,7 +209,7 @@ model ID (e.g., "claude-sonnet-4-5@20250929")
209
209
 
210
210
  ┌─────────────────────────────────────┐
211
211
  │ Look up provider in providers.json │
212
- │ (search models.{provider}.list)
212
+ │ (search models[provider:*].list)
213
213
  └──────────────┬──────────────────────┘
214
214
 
215
215
  ┌──────────┴──────────┐
@@ -242,18 +242,26 @@ model ID (e.g., "claude-sonnet-4-5@20250929")
242
242
 
243
243
  #### 4.2.2 Provider Lookup from providers.json
244
244
 
245
- The `~/.gencode/providers.json` file stores cached models for each connected provider:
245
+ The `~/.gen/providers.json` file stores cached models for each provider using `"provider:authMethod"` keys:
246
246
 
247
247
  ```json
248
248
  {
249
249
  "models": {
250
- "anthropic": {
250
+ "anthropic:api_key": {
251
+ "cachedAt": "2025-01-17T10:00:00Z",
251
252
  "list": [
252
253
  { "id": "claude-sonnet-4-5@20250929", "name": "Claude Sonnet 4.5" },
253
254
  { "id": "claude-opus-4-1@20250805", "name": "Claude Opus 4.1" }
254
255
  ]
255
256
  },
256
- "gemini": {
257
+ "anthropic:vertex": {
258
+ "cachedAt": "2025-01-17T09:00:00Z",
259
+ "list": [
260
+ { "id": "claude-3-5-sonnet@20241022", "name": "Claude 3.5 Sonnet" }
261
+ ]
262
+ },
263
+ "gemini:api_key": {
264
+ "cachedAt": "2025-01-17T08:00:00Z",
257
265
  "list": [
258
266
  { "id": "gemini-2.5-pro", "name": "Gemini 2.5 Pro" }
259
267
  ]
@@ -262,7 +270,7 @@ The `~/.gencode/providers.json` file stores cached models for each connected pro
262
270
  }
263
271
  ```
264
272
 
265
- Given a model ID, the system searches through each provider's model list to find the owning provider.
273
+ Given a model ID, the system searches through each provider's model list to find the owning provider. The key format is `"provider:authMethod"` to support multiple authentication methods for the same provider.
266
274
 
267
275
  #### 4.2.3 Provider to Prompt Type Mapping
268
276
 
@@ -293,7 +301,7 @@ This ensures the system always has a valid prompt to use.
293
301
  // 5.1.1 Provider Type Definition
294
302
  export type ProviderType = 'anthropic' | 'openai' | 'gemini' | 'generic';
295
303
 
296
- // 5.1.2 Look up provider for a model from ~/.gencode/providers.json
304
+ // 5.1.2 Look up provider for a model from ~/.gen/providers.json
297
305
  export function getProviderForModel(model: string): string | null {
298
306
  const config = loadProvidersConfig();
299
307
  if (!config?.models) return null;
@@ -462,7 +470,7 @@ User starts GenCode CLI
462
470
 
463
471
 
464
472
  ┌─────────────────────┐ ┌─────────────────────────────┐
465
- │ 3. Memory Loading │────▶│ Load ~/.gencode/GENCODE.md │
473
+ │ 3. Memory Loading │────▶│ Load ~/.gen/GENCODE.md │
466
474
  │ (if exists) │ │ Load ./CLAUDE.md (fallback) │
467
475
  └──────────┬──────────┘ └─────────────────────────────┘
468
476
 
@@ -480,7 +488,7 @@ User starts GenCode CLI
480
488
  │ │
481
489
  │ ┌─────────────────────────────────────────────────┐ │
482
490
  │ │ a. getPromptTypeForModel(model, fallback) │ │
483
- │ │ - Look up provider in ~/.gencode/providers.json│
491
+ │ │ - Look up provider in ~/.gen/providers.json│
484
492
  │ │ - Map provider → prompt type │ │
485
493
  │ │ - Fallback to 'generic' if not found │ │
486
494
  │ └─────────────────────────────────────────────────┘ │
@@ -19,15 +19,14 @@ This directory contains enhancement proposals for the gencode project. Each prop
19
19
  | [0001](./0001-web-fetch-tool.md) | WebFetch Tool | Implemented |
20
20
  | [0002](./0002-web-search-tool.md) | WebSearch Tool | Implemented |
21
21
  | [0003](./0003-task-subagents.md) | Task Tool & Subagents | Draft |
22
- | [0004](./0004-plan-mode.md) | Plan Mode | Draft |
22
+ | [0004](./0004-plan-mode.md) | Plan Mode | Implemented |
23
23
  | [0005](./0005-todo-system.md) | Todo System | Implemented |
24
24
  | [0006](./0006-memory-system.md) | Memory System (MYCODE.md) | Implemented |
25
25
  | [0007](./0007-context-management.md) | Context Management | Draft |
26
- | [0008](./0008-checkpointing.md) | Checkpointing | Draft |
26
+ | [0008](./0008-checkpointing.md) | Checkpointing | Partially Implemented |
27
27
  | [0009](./0009-hooks-system.md) | Hooks System | Draft |
28
28
  | [0010](./0010-mcp-integration.md) | MCP Integration | Draft |
29
- | [0011](./0011-custom-commands.md) | Custom Commands | Draft |
30
- | [0012](./0012-ask-user-question.md) | AskUserQuestion Tool | Implemented |
29
+ | [0021](./0021-skills-system.md) | Skills System | Draft |
31
30
  | [0041](./0041-configuration-system.md) | Configuration System | Implemented |
32
31
  | [0042](./0042-prompt-optimization.md) | Prompt System Optimization | Implemented |
33
32
 
@@ -35,6 +34,8 @@ This directory contains enhancement proposals for the gencode project. Each prop
35
34
 
36
35
  | ID | Title | Status |
37
36
  |----|-------|--------|
37
+ | [0011](./0011-custom-commands.md) | Custom Commands | Draft |
38
+ | [0012](./0012-ask-user-question.md) | AskUserQuestion Tool | Implemented |
38
39
  | [0013](./0013-multi-edit-tool.md) | MultiEdit Tool | Draft |
39
40
  | [0014](./0014-lsp-tool.md) | LSP Tool | Draft |
40
41
  | [0015](./0015-ls-tool.md) | LS Tool | Draft |
@@ -43,11 +44,10 @@ This directory contains enhancement proposals for the gencode project. Each prop
43
44
  | [0018](./0018-parallel-tool-execution.md) | Parallel Tool Execution | Draft |
44
45
  | [0019](./0019-session-enhancements.md) | Session Enhancements | Draft |
45
46
  | [0020](./0020-session-summarization.md) | Session Summarization | Draft |
46
- | [0021](./0021-skills-system.md) | Skills System | Draft |
47
47
  | [0022](./0022-plugin-system.md) | Plugin System | Draft |
48
48
  | [0023](./0023-permission-enhancements.md) | Permission Enhancements | Draft |
49
49
  | [0024](./0024-keyboard-shortcuts.md) | Keyboard Shortcuts | Draft |
50
- | [0025](./0025-cost-tracking.md) | Cost Tracking | Draft |
50
+ | [0025](./0025-cost-tracking.md) | Cost Tracking | Implemented |
51
51
  | [0026](./0026-git-integration.md) | Git Integration | Draft |
52
52
  | [0027](./0027-enhanced-read-tool.md) | Enhanced Read Tool | Draft |
53
53
  | [0028](./0028-enhanced-bash-tool.md) | Enhanced Bash Tool | Draft |
package/docs/providers.md CHANGED
@@ -131,16 +131,25 @@ To use Claude models via Google Vertex AI:
131
131
  ### 1. Set Environment Variables
132
132
 
133
133
  ```bash
134
+ # Required: Enable Vertex AI
135
+ export CLAUDE_CODE_USE_VERTEX=1
136
+
134
137
  # Required: Your GCP project ID
135
138
  export ANTHROPIC_VERTEX_PROJECT_ID="your-project-id"
136
139
 
137
- # Optional: Region (defaults to us-east5)
138
- export ANTHROPIC_VERTEX_REGION="us-east5"
140
+ # Required: Region (use 'global' or specific region)
141
+ export CLOUD_ML_REGION=global
139
142
  ```
140
143
 
141
- Alternative variables also supported:
142
- - `GOOGLE_CLOUD_PROJECT` - GCP project ID
143
- - `CLOUD_ML_REGION` - GCP region
144
+ **Environment Variable Details:**
145
+
146
+ | Variable | Required | Default | Description |
147
+ |----------|----------|---------|-------------|
148
+ | `CLAUDE_CODE_USE_VERTEX` | Yes | - | Set to `1` to enable Vertex AI |
149
+ | `ANTHROPIC_VERTEX_PROJECT_ID` | Yes | - | Your GCP project ID (also accepts `GCLOUD_PROJECT` or `GOOGLE_CLOUD_PROJECT`) |
150
+ | `CLOUD_ML_REGION` | Yes | `us-east5` | Region (use `global` or specific region like `us-east5`) |
151
+
152
+ **Documentation:** https://code.claude.com/docs/en/google-vertex-ai
144
153
 
145
154
  ### 2. Authenticate with Google Cloud
146
155
 
@@ -169,12 +178,24 @@ gcloud services enable aiplatform.googleapis.com
169
178
  # Press Enter to connect
170
179
  ```
171
180
 
181
+ ## Architecture
182
+
183
+ GenCode uses a two-layer provider architecture:
184
+
185
+ - **Layer 1: Provider** (Semantic layer) - `anthropic` | `openai` | `gemini`
186
+ - **Layer 2: AuthMethod** (Implementation layer) - `api_key` | `vertex` | `bedrock` | `azure`
187
+
188
+ Each provider can support multiple authentication methods. For example, Anthropic supports:
189
+ - `api_key` - Direct API access
190
+ - `vertex` - Google Vertex AI
191
+ - `bedrock` - Amazon Bedrock (coming soon)
192
+
172
193
  ## Configuration Storage
173
194
 
174
195
  Provider connections and cached models are stored in:
175
196
 
176
197
  ```
177
- ~/.gencode/
198
+ ~/.gen/
178
199
  ├── settings.json # Current model and provider settings
179
200
  └── providers.json # Provider connections and model cache
180
201
  ```
@@ -185,23 +206,87 @@ Provider connections and cached models are stored in:
185
206
  {
186
207
  "connections": {
187
208
  "anthropic": {
188
- "method": "vertex",
209
+ "authMethod": "vertex",
210
+ "method": "Google Vertex AI",
189
211
  "connectedAt": "2025-01-15T10:00:00Z"
212
+ },
213
+ "openai": {
214
+ "authMethod": "api_key",
215
+ "method": "Direct API",
216
+ "connectedAt": "2025-01-15T09:00:00Z"
190
217
  }
191
218
  },
192
219
  "models": {
193
- "anthropic": {
220
+ "anthropic:vertex": {
194
221
  "cachedAt": "2025-01-15T10:00:00Z",
222
+ "list": [
223
+ { "id": "claude-3-5-sonnet@20241022", "name": "Claude 3.5 Sonnet" }
224
+ ]
225
+ },
226
+ "anthropic:api_key": {
227
+ "cachedAt": "2025-01-15T11:00:00Z",
195
228
  "list": [
196
229
  { "id": "claude-sonnet-4-5@20250929", "name": "Claude Sonnet 4.5" }
197
230
  ]
231
+ },
232
+ "openai:api_key": {
233
+ "cachedAt": "2025-01-15T09:00:00Z",
234
+ "list": [
235
+ { "id": "gpt-4", "name": "GPT-4" }
236
+ ]
198
237
  }
199
238
  },
200
239
  "searchProvider": "exa"
201
240
  }
202
241
  ```
203
242
 
204
- The `searchProvider` field stores the selected search provider. Valid values: `exa`, `serper`, `brave`. If not set, defaults to `exa`.
243
+ **Key points:**
244
+ - `connections` stores the active connection for each provider
245
+ - `authMethod` - Authentication method being used
246
+ - `method` - Display name (optional, legacy field)
247
+ - `models` uses `"provider:authMethod"` as the key
248
+ - Supports multiple auth methods for the same provider
249
+ - Each auth method has its own cached model list
250
+ - `searchProvider` - Selected search provider (`exa`, `serper`, `brave`)
251
+
252
+ ### Migration from Old Format
253
+
254
+ If you're upgrading from an older version, run the migration script to update your configuration:
255
+
256
+ ```bash
257
+ npm run migrate
258
+ ```
259
+
260
+ The script will:
261
+ 1. Convert old format models keys (e.g., `"anthropic"`) to new format (e.g., `"anthropic:vertex"`)
262
+ 2. Add `authMethod` field to connections
263
+ 3. Create a backup of your old configuration
264
+
265
+ **Old format:**
266
+ ```json
267
+ {
268
+ "models": {
269
+ "anthropic": {
270
+ "provider": "anthropic",
271
+ "authMethod": "vertex",
272
+ "cachedAt": "...",
273
+ "list": [...]
274
+ }
275
+ }
276
+ }
277
+ ```
278
+
279
+ **New format:**
280
+ ```json
281
+ {
282
+ "models": {
283
+ "anthropic:vertex": {
284
+ "cachedAt": "...",
285
+ "list": [...]
286
+ }
287
+ }
288
+ }
289
+ ```
205
290
 
206
291
  ## Troubleshooting
207
292
 
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Test Checkpointing System
3
+ *
4
+ * This example demonstrates the automatic file change tracking and rewind capabilities.
5
+ */
6
+
7
+ import { CheckpointManager } from '../src/checkpointing/index.js';
8
+ import * as fs from 'fs/promises';
9
+ import * as path from 'path';
10
+ import { fileURLToPath } from 'url';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+
15
+ async function testCheckpointing() {
16
+ console.log('🧪 Testing Checkpointing System\n');
17
+
18
+ const manager = new CheckpointManager('test-session');
19
+ const testDir = path.join(__dirname, '../.test-checkpoints');
20
+ const testFile = path.join(testDir, 'example.txt');
21
+
22
+ try {
23
+ // Create test directory
24
+ await fs.mkdir(testDir, { recursive: true });
25
+
26
+ console.log('1️⃣ Recording file creation...');
27
+ const originalContent = 'Hello, World!';
28
+ await fs.writeFile(testFile, originalContent, 'utf-8');
29
+
30
+ manager.recordChange({
31
+ path: testFile,
32
+ changeType: 'create',
33
+ previousContent: null,
34
+ newContent: originalContent,
35
+ toolName: 'Write',
36
+ });
37
+
38
+ console.log(' ✓ File created:', testFile);
39
+ console.log(' ✓ Checkpoint recorded\n');
40
+
41
+ console.log('2️⃣ Recording file modification...');
42
+ const modifiedContent = 'Hello, Checkpointing!';
43
+ await fs.writeFile(testFile, modifiedContent, 'utf-8');
44
+
45
+ manager.recordChange({
46
+ path: testFile,
47
+ changeType: 'modify',
48
+ previousContent: originalContent,
49
+ newContent: modifiedContent,
50
+ toolName: 'Edit',
51
+ });
52
+
53
+ console.log(' ✓ File modified');
54
+ console.log(' ✓ Checkpoint recorded\n');
55
+
56
+ console.log('3️⃣ Listing checkpoints...');
57
+ console.log(manager.formatCheckpointList(true));
58
+ console.log();
59
+
60
+ console.log('4️⃣ Getting summary...');
61
+ const summary = manager.getSummary();
62
+ console.log(` Created: ${summary.created}`);
63
+ console.log(` Modified: ${summary.modified}`);
64
+ console.log(` Deleted: ${summary.deleted}`);
65
+ console.log(` Total: ${summary.total}\n`);
66
+
67
+ console.log('5️⃣ Rewinding last change...');
68
+ const result = await manager.rewind({ count: 1 });
69
+
70
+ if (result.success) {
71
+ console.log(' ✓ Rewind successful');
72
+ result.revertedFiles.forEach((f) => {
73
+ console.log(` • ${path.basename(f.path)} (${f.action})`);
74
+ });
75
+
76
+ // Verify content was restored
77
+ const restoredContent = await fs.readFile(testFile, 'utf-8');
78
+ if (restoredContent === originalContent) {
79
+ console.log(' ✓ Content restored correctly\n');
80
+ } else {
81
+ console.log(' ✗ Content mismatch!\n');
82
+ }
83
+ } else {
84
+ console.log(' ✗ Rewind failed');
85
+ result.errors.forEach((e) => console.log(` ${e.error}`));
86
+ }
87
+
88
+ console.log('6️⃣ Rewinding all changes...');
89
+ const finalResult = await manager.rewind({ all: true });
90
+
91
+ if (finalResult.success) {
92
+ console.log(' ✓ All changes reverted');
93
+ finalResult.revertedFiles.forEach((f) => {
94
+ console.log(` • ${path.basename(f.path)} (${f.action})`);
95
+ });
96
+
97
+ // Verify file was deleted
98
+ try {
99
+ await fs.access(testFile);
100
+ console.log(' ✗ File still exists!\n');
101
+ } catch {
102
+ console.log(' ✓ File was deleted as expected\n');
103
+ }
104
+ }
105
+
106
+ console.log('✅ All tests passed!\n');
107
+ } catch (error) {
108
+ console.error('❌ Test failed:', error);
109
+ } finally {
110
+ // Cleanup
111
+ try {
112
+ await fs.rm(testDir, { recursive: true, force: true });
113
+ console.log('🧹 Cleaned up test directory');
114
+ } catch {
115
+ // Ignore cleanup errors
116
+ }
117
+ }
118
+ }
119
+
120
+ // Run the test
121
+ testCheckpointing();
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Test cost tracking functionality
3
+ */
4
+
5
+ import { createProvider } from '../src/providers/index.js';
6
+ import { calculateCost, formatCost, formatTokens } from '../src/pricing/calculator.js';
7
+
8
+ async function testCostTracking() {
9
+ console.log('='.repeat(60));
10
+ console.log('Testing Cost Tracking Feature');
11
+ console.log('='.repeat(60));
12
+ console.log();
13
+
14
+ // Test 1: Cost Calculation
15
+ console.log('Test 1: Cost Calculation');
16
+ console.log('-'.repeat(60));
17
+
18
+ const testCases = [
19
+ { provider: 'anthropic', model: 'claude-sonnet-4', input: 1000, output: 500 },
20
+ { provider: 'openai', model: 'gpt-4o', input: 1000, output: 500 },
21
+ { provider: 'gemini', model: 'gemini-2.0-flash', input: 1000, output: 500 },
22
+ ];
23
+
24
+ for (const test of testCases) {
25
+ const cost = calculateCost(test.provider, test.model, {
26
+ inputTokens: test.input,
27
+ outputTokens: test.output,
28
+ });
29
+
30
+ console.log(`\n${test.provider}/${test.model}:`);
31
+ console.log(` Input: ${formatTokens(test.input)} tokens`);
32
+ console.log(` Output: ${formatTokens(test.output)} tokens`);
33
+ console.log(` Cost: ${formatCost(cost.totalCost)}`);
34
+ console.log(` Breakdown: ${formatCost(cost.inputCost)} (input) + ${formatCost(cost.outputCost)} (output)`);
35
+ }
36
+
37
+ console.log();
38
+ console.log('='.repeat(60));
39
+ console.log();
40
+
41
+ // Test 2: Real API Call (if env var is set)
42
+ if (process.env.ANTHROPIC_API_KEY) {
43
+ console.log('Test 2: Real API Call with Anthropic');
44
+ console.log('-'.repeat(60));
45
+
46
+ const provider = createProvider({ provider: 'anthropic', model: 'claude-haiku-3-5' });
47
+
48
+ const response = await provider.complete({
49
+ model: 'claude-haiku-3-5',
50
+ messages: [{ role: 'user', content: 'Say hello in one word' }],
51
+ maxTokens: 10,
52
+ });
53
+
54
+ console.log('\nResponse:', response.content[0]?.type === 'text' ? response.content[0].text : '');
55
+
56
+ if (response.usage) {
57
+ console.log(`\nToken Usage:`);
58
+ console.log(` Input: ${formatTokens(response.usage.inputTokens)}`);
59
+ console.log(` Output: ${formatTokens(response.usage.outputTokens)}`);
60
+ }
61
+
62
+ if (response.cost) {
63
+ console.log(`\nCost Estimate:`);
64
+ console.log(` Total: ${formatCost(response.cost.totalCost)}`);
65
+ console.log(` Input: ${formatCost(response.cost.inputCost)}`);
66
+ console.log(` Output: ${formatCost(response.cost.outputCost)}`);
67
+ }
68
+
69
+ console.log();
70
+ console.log('='.repeat(60));
71
+ } else {
72
+ console.log('Skipping API test (no ANTHROPIC_API_KEY)');
73
+ console.log('='.repeat(60));
74
+ }
75
+ }
76
+
77
+ testCostTracking().catch(console.error);
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Test Interrupt Cleanup
3
+ *
4
+ * Simulates the interrupt scenario and verifies cleanup works correctly
5
+ */
6
+
7
+ import { Agent } from '../src/agent/index.js';
8
+ import type { Message } from '../src/providers/types.js';
9
+
10
+ async function testInterruptCleanup() {
11
+ console.log('🧪 Testing Interrupt Cleanup\n');
12
+
13
+ const agent = new Agent({
14
+ provider: 'anthropic',
15
+ model: 'claude-3-5-sonnet-20241022',
16
+ cwd: process.cwd(),
17
+ });
18
+
19
+ try {
20
+ // Simulate incomplete tool_use message (what happens during interrupt)
21
+ console.log('1️⃣ Simulating incomplete tool_use message...');
22
+
23
+ // Access private messages array via getHistory and direct manipulation
24
+ const history = agent.getHistory();
25
+ console.log(` Initial history: ${history.length} messages`);
26
+
27
+ // Add a user message
28
+ (agent as any).messages.push({
29
+ role: 'user',
30
+ content: 'Create a file',
31
+ });
32
+ console.log(` After user message: ${agent.getHistory().length} messages`);
33
+
34
+ // Add an assistant message with tool_use (simulating interrupt point)
35
+ (agent as any).messages.push({
36
+ role: 'assistant',
37
+ content: [
38
+ { type: 'text', text: 'I will create the file.' },
39
+ {
40
+ type: 'tool_use',
41
+ id: 'toolu_test_123',
42
+ name: 'Write',
43
+ input: { file_path: 'test.txt', content: 'hello' },
44
+ },
45
+ ],
46
+ });
47
+ console.log(` After assistant+tool_use: ${agent.getHistory().length} messages`);
48
+ console.log(` Last message role: ${agent.getHistory()[agent.getHistory().length - 1].role}`);
49
+
50
+ // Verify incomplete state
51
+ const lastMessage = agent.getHistory()[agent.getHistory().length - 1];
52
+ const hasToolUse = Array.isArray(lastMessage.content) &&
53
+ lastMessage.content.some((c: any) => c.type === 'tool_use');
54
+ console.log(` Has incomplete tool_use: ${hasToolUse}\n`);
55
+
56
+ console.log('2️⃣ Calling cleanupIncompleteMessages()...');
57
+ agent.cleanupIncompleteMessages();
58
+
59
+ const afterCleanup = agent.getHistory();
60
+ console.log(` After cleanup: ${afterCleanup.length} messages`);
61
+
62
+ if (afterCleanup.length === 1 && afterCleanup[0].role === 'user') {
63
+ console.log(' ✓ Incomplete assistant message removed!\n');
64
+ } else {
65
+ console.log(' ✗ Cleanup failed!\n');
66
+ console.log(' Remaining messages:', JSON.stringify(afterCleanup, null, 2));
67
+ }
68
+
69
+ console.log('3️⃣ Testing with complete messages (no tool_use)...');
70
+
71
+ // Add complete assistant message
72
+ (agent as any).messages.push({
73
+ role: 'assistant',
74
+ content: [{ type: 'text', text: 'Here is your answer.' }],
75
+ });
76
+ console.log(` Before cleanup: ${agent.getHistory().length} messages`);
77
+
78
+ agent.cleanupIncompleteMessages();
79
+ console.log(` After cleanup: ${agent.getHistory().length} messages`);
80
+
81
+ if (agent.getHistory().length === 2) {
82
+ console.log(' ✓ Complete messages preserved!\n');
83
+ } else {
84
+ console.log(' ✗ Complete message was incorrectly removed!\n');
85
+ }
86
+
87
+ console.log('✅ All tests passed!\n');
88
+ } catch (error) {
89
+ console.error('❌ Test failed:', error);
90
+ }
91
+ }
92
+
93
+ // Run the test
94
+ testInterruptCleanup();