gencode-ai 0.1.0 → 0.1.2

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 (356) hide show
  1. package/.gencode/settings.local.json +7 -0
  2. package/README.md +20 -102
  3. package/dist/agent/agent.d.ts +43 -2
  4. package/dist/agent/agent.d.ts.map +1 -1
  5. package/dist/agent/agent.js +90 -17
  6. package/dist/agent/agent.js.map +1 -1
  7. package/dist/agent/types.d.ts +9 -1
  8. package/dist/agent/types.d.ts.map +1 -1
  9. package/dist/cli/components/AllModelsSelector.d.ts +11 -0
  10. package/dist/cli/components/AllModelsSelector.d.ts.map +1 -0
  11. package/dist/cli/components/AllModelsSelector.js +153 -0
  12. package/dist/cli/components/AllModelsSelector.js.map +1 -0
  13. package/dist/cli/components/App.d.ts +8 -1
  14. package/dist/cli/components/App.d.ts.map +1 -1
  15. package/dist/cli/components/App.js +276 -40
  16. package/dist/cli/components/App.js.map +1 -1
  17. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
  18. package/dist/cli/components/CommandSuggestions.js +3 -0
  19. package/dist/cli/components/CommandSuggestions.js.map +1 -1
  20. package/dist/cli/components/Header.d.ts +1 -1
  21. package/dist/cli/components/Header.d.ts.map +1 -1
  22. package/dist/cli/components/Header.js +4 -6
  23. package/dist/cli/components/Header.js.map +1 -1
  24. package/dist/cli/components/Logo.d.ts +1 -0
  25. package/dist/cli/components/Logo.d.ts.map +1 -1
  26. package/dist/cli/components/Logo.js +16 -3
  27. package/dist/cli/components/Logo.js.map +1 -1
  28. package/dist/cli/components/Messages.d.ts +17 -3
  29. package/dist/cli/components/Messages.d.ts.map +1 -1
  30. package/dist/cli/components/Messages.js +70 -18
  31. package/dist/cli/components/Messages.js.map +1 -1
  32. package/dist/cli/components/ModelSelector.d.ts +7 -7
  33. package/dist/cli/components/ModelSelector.d.ts.map +1 -1
  34. package/dist/cli/components/ModelSelector.js +116 -33
  35. package/dist/cli/components/ModelSelector.js.map +1 -1
  36. package/dist/cli/components/PermissionPrompt.d.ts +60 -0
  37. package/dist/cli/components/PermissionPrompt.d.ts.map +1 -0
  38. package/dist/cli/components/PermissionPrompt.js +192 -0
  39. package/dist/cli/components/PermissionPrompt.js.map +1 -0
  40. package/dist/cli/components/ProviderManager.d.ts +8 -0
  41. package/dist/cli/components/ProviderManager.d.ts.map +1 -0
  42. package/dist/cli/components/ProviderManager.js +280 -0
  43. package/dist/cli/components/ProviderManager.js.map +1 -0
  44. package/dist/cli/components/Spinner.d.ts +7 -2
  45. package/dist/cli/components/Spinner.d.ts.map +1 -1
  46. package/dist/cli/components/Spinner.js +116 -25
  47. package/dist/cli/components/Spinner.js.map +1 -1
  48. package/dist/cli/components/TodoList.d.ts +7 -0
  49. package/dist/cli/components/TodoList.d.ts.map +1 -0
  50. package/dist/cli/components/TodoList.js +34 -0
  51. package/dist/cli/components/TodoList.js.map +1 -0
  52. package/dist/cli/components/index.d.ts +1 -0
  53. package/dist/cli/components/index.d.ts.map +1 -1
  54. package/dist/cli/components/index.js +1 -0
  55. package/dist/cli/components/index.js.map +1 -1
  56. package/dist/cli/components/markdown.d.ts +9 -0
  57. package/dist/cli/components/markdown.d.ts.map +1 -0
  58. package/dist/cli/components/markdown.js +129 -0
  59. package/dist/cli/components/markdown.js.map +1 -0
  60. package/dist/cli/components/theme.d.ts +5 -0
  61. package/dist/cli/components/theme.d.ts.map +1 -1
  62. package/dist/cli/components/theme.js +7 -0
  63. package/dist/cli/components/theme.js.map +1 -1
  64. package/dist/cli/index.js +66 -12
  65. package/dist/cli/index.js.map +1 -1
  66. package/dist/config/index.d.ts +14 -4
  67. package/dist/config/index.d.ts.map +1 -1
  68. package/dist/config/index.js +19 -3
  69. package/dist/config/index.js.map +1 -1
  70. package/dist/config/levels.d.ts +49 -0
  71. package/dist/config/levels.d.ts.map +1 -0
  72. package/dist/config/levels.js +222 -0
  73. package/dist/config/levels.js.map +1 -0
  74. package/dist/config/loader.d.ts +46 -0
  75. package/dist/config/loader.d.ts.map +1 -0
  76. package/dist/config/loader.js +153 -0
  77. package/dist/config/loader.js.map +1 -0
  78. package/dist/config/manager.d.ts +115 -15
  79. package/dist/config/manager.d.ts.map +1 -1
  80. package/dist/config/manager.js +260 -34
  81. package/dist/config/manager.js.map +1 -1
  82. package/dist/config/manager.test.d.ts +5 -0
  83. package/dist/config/manager.test.d.ts.map +1 -0
  84. package/dist/config/manager.test.js +192 -0
  85. package/dist/config/manager.test.js.map +1 -0
  86. package/dist/config/merger.d.ts +56 -0
  87. package/dist/config/merger.d.ts.map +1 -0
  88. package/dist/config/merger.js +177 -0
  89. package/dist/config/merger.js.map +1 -0
  90. package/dist/config/providers-config.d.ts +28 -0
  91. package/dist/config/providers-config.d.ts.map +1 -0
  92. package/dist/config/providers-config.js +79 -0
  93. package/dist/config/providers-config.js.map +1 -0
  94. package/dist/config/test-utils.d.ts +24 -0
  95. package/dist/config/test-utils.d.ts.map +1 -0
  96. package/dist/config/test-utils.js +55 -0
  97. package/dist/config/test-utils.js.map +1 -0
  98. package/dist/config/types.d.ts +108 -9
  99. package/dist/config/types.d.ts.map +1 -1
  100. package/dist/config/types.js +53 -2
  101. package/dist/config/types.js.map +1 -1
  102. package/dist/memory/import-resolver.d.ts +46 -0
  103. package/dist/memory/import-resolver.d.ts.map +1 -0
  104. package/dist/memory/import-resolver.js +117 -0
  105. package/dist/memory/import-resolver.js.map +1 -0
  106. package/dist/memory/index.d.ts +7 -6
  107. package/dist/memory/index.d.ts.map +1 -1
  108. package/dist/memory/index.js +7 -5
  109. package/dist/memory/index.js.map +1 -1
  110. package/dist/memory/init-prompt.d.ts +22 -0
  111. package/dist/memory/init-prompt.d.ts.map +1 -0
  112. package/dist/memory/init-prompt.js +103 -0
  113. package/dist/memory/init-prompt.js.map +1 -0
  114. package/dist/memory/memory-manager.d.ts +119 -0
  115. package/dist/memory/memory-manager.d.ts.map +1 -0
  116. package/dist/memory/memory-manager.js +587 -0
  117. package/dist/memory/memory-manager.js.map +1 -0
  118. package/dist/memory/rules-parser.d.ts +38 -0
  119. package/dist/memory/rules-parser.d.ts.map +1 -0
  120. package/dist/memory/rules-parser.js +69 -0
  121. package/dist/memory/rules-parser.js.map +1 -0
  122. package/dist/memory/test-utils.d.ts +20 -0
  123. package/dist/memory/test-utils.d.ts.map +1 -0
  124. package/dist/memory/test-utils.js +44 -0
  125. package/dist/memory/test-utils.js.map +1 -0
  126. package/dist/memory/types.d.ts +70 -63
  127. package/dist/memory/types.d.ts.map +1 -1
  128. package/dist/memory/types.js +42 -2
  129. package/dist/memory/types.js.map +1 -1
  130. package/dist/permissions/audit.d.ts +82 -0
  131. package/dist/permissions/audit.d.ts.map +1 -0
  132. package/dist/permissions/audit.js +229 -0
  133. package/dist/permissions/audit.js.map +1 -0
  134. package/dist/permissions/index.d.ts +11 -1
  135. package/dist/permissions/index.d.ts.map +1 -1
  136. package/dist/permissions/index.js +15 -0
  137. package/dist/permissions/index.js.map +1 -1
  138. package/dist/permissions/manager.d.ts +149 -13
  139. package/dist/permissions/manager.d.ts.map +1 -1
  140. package/dist/permissions/manager.js +480 -35
  141. package/dist/permissions/manager.js.map +1 -1
  142. package/dist/permissions/manager.test.d.ts +5 -0
  143. package/dist/permissions/manager.test.d.ts.map +1 -0
  144. package/dist/permissions/manager.test.js +213 -0
  145. package/dist/permissions/manager.test.js.map +1 -0
  146. package/dist/permissions/persistence.d.ts +74 -0
  147. package/dist/permissions/persistence.d.ts.map +1 -0
  148. package/dist/permissions/persistence.js +248 -0
  149. package/dist/permissions/persistence.js.map +1 -0
  150. package/dist/permissions/persistence.test.d.ts +5 -0
  151. package/dist/permissions/persistence.test.d.ts.map +1 -0
  152. package/dist/permissions/persistence.test.js +171 -0
  153. package/dist/permissions/persistence.test.js.map +1 -0
  154. package/dist/permissions/prompt-matcher.d.ts +64 -0
  155. package/dist/permissions/prompt-matcher.d.ts.map +1 -0
  156. package/dist/permissions/prompt-matcher.js +415 -0
  157. package/dist/permissions/prompt-matcher.js.map +1 -0
  158. package/dist/permissions/prompt-matcher.test.d.ts +5 -0
  159. package/dist/permissions/prompt-matcher.test.d.ts.map +1 -0
  160. package/dist/permissions/prompt-matcher.test.js +107 -0
  161. package/dist/permissions/prompt-matcher.test.js.map +1 -0
  162. package/dist/permissions/types.d.ts +157 -0
  163. package/dist/permissions/types.d.ts.map +1 -1
  164. package/dist/permissions/types.js +43 -8
  165. package/dist/permissions/types.js.map +1 -1
  166. package/dist/prompts/index.d.ts +92 -0
  167. package/dist/prompts/index.d.ts.map +1 -0
  168. package/dist/prompts/index.js +241 -0
  169. package/dist/prompts/index.js.map +1 -0
  170. package/dist/providers/gemini.d.ts.map +1 -1
  171. package/dist/providers/gemini.js +14 -3
  172. package/dist/providers/gemini.js.map +1 -1
  173. package/dist/providers/index.d.ts +5 -3
  174. package/dist/providers/index.d.ts.map +1 -1
  175. package/dist/providers/index.js +13 -1
  176. package/dist/providers/index.js.map +1 -1
  177. package/dist/providers/registry.d.ts +66 -0
  178. package/dist/providers/registry.d.ts.map +1 -0
  179. package/dist/providers/registry.js +158 -0
  180. package/dist/providers/registry.js.map +1 -0
  181. package/dist/providers/search/brave.d.ts +14 -0
  182. package/dist/providers/search/brave.d.ts.map +1 -0
  183. package/dist/providers/search/brave.js +87 -0
  184. package/dist/providers/search/brave.js.map +1 -0
  185. package/dist/providers/search/exa.d.ts +12 -0
  186. package/dist/providers/search/exa.d.ts.map +1 -0
  187. package/dist/providers/search/exa.js +158 -0
  188. package/dist/providers/search/exa.js.map +1 -0
  189. package/dist/providers/search/index.d.ts +31 -0
  190. package/dist/providers/search/index.d.ts.map +1 -0
  191. package/dist/providers/search/index.js +75 -0
  192. package/dist/providers/search/index.js.map +1 -0
  193. package/dist/providers/search/serper.d.ts +14 -0
  194. package/dist/providers/search/serper.d.ts.map +1 -0
  195. package/dist/providers/search/serper.js +87 -0
  196. package/dist/providers/search/serper.js.map +1 -0
  197. package/dist/providers/search/types.d.ts +21 -0
  198. package/dist/providers/search/types.d.ts.map +1 -0
  199. package/dist/providers/search/types.js +5 -0
  200. package/dist/providers/search/types.js.map +1 -0
  201. package/dist/providers/store.d.ts +104 -0
  202. package/dist/providers/store.d.ts.map +1 -0
  203. package/dist/providers/store.js +171 -0
  204. package/dist/providers/store.js.map +1 -0
  205. package/dist/providers/types.d.ts +7 -1
  206. package/dist/providers/types.d.ts.map +1 -1
  207. package/dist/providers/vertex-ai.d.ts +33 -0
  208. package/dist/providers/vertex-ai.d.ts.map +1 -0
  209. package/dist/providers/vertex-ai.js +407 -0
  210. package/dist/providers/vertex-ai.js.map +1 -0
  211. package/dist/tools/builtin/bash.d.ts.map +1 -1
  212. package/dist/tools/builtin/bash.js +2 -1
  213. package/dist/tools/builtin/bash.js.map +1 -1
  214. package/dist/tools/builtin/edit.d.ts.map +1 -1
  215. package/dist/tools/builtin/edit.js +2 -1
  216. package/dist/tools/builtin/edit.js.map +1 -1
  217. package/dist/tools/builtin/glob.d.ts.map +1 -1
  218. package/dist/tools/builtin/glob.js +2 -1
  219. package/dist/tools/builtin/glob.js.map +1 -1
  220. package/dist/tools/builtin/grep.d.ts.map +1 -1
  221. package/dist/tools/builtin/grep.js +2 -1
  222. package/dist/tools/builtin/grep.js.map +1 -1
  223. package/dist/tools/builtin/read.d.ts.map +1 -1
  224. package/dist/tools/builtin/read.js +2 -1
  225. package/dist/tools/builtin/read.js.map +1 -1
  226. package/dist/tools/builtin/todowrite.d.ts +15 -0
  227. package/dist/tools/builtin/todowrite.d.ts.map +1 -0
  228. package/dist/tools/builtin/todowrite.js +88 -0
  229. package/dist/tools/builtin/todowrite.js.map +1 -0
  230. package/dist/tools/builtin/webfetch.d.ts +20 -0
  231. package/dist/tools/builtin/webfetch.d.ts.map +1 -0
  232. package/dist/tools/builtin/webfetch.js +228 -0
  233. package/dist/tools/builtin/webfetch.js.map +1 -0
  234. package/dist/tools/builtin/websearch.d.ts +17 -0
  235. package/dist/tools/builtin/websearch.d.ts.map +1 -0
  236. package/dist/tools/builtin/websearch.js +87 -0
  237. package/dist/tools/builtin/websearch.js.map +1 -0
  238. package/dist/tools/builtin/write.d.ts.map +1 -1
  239. package/dist/tools/builtin/write.js +2 -1
  240. package/dist/tools/builtin/write.js.map +1 -1
  241. package/dist/tools/index.d.ts +18 -0
  242. package/dist/tools/index.d.ts.map +1 -1
  243. package/dist/tools/index.js +28 -2
  244. package/dist/tools/index.js.map +1 -1
  245. package/dist/tools/types.d.ts +41 -0
  246. package/dist/tools/types.d.ts.map +1 -1
  247. package/dist/tools/types.js +16 -0
  248. package/dist/tools/types.js.map +1 -1
  249. package/dist/tools/utils/ssrf.d.ts +18 -0
  250. package/dist/tools/utils/ssrf.d.ts.map +1 -0
  251. package/dist/tools/utils/ssrf.js +70 -0
  252. package/dist/tools/utils/ssrf.js.map +1 -0
  253. package/docs/README.md +5 -4
  254. package/docs/config-system-comparison.md +707 -0
  255. package/docs/memory-system.md +238 -0
  256. package/docs/permissions.md +368 -0
  257. package/docs/proposals/0001-web-fetch-tool.md +32 -2
  258. package/docs/proposals/0002-web-search-tool.md +59 -2
  259. package/docs/proposals/0005-todo-system.md +350 -85
  260. package/docs/proposals/0006-memory-system.md +11 -10
  261. package/docs/proposals/0012-ask-user-question.md +941 -206
  262. package/docs/proposals/0023-permission-enhancements.md +61 -2
  263. package/docs/proposals/0041-configuration-system.md +587 -0
  264. package/docs/proposals/0042-prompt-optimization.md +866 -0
  265. package/docs/proposals/README.md +8 -6
  266. package/docs/providers.md +220 -0
  267. package/jest.config.js +26 -0
  268. package/package.json +14 -3
  269. package/src/agent/agent.ts +120 -18
  270. package/src/agent/types.ts +9 -1
  271. package/src/cli/components/App.tsx +369 -47
  272. package/src/cli/components/CommandSuggestions.tsx +3 -0
  273. package/src/cli/components/Header.tsx +11 -17
  274. package/src/cli/components/Logo.tsx +76 -9
  275. package/src/cli/components/Messages.tsx +146 -38
  276. package/src/cli/components/ModelSelector.tsx +169 -52
  277. package/src/cli/components/PermissionPrompt.tsx +388 -0
  278. package/src/cli/components/ProviderManager.tsx +534 -0
  279. package/src/cli/components/Spinner.tsx +138 -25
  280. package/src/cli/components/TodoList.tsx +54 -0
  281. package/src/cli/components/index.ts +6 -0
  282. package/src/cli/components/markdown.ts +157 -0
  283. package/src/cli/components/theme.ts +7 -0
  284. package/src/cli/index.tsx +76 -13
  285. package/src/config/index.ts +79 -4
  286. package/src/config/levels.test.ts +163 -0
  287. package/src/config/levels.ts +285 -0
  288. package/src/config/loader.test.ts +120 -0
  289. package/src/config/loader.ts +178 -0
  290. package/src/config/manager.test.ts +215 -0
  291. package/src/config/manager.ts +328 -40
  292. package/src/config/merger.test.ts +360 -0
  293. package/src/config/merger.ts +221 -0
  294. package/src/config/providers-config.ts +85 -0
  295. package/src/config/test-utils.ts +79 -0
  296. package/src/config/types.ts +186 -9
  297. package/src/memory/import-resolver.test.ts +117 -0
  298. package/src/memory/import-resolver.ts +149 -0
  299. package/src/memory/index.ts +11 -0
  300. package/src/memory/init-prompt.ts +113 -0
  301. package/src/memory/memory-manager.test.ts +198 -0
  302. package/src/memory/memory-manager.ts +716 -0
  303. package/src/memory/rules-parser.test.ts +182 -0
  304. package/src/memory/rules-parser.ts +82 -0
  305. package/src/memory/test-utils.ts +60 -0
  306. package/src/memory/types.ts +119 -0
  307. package/src/permissions/audit.ts +284 -0
  308. package/src/permissions/index.ts +20 -1
  309. package/src/permissions/manager.test.ts +260 -0
  310. package/src/permissions/manager.ts +592 -40
  311. package/src/permissions/persistence.test.ts +220 -0
  312. package/src/permissions/persistence.ts +301 -0
  313. package/src/permissions/prompt-matcher.test.ts +213 -0
  314. package/src/permissions/prompt-matcher.ts +472 -0
  315. package/src/permissions/types.ts +236 -8
  316. package/src/prompts/index.test.ts +279 -0
  317. package/src/prompts/index.ts +306 -0
  318. package/src/prompts/system/anthropic.txt +29 -0
  319. package/src/prompts/system/base.txt +124 -0
  320. package/src/prompts/system/gemini.txt +35 -0
  321. package/src/prompts/system/generic.txt +128 -0
  322. package/src/prompts/system/openai.txt +29 -0
  323. package/src/prompts/tools/bash.txt +60 -0
  324. package/src/prompts/tools/edit.txt +29 -0
  325. package/src/prompts/tools/glob.txt +35 -0
  326. package/src/prompts/tools/grep.txt +43 -0
  327. package/src/prompts/tools/read.txt +22 -0
  328. package/src/prompts/tools/todowrite.txt +71 -0
  329. package/src/prompts/tools/webfetch.txt +34 -0
  330. package/src/prompts/tools/websearch.txt +41 -0
  331. package/src/prompts/tools/write.txt +23 -0
  332. package/src/providers/gemini.ts +20 -4
  333. package/src/providers/index.ts +18 -3
  334. package/src/providers/registry.ts +198 -0
  335. package/src/providers/search/brave.ts +132 -0
  336. package/src/providers/search/exa.ts +217 -0
  337. package/src/providers/search/index.ts +79 -0
  338. package/src/providers/search/serper.ts +133 -0
  339. package/src/providers/search/types.ts +24 -0
  340. package/src/providers/store.ts +216 -0
  341. package/src/providers/types.ts +9 -1
  342. package/src/providers/vertex-ai.ts +594 -0
  343. package/src/tools/builtin/bash.ts +2 -1
  344. package/src/tools/builtin/edit.ts +2 -1
  345. package/src/tools/builtin/glob.ts +2 -1
  346. package/src/tools/builtin/grep.ts +2 -1
  347. package/src/tools/builtin/read.ts +2 -1
  348. package/src/tools/builtin/todowrite.ts +102 -0
  349. package/src/tools/builtin/webfetch.ts +261 -0
  350. package/src/tools/builtin/websearch.ts +103 -0
  351. package/src/tools/builtin/write.ts +2 -1
  352. package/src/tools/index.ts +28 -2
  353. package/src/tools/types.ts +32 -0
  354. package/src/tools/utils/ssrf.ts +79 -0
  355. package/tsconfig.json +1 -1
  356. package/CLAUDE.md +0 -70
@@ -2,9 +2,10 @@
2
2
 
3
3
  - **Proposal ID**: 0023
4
4
  - **Author**: mycode team
5
- - **Status**: Draft
5
+ - **Status**: Implemented
6
6
  - **Created**: 2025-01-15
7
- - **Updated**: 2025-01-15
7
+ - **Updated**: 2026-01-15
8
+ - **Implemented**: 2026-01-15
8
9
 
9
10
  ## Summary
10
11
 
@@ -463,6 +464,64 @@ Only allow explicitly approved operations.
463
464
 
464
465
  Backward compatible with existing rules.
465
466
 
467
+ ## Implementation Notes
468
+
469
+ ### Files Created/Modified
470
+
471
+ | File | Action | Description |
472
+ |------|--------|-------------|
473
+ | `src/permissions/types.ts` | Modified | Enhanced types with ApprovalAction, PromptPermission, audit types, persistence types |
474
+ | `src/permissions/manager.ts` | Modified | Enhanced PermissionManager with pattern matching, prompt matching, persistence, audit |
475
+ | `src/permissions/prompt-matcher.ts` | Created | Semantic prompt matching for Claude Code style permissions |
476
+ | `src/permissions/persistence.ts` | Created | Persistence layer for storing rules to disk |
477
+ | `src/permissions/audit.ts` | Created | Audit logging for permission decisions |
478
+ | `src/permissions/index.ts` | Modified | Export all new modules |
479
+ | `src/cli/components/PermissionPrompt.tsx` | Created | Enhanced permission prompt UI with approval options |
480
+ | `src/cli/components/CommandSuggestions.tsx` | Modified | Added /permissions command |
481
+ | `src/cli/components/App.tsx` | Modified | Integrated permission system, added /permissions command |
482
+ | `src/cli/components/index.ts` | Modified | Export new components |
483
+ | `src/cli/index.tsx` | Modified | Pass permission settings to App |
484
+ | `src/agent/agent.ts` | Modified | Enhanced permission integration with new API |
485
+
486
+ ### Key Implementation Details
487
+
488
+ 1. **Pattern-Based Rules**: Supports Claude Code format like `Bash(git add:*)` with glob-style wildcards
489
+ 2. **Prompt-Based Permissions**: ExitPlanMode style with semantic matching for common operations (run tests, install dependencies, etc.)
490
+ 3. **Multi-Scope Permissions**: Session (in-memory), Project (.gencode/permissions.json), Global (~/.gencode/permissions.json)
491
+ 4. **Approval Options**: Allow once, Allow for session, Always allow (persistent), Deny
492
+ 5. **Audit Logging**: In-memory audit trail with optional file persistence
493
+ 6. **CLI Commands**: `/permissions` shows rules, `/permissions audit` shows decision history, `/permissions stats` shows statistics
494
+
495
+ ### Usage Examples
496
+
497
+ ```bash
498
+ # View current permission rules
499
+ /permissions
500
+
501
+ # View audit log
502
+ /permissions audit
503
+
504
+ # View statistics
505
+ /permissions stats
506
+ ```
507
+
508
+ ### Settings Configuration
509
+
510
+ Add to `~/.gencode/settings.json`:
511
+ ```json
512
+ {
513
+ "permissions": {
514
+ "allow": [
515
+ "Bash(git add:*)",
516
+ "Bash(npm install:*)"
517
+ ],
518
+ "deny": [
519
+ "Bash(rm -rf:*)"
520
+ ]
521
+ }
522
+ }
523
+ ```
524
+
466
525
  ## References
467
526
 
468
527
  - [Claude Code Permission System](https://code.claude.com/docs/en/permissions)
@@ -0,0 +1,587 @@
1
+ # Proposal: Configuration System
2
+
3
+ - **Proposal ID**: 0041
4
+ - **Author**: gencode team
5
+ - **Status**: Implemented
6
+ - **Created**: 2026-01-15
7
+ - **Updated**: 2026-01-16
8
+ - **Implemented**: 2026-01-16
9
+
10
+ ## Summary
11
+
12
+ Implement a comprehensive configuration system for gencode, supporting multi-level configuration loading (user and project level), environment variable handling, permission management, and configuration merging. This design draws from both Claude Code's `~/.claude/` directory structure and OpenCode's configuration patterns.
13
+
14
+ ## Motivation
15
+
16
+ A robust configuration system is essential for:
17
+
18
+ 1. **Personalization**: Users need to customize behavior, model selection, and permissions
19
+ 2. **Project-specific settings**: Different projects may require different configurations
20
+ 3. **Team collaboration**: Shared project settings can be version controlled
21
+ 4. **Security**: Sensitive local settings should be gitignored while shared settings remain portable
22
+ 5. **Provider flexibility**: gencode's multi-provider architecture needs clean configuration for API keys and provider selection
23
+
24
+ ## Claude Code Reference
25
+
26
+ ### Configuration File Hierarchy
27
+
28
+ Claude Code uses a layered configuration system with the following priority (high to low):
29
+
30
+ | Level | Location | Purpose | Git Tracked |
31
+ |-------|----------|---------|-------------|
32
+ | 1 | `~/.claude.json` | Legacy main config | No |
33
+ | 2 | `~/.claude/settings.json` | User global settings | No |
34
+ | 3 | `~/.claude/settings.local.json` | User local settings | No |
35
+ | 4 | `.claude/settings.json` | Project shared settings | Yes |
36
+ | 5 | `.claude/settings.local.json` | Project personal settings | No (gitignored) |
37
+ | 6 | `.mcp.json` | Project MCP servers | Yes |
38
+
39
+ ### Environment Variables
40
+
41
+ Claude Code supports extensive environment variables:
42
+
43
+ **Authentication & API:**
44
+ - `ANTHROPIC_API_KEY` - Primary API key
45
+ - `ANTHROPIC_AUTH_TOKEN` - Alternative token
46
+ - `ANTHROPIC_BASE_URL` - Custom API endpoint
47
+ - `ANTHROPIC_MODEL` - Default model selection
48
+ - `ANTHROPIC_SMALL_FAST_MODEL` - Fast model for quick operations
49
+
50
+ **Cloud Providers:**
51
+ - `CLAUDE_CODE_USE_BEDROCK` - Enable AWS Bedrock
52
+ - `CLAUDE_CODE_USE_VERTEX` - Enable Google Vertex AI
53
+ - `CLAUDE_CODE_SKIP_BEDROCK_AUTH` - Bypass AWS auth
54
+ - `CLAUDE_CODE_SKIP_VERTEX_AUTH` - Bypass Vertex auth
55
+
56
+ **Operational:**
57
+ - `CLAUDE_CODE_MAX_OUTPUT_TOKENS` - Token limit
58
+ - `CLAUDE_CODE_ACTION` - Permission mode (acceptEdits, plan, bypassPermissions)
59
+ - `FORCE_CODE_TERMINAL` - Force CLI mode
60
+
61
+ **Debugging:**
62
+ - `DEBUG` - Verbose logging
63
+ - `DISABLE_ERROR_REPORTING` - No error submission
64
+ - `DISABLE_TELEMETRY` - No usage tracking
65
+
66
+ ### settings.json Structure
67
+
68
+ ```json
69
+ {
70
+ "projects": {
71
+ "/path/to/project": {
72
+ "mcpServers": { },
73
+ "allowedTools": [ ]
74
+ }
75
+ },
76
+ "permissions": {
77
+ "allow": ["Bash(npm:*)", "Read(/path/**)"],
78
+ "deny": ["Read(./.env)"]
79
+ },
80
+ "model": "claude-opus-4-5-20251101",
81
+ "spinnerTipsEnabled": false,
82
+ "attribution": {
83
+ "commits": true,
84
+ "pullRequests": true
85
+ },
86
+ "mcpServers": { },
87
+ "enableAllProjectMcpServers": true
88
+ }
89
+ ```
90
+
91
+ ### Tool Permission Patterns
92
+
93
+ - `Bash(git log:*)` - Git commands
94
+ - `Bash(npm run:*)` - NPM scripts
95
+ - `Read(/path/**)` - File patterns with globs
96
+ - `WebFetch(domain:github.com)` - Domain restrictions
97
+ - Tool names: `Task`, `Glob`, `Grep`, `LS`, `Edit`, `MultiEdit`, `Write`, `WebSearch`
98
+
99
+ ## OpenCode Reference
100
+
101
+ OpenCode provides additional patterns worth adopting:
102
+
103
+ ### Configuration Loading Order (Low → High Priority)
104
+
105
+ 1. Remote config (`.well-known/opencode`)
106
+ 2. Global config (`~/.config/opencode/opencode.json`)
107
+ 3. `OPENCODE_CONFIG` env var file
108
+ 4. Project config (`opencode.json`)
109
+ 5. `OPENCODE_CONFIG_CONTENT` inline JSON
110
+
111
+ ### Key Features
112
+
113
+ - **JSON/JSONC support**: Comments and trailing commas allowed
114
+ - **Environment variable substitution**: `{env:VARIABLE_NAME}` syntax
115
+ - **File content inclusion**: `{file:path/to/file}` syntax
116
+ - **Deep merge**: Arrays concatenate rather than replace
117
+ - **Zod schema validation**: Runtime type checking
118
+
119
+ ## Detailed Design
120
+
121
+ ### Directory Structure
122
+
123
+ ```
124
+ ~/.gencode/ # User-level configuration
125
+ ├── settings.json # Main user config
126
+ ├── settings.local.json # User local overrides (gitignored pattern)
127
+ ├── GENCODE.md # User context (like CLAUDE.md)
128
+ ├── commands/ # Custom slash commands
129
+ ├── skills/ # Custom skills
130
+ ├── agents/ # Custom subagents
131
+ ├── plugins/ # Plugin management
132
+ │ ├── marketplaces.json
133
+ │ └── installed.json
134
+ ├── hooks/ # Event hooks
135
+ └── sessions/ # Session data
136
+
137
+ ./gencode.json # Project config (like opencode.json)
138
+ ./.gencode/ # Project directory
139
+ ├── settings.local.json # Project local overrides (gitignored)
140
+ ├── GENCODE.md # Project context
141
+ ├── rules/ # Path-scoped rules
142
+ └── skills/ # Project-specific skills
143
+ ```
144
+
145
+ ### Configuration Priority (High → Low)
146
+
147
+ 1. **Environment variables** (`GENCODE_*`, provider API keys)
148
+ 2. **CLI arguments** (`--model`, `--provider`)
149
+ 3. **Project local** (`./.gencode/settings.local.json`)
150
+ 4. **Project shared** (`./gencode.json`)
151
+ 5. **User local** (`~/.gencode/settings.local.json`)
152
+ 6. **User global** (`~/.gencode/settings.json`)
153
+ 7. **Defaults**
154
+
155
+ ### API Design
156
+
157
+ ```typescript
158
+ // src/config/types.ts
159
+ interface GencodeConfig {
160
+ // Provider configuration
161
+ provider?: 'anthropic' | 'openai' | 'gemini' | 'bedrock' | 'vertex';
162
+ model?: string;
163
+
164
+ // Permission system
165
+ permissions?: {
166
+ allow?: string[]; // e.g., ["Bash(npm:*)", "Read(**/src/**)"]
167
+ deny?: string[]; // e.g., ["Read(.env)", "Bash(rm -rf:*)"]
168
+ };
169
+
170
+ // Environment variables to inject
171
+ env?: Record<string, string>;
172
+
173
+ // Hook definitions
174
+ hooks?: {
175
+ preToolUse?: HookConfig[];
176
+ postToolUse?: HookConfig[];
177
+ notification?: HookConfig[];
178
+ };
179
+
180
+ // MCP server configuration
181
+ mcpServers?: Record<string, McpServerConfig>;
182
+
183
+ // Plugin enablement
184
+ enabledPlugins?: string[];
185
+
186
+ // UI preferences
187
+ theme?: 'dark' | 'light' | 'auto';
188
+ spinnerTipsEnabled?: boolean;
189
+
190
+ // Attribution settings
191
+ attribution?: {
192
+ commits?: boolean;
193
+ pullRequests?: boolean;
194
+ };
195
+ }
196
+
197
+ interface HookConfig {
198
+ tool?: string;
199
+ command: string;
200
+ timeout?: number;
201
+ }
202
+
203
+ interface McpServerConfig {
204
+ command: string;
205
+ args?: string[];
206
+ env?: Record<string, string>;
207
+ }
208
+
209
+ // src/config/loader.ts
210
+ interface ConfigLoader {
211
+ load(): Promise<GencodeConfig>;
212
+ getUserConfig(): Promise<GencodeConfig>;
213
+ getProjectConfig(): Promise<GencodeConfig>;
214
+ getEffectiveConfig(): Promise<GencodeConfig>;
215
+ watch(callback: (config: GencodeConfig) => void): void;
216
+ }
217
+
218
+ // src/config/env.ts
219
+ interface EnvHandler {
220
+ getProviderFromEnv(): string | undefined;
221
+ getModelFromEnv(): string | undefined;
222
+ getApiKey(provider: string): string | undefined;
223
+ substituteEnvVars(value: string): string;
224
+ }
225
+ ```
226
+
227
+ ### Environment Variables
228
+
229
+ **Provider Selection:**
230
+ - `GENCODE_PROVIDER` - Provider name (anthropic, openai, gemini, bedrock, vertex)
231
+ - `GENCODE_MODEL` - Model ID
232
+ - `GENCODE_CONFIG` - Custom config file path
233
+
234
+ **Provider API Keys (Auto-detect):**
235
+ - `ANTHROPIC_API_KEY`
236
+ - `OPENAI_API_KEY`
237
+ - `GOOGLE_API_KEY`
238
+ - `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` (for Bedrock)
239
+
240
+ **Operational:**
241
+ - `GENCODE_MAX_OUTPUT_TOKENS` - Token limit
242
+ - `GENCODE_DISABLE_TELEMETRY` - Disable tracking
243
+ - `GENCODE_DEBUG` - Debug mode
244
+ - `HTTP_PROXY` / `HTTPS_PROXY` - Network proxy
245
+
246
+ ### settings.json Schema
247
+
248
+ ```json
249
+ {
250
+ "$schema": "https://gencode.dev/settings.schema.json",
251
+ "provider": "anthropic",
252
+ "model": "claude-sonnet-4",
253
+ "permissions": {
254
+ "allow": ["Bash(npm:*)", "Read(**/src/**)"],
255
+ "deny": ["Read(.env)", "Bash(rm -rf:*)"]
256
+ },
257
+ "env": {
258
+ "CUSTOM_VAR": "value",
259
+ "API_URL": "{env:BASE_API_URL}/v1"
260
+ },
261
+ "hooks": {
262
+ "postToolUse": [
263
+ { "tool": "Write", "command": "make fmt" }
264
+ ]
265
+ },
266
+ "mcpServers": {
267
+ "memory": {
268
+ "command": "npx",
269
+ "args": ["@modelcontextprotocol/server-memory"]
270
+ }
271
+ },
272
+ "enabledPlugins": ["git@official", "jira@community"],
273
+ "theme": "dark",
274
+ "spinnerTipsEnabled": true,
275
+ "attribution": {
276
+ "commits": true,
277
+ "pullRequests": true
278
+ }
279
+ }
280
+ ```
281
+
282
+ ### Implementation Approach
283
+
284
+ #### Phase 1: Core Config Loading
285
+
286
+ ```typescript
287
+ // src/config/loader.ts
288
+ import { parse as parseJsonc } from 'jsonc-parser';
289
+ import { findUp } from 'find-up';
290
+ import { z } from 'zod';
291
+
292
+ const ConfigSchema = z.object({
293
+ provider: z.enum(['anthropic', 'openai', 'gemini', 'bedrock', 'vertex']).optional(),
294
+ model: z.string().optional(),
295
+ permissions: z.object({
296
+ allow: z.array(z.string()).optional(),
297
+ deny: z.array(z.string()).optional(),
298
+ }).optional(),
299
+ // ... rest of schema
300
+ });
301
+
302
+ export class ConfigLoader {
303
+ private userConfigDir = path.join(os.homedir(), '.gencode');
304
+
305
+ async load(): Promise<GencodeConfig> {
306
+ const configs = await Promise.all([
307
+ this.loadDefaults(),
308
+ this.loadUserGlobal(),
309
+ this.loadUserLocal(),
310
+ this.loadProjectShared(),
311
+ this.loadProjectLocal(),
312
+ ]);
313
+
314
+ return this.deepMerge(...configs);
315
+ }
316
+
317
+ private async loadFile(filePath: string): Promise<Partial<GencodeConfig>> {
318
+ try {
319
+ const content = await fs.readFile(filePath, 'utf-8');
320
+ const parsed = parseJsonc(content); // Supports comments
321
+ return ConfigSchema.partial().parse(parsed);
322
+ } catch {
323
+ return {};
324
+ }
325
+ }
326
+
327
+ private deepMerge(...configs: Partial<GencodeConfig>[]): GencodeConfig {
328
+ // Arrays concatenate, objects merge recursively
329
+ return configs.reduce((acc, config) => {
330
+ return mergeWith(acc, config, (objValue, srcValue) => {
331
+ if (Array.isArray(objValue) && Array.isArray(srcValue)) {
332
+ return [...objValue, ...srcValue]; // Concatenate arrays
333
+ }
334
+ });
335
+ }, {} as GencodeConfig);
336
+ }
337
+ }
338
+ ```
339
+
340
+ #### Phase 2: Environment Variable Handling
341
+
342
+ ```typescript
343
+ // src/config/env.ts
344
+ export class EnvHandler {
345
+ private readonly providerKeyMap: Record<string, string> = {
346
+ anthropic: 'ANTHROPIC_API_KEY',
347
+ openai: 'OPENAI_API_KEY',
348
+ gemini: 'GOOGLE_API_KEY',
349
+ };
350
+
351
+ getProviderFromEnv(): string | undefined {
352
+ return process.env.GENCODE_PROVIDER;
353
+ }
354
+
355
+ getApiKey(provider: string): string | undefined {
356
+ const envKey = this.providerKeyMap[provider];
357
+ return envKey ? process.env[envKey] : undefined;
358
+ }
359
+
360
+ // Substitute {env:VAR} patterns
361
+ substituteEnvVars(value: string): string {
362
+ return value.replace(/\{env:(\w+)\}/g, (_, varName) => {
363
+ return process.env[varName] || '';
364
+ });
365
+ }
366
+
367
+ autoDetectProvider(): string | undefined {
368
+ for (const [provider, key] of Object.entries(this.providerKeyMap)) {
369
+ if (process.env[key]) {
370
+ return provider;
371
+ }
372
+ }
373
+ return undefined;
374
+ }
375
+ }
376
+ ```
377
+
378
+ #### Phase 3: Permission Matching
379
+
380
+ ```typescript
381
+ // src/config/permissions.ts
382
+ import { minimatch } from 'minimatch';
383
+
384
+ export class PermissionMatcher {
385
+ constructor(private config: GencodeConfig) {}
386
+
387
+ isAllowed(tool: string, args: string): boolean {
388
+ const permission = `${tool}(${args})`;
389
+
390
+ // Check deny list first
391
+ for (const pattern of this.config.permissions?.deny || []) {
392
+ if (this.matchPermission(permission, pattern)) {
393
+ return false;
394
+ }
395
+ }
396
+
397
+ // Check allow list
398
+ for (const pattern of this.config.permissions?.allow || []) {
399
+ if (this.matchPermission(permission, pattern)) {
400
+ return true;
401
+ }
402
+ }
403
+
404
+ return false; // Default deny
405
+ }
406
+
407
+ private matchPermission(permission: string, pattern: string): boolean {
408
+ // Parse pattern: Tool(arg:pattern)
409
+ const match = pattern.match(/^(\w+)\((.+)\)$/);
410
+ if (!match) return false;
411
+
412
+ const [, toolPattern, argPattern] = match;
413
+ const [tool, arg] = permission.match(/^(\w+)\((.+)\)$/)?.slice(1) || [];
414
+
415
+ if (toolPattern !== tool && toolPattern !== '*') return false;
416
+ return minimatch(arg, argPattern);
417
+ }
418
+ }
419
+ ```
420
+
421
+ ### File Changes
422
+
423
+ | File | Action | Description |
424
+ |------|--------|-------------|
425
+ | `src/config/types.ts` | Create | Configuration type definitions |
426
+ | `src/config/loader.ts` | Create | Multi-level config loading |
427
+ | `src/config/env.ts` | Create | Environment variable handling |
428
+ | `src/config/permissions.ts` | Create | Permission pattern matching |
429
+ | `src/config/index.ts` | Create | Public API exports |
430
+ | `src/agent/agent.ts` | Modify | Integrate config system |
431
+ | `src/cli/index.ts` | Modify | Add --config CLI flag |
432
+ | `schemas/settings.schema.json` | Create | JSON Schema for validation |
433
+
434
+ ## User Experience
435
+
436
+ ### First-time Setup
437
+
438
+ ```bash
439
+ # gencode auto-detects provider from API keys
440
+ $ export OPENAI_API_KEY=sk-...
441
+ $ gencode
442
+ # Uses OpenAI automatically
443
+
444
+ # Or specify explicitly
445
+ $ export GENCODE_PROVIDER=anthropic
446
+ $ export ANTHROPIC_API_KEY=sk-ant-...
447
+ $ gencode
448
+ ```
449
+
450
+ ### Project Configuration
451
+
452
+ ```bash
453
+ # Initialize project config
454
+ $ gencode init
455
+ # Creates ./gencode.json with sensible defaults
456
+
457
+ # View effective configuration
458
+ $ gencode config
459
+ # Shows merged configuration from all sources
460
+
461
+ # Set project-specific model
462
+ $ gencode config set model claude-sonnet-4
463
+ # Updates ./gencode.json
464
+ ```
465
+
466
+ ### Permission Management
467
+
468
+ ```bash
469
+ # View current permissions
470
+ $ gencode /permissions
471
+
472
+ # Allow npm commands for this project
473
+ $ gencode config allow "Bash(npm:*)"
474
+
475
+ # Deny reading .env files
476
+ $ gencode config deny "Read(.env)"
477
+ ```
478
+
479
+ ## Alternatives Considered
480
+
481
+ ### Single Config File
482
+
483
+ A single `~/.gencoderc` file would be simpler but lacks:
484
+ - Project-specific overrides
485
+ - Team-shareable settings
486
+ - Local-only sensitive settings
487
+
488
+ ### YAML Configuration
489
+
490
+ YAML is more readable but:
491
+ - JSON has better tooling support
492
+ - JSONC provides comments without complexity
493
+ - Matches Claude Code and OpenCode patterns
494
+
495
+ ### No Environment Variable Substitution
496
+
497
+ Simpler implementation but:
498
+ - Forces duplication of values
499
+ - Makes CI/CD integration harder
500
+ - Loses flexibility for sensitive values
501
+
502
+ ## Security Considerations
503
+
504
+ 1. **API Key Handling**: Never log or expose API keys; load from environment only
505
+ 2. **Local Settings**: `settings.local.json` files should be gitignored
506
+ 3. **Permission Defaults**: Default to deny; require explicit allow
507
+ 4. **File Permissions**: Config files should be user-readable only (0600)
508
+ 5. **Command Injection**: Validate hook commands; sanitize environment variable substitution
509
+
510
+ ## Testing Strategy
511
+
512
+ 1. **Unit Tests**:
513
+ - Config loading from multiple sources
514
+ - Deep merge behavior (especially arrays)
515
+ - Environment variable substitution
516
+ - Permission pattern matching
517
+
518
+ 2. **Integration Tests**:
519
+ - Full config resolution with mock file system
520
+ - CLI flag override behavior
521
+ - Provider auto-detection
522
+
523
+ 3. **E2E Tests**:
524
+ - `gencode config` commands
525
+ - Permission enforcement during tool execution
526
+
527
+ ## Migration Path
528
+
529
+ 1. **From mycode**: Migrate `~/.mycode/` to `~/.gencode/`
530
+ 2. **Version Detection**: Check for legacy config locations and prompt migration
531
+ 3. **Backward Compatibility**: Support reading old config format for one major version
532
+
533
+ ## Dependencies
534
+
535
+ - [find-up](https://www.npmjs.com/package/find-up) - Directory traversal
536
+ - [jsonc-parser](https://www.npmjs.com/package/jsonc-parser) - JSON with comments
537
+ - [minimatch](https://www.npmjs.com/package/minimatch) - Glob pattern matching
538
+ - [zod](https://www.npmjs.com/package/zod) - Schema validation (already used)
539
+ - [lodash.mergewith](https://www.npmjs.com/package/lodash.mergewith) - Deep merge
540
+
541
+ ## Related Proposals
542
+
543
+ | Proposal | Relationship |
544
+ |----------|--------------|
545
+ | [0006 Memory System](./0006-memory-system.md) | GENCODE.md is stored in config directories |
546
+ | [0009 Hooks System](./0009-hooks-system.md) | Hook definitions stored in settings.json |
547
+ | [0022 Plugin System](./0022-plugin-system.md) | Plugin enablement configured in settings |
548
+ | [0023 Permission Enhancements](./0023-permission-enhancements.md) | Permission patterns defined in settings |
549
+
550
+ ## References
551
+
552
+ - [Claude Code Settings - Official Docs](https://code.claude.com/docs/en/settings)
553
+ - [Claude Code Configuration Guide | ClaudeLog](https://claudelog.com/configuration/)
554
+ - [Claude Code CLI Environment Variables](https://gist.github.com/unkn0wncode/f87295d055dd0f0e8082358a0b5cc467)
555
+ - [settings.json in Claude Code Guide](https://www.eesel.ai/blog/settings-json-claude-code)
556
+ - [OpenCode Config Docs](https://opencode.ai/docs/config/)
557
+ - [OpenCode Configuration System | DeepWiki](https://deepwiki.com/sst/opencode/3-configuration-system)
558
+
559
+ ## Implementation Notes
560
+
561
+ ### Files Created/Modified
562
+
563
+ | File | Action | Description |
564
+ |------|--------|-------------|
565
+ | `src/config/types.ts` | Created | Configuration type definitions with Zod schemas |
566
+ | `src/config/loader.ts` | Created | Multi-level config loading with deep merge |
567
+ | `src/config/env.ts` | Created | Environment variable handling and provider auto-detection |
568
+ | `src/config/index.ts` | Created | Public API exports |
569
+ | `src/agent/agent.ts` | Modified | Integrated config system |
570
+
571
+ ### Key Implementation Details
572
+
573
+ 1. **Multi-level Loading**: User (`~/.gencode/`) → Project (`./.gencode/`) with proper merge
574
+ 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
576
+ 4. **Deep Merge**: Arrays concatenate, objects merge recursively
577
+ 5. **JSONC Support**: Configuration files support comments and trailing commas
578
+
579
+ ### Configuration Priority (High → Low)
580
+
581
+ 1. Environment variables (`GENCODE_*`)
582
+ 2. CLI arguments
583
+ 3. Project local (`./.gencode/settings.local.json`)
584
+ 4. Project shared (`./gencode.json`)
585
+ 5. User local (`~/.gencode/settings.local.json`)
586
+ 6. User global (`~/.gencode/settings.json`)
587
+ 7. Defaults