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.
- package/.gencode/settings.local.json +7 -0
- package/README.md +20 -102
- package/dist/agent/agent.d.ts +43 -2
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +90 -17
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/types.d.ts +9 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/components/AllModelsSelector.d.ts +11 -0
- package/dist/cli/components/AllModelsSelector.d.ts.map +1 -0
- package/dist/cli/components/AllModelsSelector.js +153 -0
- package/dist/cli/components/AllModelsSelector.js.map +1 -0
- package/dist/cli/components/App.d.ts +8 -1
- package/dist/cli/components/App.d.ts.map +1 -1
- package/dist/cli/components/App.js +276 -40
- package/dist/cli/components/App.js.map +1 -1
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
- package/dist/cli/components/CommandSuggestions.js +3 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -1
- package/dist/cli/components/Header.d.ts +1 -1
- package/dist/cli/components/Header.d.ts.map +1 -1
- package/dist/cli/components/Header.js +4 -6
- package/dist/cli/components/Header.js.map +1 -1
- package/dist/cli/components/Logo.d.ts +1 -0
- package/dist/cli/components/Logo.d.ts.map +1 -1
- package/dist/cli/components/Logo.js +16 -3
- package/dist/cli/components/Logo.js.map +1 -1
- package/dist/cli/components/Messages.d.ts +17 -3
- package/dist/cli/components/Messages.d.ts.map +1 -1
- package/dist/cli/components/Messages.js +70 -18
- package/dist/cli/components/Messages.js.map +1 -1
- package/dist/cli/components/ModelSelector.d.ts +7 -7
- package/dist/cli/components/ModelSelector.d.ts.map +1 -1
- package/dist/cli/components/ModelSelector.js +116 -33
- package/dist/cli/components/ModelSelector.js.map +1 -1
- package/dist/cli/components/PermissionPrompt.d.ts +60 -0
- package/dist/cli/components/PermissionPrompt.d.ts.map +1 -0
- package/dist/cli/components/PermissionPrompt.js +192 -0
- package/dist/cli/components/PermissionPrompt.js.map +1 -0
- package/dist/cli/components/ProviderManager.d.ts +8 -0
- package/dist/cli/components/ProviderManager.d.ts.map +1 -0
- package/dist/cli/components/ProviderManager.js +280 -0
- package/dist/cli/components/ProviderManager.js.map +1 -0
- package/dist/cli/components/Spinner.d.ts +7 -2
- package/dist/cli/components/Spinner.d.ts.map +1 -1
- package/dist/cli/components/Spinner.js +116 -25
- package/dist/cli/components/Spinner.js.map +1 -1
- package/dist/cli/components/TodoList.d.ts +7 -0
- package/dist/cli/components/TodoList.d.ts.map +1 -0
- package/dist/cli/components/TodoList.js +34 -0
- package/dist/cli/components/TodoList.js.map +1 -0
- package/dist/cli/components/index.d.ts +1 -0
- package/dist/cli/components/index.d.ts.map +1 -1
- package/dist/cli/components/index.js +1 -0
- package/dist/cli/components/index.js.map +1 -1
- package/dist/cli/components/markdown.d.ts +9 -0
- package/dist/cli/components/markdown.d.ts.map +1 -0
- package/dist/cli/components/markdown.js +129 -0
- package/dist/cli/components/markdown.js.map +1 -0
- package/dist/cli/components/theme.d.ts +5 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +7 -0
- package/dist/cli/components/theme.js.map +1 -1
- package/dist/cli/index.js +66 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +14 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +19 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config/levels.d.ts +49 -0
- package/dist/config/levels.d.ts.map +1 -0
- package/dist/config/levels.js +222 -0
- package/dist/config/levels.js.map +1 -0
- package/dist/config/loader.d.ts +46 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +153 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/manager.d.ts +115 -15
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +260 -34
- package/dist/config/manager.js.map +1 -1
- package/dist/config/manager.test.d.ts +5 -0
- package/dist/config/manager.test.d.ts.map +1 -0
- package/dist/config/manager.test.js +192 -0
- package/dist/config/manager.test.js.map +1 -0
- package/dist/config/merger.d.ts +56 -0
- package/dist/config/merger.d.ts.map +1 -0
- package/dist/config/merger.js +177 -0
- package/dist/config/merger.js.map +1 -0
- package/dist/config/providers-config.d.ts +28 -0
- package/dist/config/providers-config.d.ts.map +1 -0
- package/dist/config/providers-config.js +79 -0
- package/dist/config/providers-config.js.map +1 -0
- package/dist/config/test-utils.d.ts +24 -0
- package/dist/config/test-utils.d.ts.map +1 -0
- package/dist/config/test-utils.js +55 -0
- package/dist/config/test-utils.js.map +1 -0
- package/dist/config/types.d.ts +108 -9
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +53 -2
- package/dist/config/types.js.map +1 -1
- package/dist/memory/import-resolver.d.ts +46 -0
- package/dist/memory/import-resolver.d.ts.map +1 -0
- package/dist/memory/import-resolver.js +117 -0
- package/dist/memory/import-resolver.js.map +1 -0
- package/dist/memory/index.d.ts +7 -6
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +7 -5
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/init-prompt.d.ts +22 -0
- package/dist/memory/init-prompt.d.ts.map +1 -0
- package/dist/memory/init-prompt.js +103 -0
- package/dist/memory/init-prompt.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +119 -0
- package/dist/memory/memory-manager.d.ts.map +1 -0
- package/dist/memory/memory-manager.js +587 -0
- package/dist/memory/memory-manager.js.map +1 -0
- package/dist/memory/rules-parser.d.ts +38 -0
- package/dist/memory/rules-parser.d.ts.map +1 -0
- package/dist/memory/rules-parser.js +69 -0
- package/dist/memory/rules-parser.js.map +1 -0
- package/dist/memory/test-utils.d.ts +20 -0
- package/dist/memory/test-utils.d.ts.map +1 -0
- package/dist/memory/test-utils.js +44 -0
- package/dist/memory/test-utils.js.map +1 -0
- package/dist/memory/types.d.ts +70 -63
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +42 -2
- package/dist/memory/types.js.map +1 -1
- package/dist/permissions/audit.d.ts +82 -0
- package/dist/permissions/audit.d.ts.map +1 -0
- package/dist/permissions/audit.js +229 -0
- package/dist/permissions/audit.js.map +1 -0
- package/dist/permissions/index.d.ts +11 -1
- package/dist/permissions/index.d.ts.map +1 -1
- package/dist/permissions/index.js +15 -0
- package/dist/permissions/index.js.map +1 -1
- package/dist/permissions/manager.d.ts +149 -13
- package/dist/permissions/manager.d.ts.map +1 -1
- package/dist/permissions/manager.js +480 -35
- package/dist/permissions/manager.js.map +1 -1
- package/dist/permissions/manager.test.d.ts +5 -0
- package/dist/permissions/manager.test.d.ts.map +1 -0
- package/dist/permissions/manager.test.js +213 -0
- package/dist/permissions/manager.test.js.map +1 -0
- package/dist/permissions/persistence.d.ts +74 -0
- package/dist/permissions/persistence.d.ts.map +1 -0
- package/dist/permissions/persistence.js +248 -0
- package/dist/permissions/persistence.js.map +1 -0
- package/dist/permissions/persistence.test.d.ts +5 -0
- package/dist/permissions/persistence.test.d.ts.map +1 -0
- package/dist/permissions/persistence.test.js +171 -0
- package/dist/permissions/persistence.test.js.map +1 -0
- package/dist/permissions/prompt-matcher.d.ts +64 -0
- package/dist/permissions/prompt-matcher.d.ts.map +1 -0
- package/dist/permissions/prompt-matcher.js +415 -0
- package/dist/permissions/prompt-matcher.js.map +1 -0
- package/dist/permissions/prompt-matcher.test.d.ts +5 -0
- package/dist/permissions/prompt-matcher.test.d.ts.map +1 -0
- package/dist/permissions/prompt-matcher.test.js +107 -0
- package/dist/permissions/prompt-matcher.test.js.map +1 -0
- package/dist/permissions/types.d.ts +157 -0
- package/dist/permissions/types.d.ts.map +1 -1
- package/dist/permissions/types.js +43 -8
- package/dist/permissions/types.js.map +1 -1
- package/dist/prompts/index.d.ts +92 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +241 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +14 -3
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/index.d.ts +5 -3
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +13 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/registry.d.ts +66 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +158 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/search/brave.d.ts +14 -0
- package/dist/providers/search/brave.d.ts.map +1 -0
- package/dist/providers/search/brave.js +87 -0
- package/dist/providers/search/brave.js.map +1 -0
- package/dist/providers/search/exa.d.ts +12 -0
- package/dist/providers/search/exa.d.ts.map +1 -0
- package/dist/providers/search/exa.js +158 -0
- package/dist/providers/search/exa.js.map +1 -0
- package/dist/providers/search/index.d.ts +31 -0
- package/dist/providers/search/index.d.ts.map +1 -0
- package/dist/providers/search/index.js +75 -0
- package/dist/providers/search/index.js.map +1 -0
- package/dist/providers/search/serper.d.ts +14 -0
- package/dist/providers/search/serper.d.ts.map +1 -0
- package/dist/providers/search/serper.js +87 -0
- package/dist/providers/search/serper.js.map +1 -0
- package/dist/providers/search/types.d.ts +21 -0
- package/dist/providers/search/types.d.ts.map +1 -0
- package/dist/providers/search/types.js +5 -0
- package/dist/providers/search/types.js.map +1 -0
- package/dist/providers/store.d.ts +104 -0
- package/dist/providers/store.d.ts.map +1 -0
- package/dist/providers/store.js +171 -0
- package/dist/providers/store.js.map +1 -0
- package/dist/providers/types.d.ts +7 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/vertex-ai.d.ts +33 -0
- package/dist/providers/vertex-ai.d.ts.map +1 -0
- package/dist/providers/vertex-ai.js +407 -0
- package/dist/providers/vertex-ai.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts.map +1 -1
- package/dist/tools/builtin/bash.js +2 -1
- package/dist/tools/builtin/bash.js.map +1 -1
- package/dist/tools/builtin/edit.d.ts.map +1 -1
- package/dist/tools/builtin/edit.js +2 -1
- package/dist/tools/builtin/edit.js.map +1 -1
- package/dist/tools/builtin/glob.d.ts.map +1 -1
- package/dist/tools/builtin/glob.js +2 -1
- package/dist/tools/builtin/glob.js.map +1 -1
- package/dist/tools/builtin/grep.d.ts.map +1 -1
- package/dist/tools/builtin/grep.js +2 -1
- package/dist/tools/builtin/grep.js.map +1 -1
- package/dist/tools/builtin/read.d.ts.map +1 -1
- package/dist/tools/builtin/read.js +2 -1
- package/dist/tools/builtin/read.js.map +1 -1
- package/dist/tools/builtin/todowrite.d.ts +15 -0
- package/dist/tools/builtin/todowrite.d.ts.map +1 -0
- package/dist/tools/builtin/todowrite.js +88 -0
- package/dist/tools/builtin/todowrite.js.map +1 -0
- package/dist/tools/builtin/webfetch.d.ts +20 -0
- package/dist/tools/builtin/webfetch.d.ts.map +1 -0
- package/dist/tools/builtin/webfetch.js +228 -0
- package/dist/tools/builtin/webfetch.js.map +1 -0
- package/dist/tools/builtin/websearch.d.ts +17 -0
- package/dist/tools/builtin/websearch.d.ts.map +1 -0
- package/dist/tools/builtin/websearch.js +87 -0
- package/dist/tools/builtin/websearch.js.map +1 -0
- package/dist/tools/builtin/write.d.ts.map +1 -1
- package/dist/tools/builtin/write.js +2 -1
- package/dist/tools/builtin/write.js.map +1 -1
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +28 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/types.d.ts +41 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +16 -0
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/utils/ssrf.d.ts +18 -0
- package/dist/tools/utils/ssrf.d.ts.map +1 -0
- package/dist/tools/utils/ssrf.js +70 -0
- package/dist/tools/utils/ssrf.js.map +1 -0
- package/docs/README.md +5 -4
- package/docs/config-system-comparison.md +707 -0
- package/docs/memory-system.md +238 -0
- package/docs/permissions.md +368 -0
- package/docs/proposals/0001-web-fetch-tool.md +32 -2
- package/docs/proposals/0002-web-search-tool.md +59 -2
- package/docs/proposals/0005-todo-system.md +350 -85
- package/docs/proposals/0006-memory-system.md +11 -10
- package/docs/proposals/0012-ask-user-question.md +941 -206
- package/docs/proposals/0023-permission-enhancements.md +61 -2
- package/docs/proposals/0041-configuration-system.md +587 -0
- package/docs/proposals/0042-prompt-optimization.md +866 -0
- package/docs/proposals/README.md +8 -6
- package/docs/providers.md +220 -0
- package/jest.config.js +26 -0
- package/package.json +14 -3
- package/src/agent/agent.ts +120 -18
- package/src/agent/types.ts +9 -1
- package/src/cli/components/App.tsx +369 -47
- package/src/cli/components/CommandSuggestions.tsx +3 -0
- package/src/cli/components/Header.tsx +11 -17
- package/src/cli/components/Logo.tsx +76 -9
- package/src/cli/components/Messages.tsx +146 -38
- package/src/cli/components/ModelSelector.tsx +169 -52
- package/src/cli/components/PermissionPrompt.tsx +388 -0
- package/src/cli/components/ProviderManager.tsx +534 -0
- package/src/cli/components/Spinner.tsx +138 -25
- package/src/cli/components/TodoList.tsx +54 -0
- package/src/cli/components/index.ts +6 -0
- package/src/cli/components/markdown.ts +157 -0
- package/src/cli/components/theme.ts +7 -0
- package/src/cli/index.tsx +76 -13
- package/src/config/index.ts +79 -4
- package/src/config/levels.test.ts +163 -0
- package/src/config/levels.ts +285 -0
- package/src/config/loader.test.ts +120 -0
- package/src/config/loader.ts +178 -0
- package/src/config/manager.test.ts +215 -0
- package/src/config/manager.ts +328 -40
- package/src/config/merger.test.ts +360 -0
- package/src/config/merger.ts +221 -0
- package/src/config/providers-config.ts +85 -0
- package/src/config/test-utils.ts +79 -0
- package/src/config/types.ts +186 -9
- package/src/memory/import-resolver.test.ts +117 -0
- package/src/memory/import-resolver.ts +149 -0
- package/src/memory/index.ts +11 -0
- package/src/memory/init-prompt.ts +113 -0
- package/src/memory/memory-manager.test.ts +198 -0
- package/src/memory/memory-manager.ts +716 -0
- package/src/memory/rules-parser.test.ts +182 -0
- package/src/memory/rules-parser.ts +82 -0
- package/src/memory/test-utils.ts +60 -0
- package/src/memory/types.ts +119 -0
- package/src/permissions/audit.ts +284 -0
- package/src/permissions/index.ts +20 -1
- package/src/permissions/manager.test.ts +260 -0
- package/src/permissions/manager.ts +592 -40
- package/src/permissions/persistence.test.ts +220 -0
- package/src/permissions/persistence.ts +301 -0
- package/src/permissions/prompt-matcher.test.ts +213 -0
- package/src/permissions/prompt-matcher.ts +472 -0
- package/src/permissions/types.ts +236 -8
- package/src/prompts/index.test.ts +279 -0
- package/src/prompts/index.ts +306 -0
- package/src/prompts/system/anthropic.txt +29 -0
- package/src/prompts/system/base.txt +124 -0
- package/src/prompts/system/gemini.txt +35 -0
- package/src/prompts/system/generic.txt +128 -0
- package/src/prompts/system/openai.txt +29 -0
- package/src/prompts/tools/bash.txt +60 -0
- package/src/prompts/tools/edit.txt +29 -0
- package/src/prompts/tools/glob.txt +35 -0
- package/src/prompts/tools/grep.txt +43 -0
- package/src/prompts/tools/read.txt +22 -0
- package/src/prompts/tools/todowrite.txt +71 -0
- package/src/prompts/tools/webfetch.txt +34 -0
- package/src/prompts/tools/websearch.txt +41 -0
- package/src/prompts/tools/write.txt +23 -0
- package/src/providers/gemini.ts +20 -4
- package/src/providers/index.ts +18 -3
- package/src/providers/registry.ts +198 -0
- package/src/providers/search/brave.ts +132 -0
- package/src/providers/search/exa.ts +217 -0
- package/src/providers/search/index.ts +79 -0
- package/src/providers/search/serper.ts +133 -0
- package/src/providers/search/types.ts +24 -0
- package/src/providers/store.ts +216 -0
- package/src/providers/types.ts +9 -1
- package/src/providers/vertex-ai.ts +594 -0
- package/src/tools/builtin/bash.ts +2 -1
- package/src/tools/builtin/edit.ts +2 -1
- package/src/tools/builtin/glob.ts +2 -1
- package/src/tools/builtin/grep.ts +2 -1
- package/src/tools/builtin/read.ts +2 -1
- package/src/tools/builtin/todowrite.ts +102 -0
- package/src/tools/builtin/webfetch.ts +261 -0
- package/src/tools/builtin/websearch.ts +103 -0
- package/src/tools/builtin/write.ts +2 -1
- package/src/tools/index.ts +28 -2
- package/src/tools/types.ts +32 -0
- package/src/tools/utils/ssrf.ts +79 -0
- package/tsconfig.json +1 -1
- package/CLAUDE.md +0 -70
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Spinner Component -
|
|
2
|
+
* Spinner Component - Vivid thinking animation
|
|
3
3
|
*/
|
|
4
|
-
import { useState, useEffect } from 'react';
|
|
4
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
5
5
|
import { Box, Text } from 'ink';
|
|
6
6
|
import InkSpinner from 'ink-spinner';
|
|
7
7
|
import { colors } from './theme.js';
|
|
@@ -33,40 +33,153 @@ export function LoadingSpinner({ text = 'Loading...' }: SpinnerProps) {
|
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// Thinking phrases that rotate during processing
|
|
37
|
+
const thinkingPhrases = [
|
|
38
|
+
'Thinking',
|
|
39
|
+
'Pondering',
|
|
40
|
+
'Analyzing',
|
|
41
|
+
'Processing',
|
|
42
|
+
'Reasoning',
|
|
43
|
+
'Contemplating',
|
|
44
|
+
'Figuring out',
|
|
45
|
+
'Working on it',
|
|
46
|
+
'Almost there',
|
|
47
|
+
'Crafting response',
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Animation frames for different styles
|
|
51
|
+
const animations = {
|
|
52
|
+
// Brainwave animation
|
|
53
|
+
brainwave: ['🧠 ∿∿∿', '🧠∿ ∿∿', '🧠∿∿ ∿', '🧠∿∿∿ ', '🧠 ∿∿∿', '🧠∿ ∿∿'],
|
|
54
|
+
// Sparkle animation
|
|
55
|
+
sparkle: ['✨ ', ' ✨ ', ' ✨ ', ' ✨ ', ' ✨', ' ✨ ', ' ✨ ', ' ✨ '],
|
|
56
|
+
// DNA helix
|
|
57
|
+
dna: ['🔬 ⌬⌬⌬', '🔬⌬ ⌬⌬', '🔬⌬⌬ ⌬', '🔬⌬⌬⌬ ', '🔬 ⌬⌬⌬'],
|
|
58
|
+
// Pulse dots
|
|
59
|
+
pulse: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
|
|
60
|
+
// Wave animation
|
|
61
|
+
wave: ['≋≈∼∽', '∽≋≈∼', '∼∽≋≈', '≈∼∽≋'],
|
|
62
|
+
// Bounce bar with gradient
|
|
63
|
+
bounceGradient: [
|
|
64
|
+
'█▓▒░ ',
|
|
65
|
+
' █▓▒░ ',
|
|
66
|
+
' █▓▒░ ',
|
|
67
|
+
' █▓▒░ ',
|
|
68
|
+
' █▓▒░',
|
|
69
|
+
' ░▒▓█ ',
|
|
70
|
+
' ░▒▓█ ',
|
|
71
|
+
' ░▒▓█ ',
|
|
72
|
+
'░▒▓█ ',
|
|
73
|
+
],
|
|
74
|
+
// Orbit animation
|
|
75
|
+
orbit: ['◐', '◓', '◑', '◒'],
|
|
76
|
+
// Loading bar with shimmer
|
|
77
|
+
shimmer: [
|
|
78
|
+
'▓▓▓▓▓░░░',
|
|
79
|
+
'░▓▓▓▓▓░░',
|
|
80
|
+
'░░▓▓▓▓▓░',
|
|
81
|
+
'░░░▓▓▓▓▓',
|
|
82
|
+
'░░░░▓▓▓▓',
|
|
83
|
+
'░░░▓▓▓▓▓',
|
|
84
|
+
'░░▓▓▓▓▓░',
|
|
85
|
+
'░▓▓▓▓▓░░',
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
type AnimationType = keyof typeof animations;
|
|
90
|
+
const animationTypes = Object.keys(animations) as AnimationType[];
|
|
91
|
+
|
|
92
|
+
// Format elapsed time
|
|
93
|
+
function formatElapsed(ms: number): string {
|
|
94
|
+
const secs = Math.floor(ms / 1000);
|
|
95
|
+
if (secs < 60) return `${secs}s`;
|
|
96
|
+
const mins = Math.floor(secs / 60);
|
|
97
|
+
const remainSecs = secs % 60;
|
|
98
|
+
return `${mins}m ${remainSecs}s`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Format token count
|
|
102
|
+
function formatTokens(count: number): string {
|
|
103
|
+
if (count >= 1000) {
|
|
104
|
+
return `${(count / 1000).toFixed(1)}k`;
|
|
105
|
+
}
|
|
106
|
+
return `${count}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface ProgressBarProps {
|
|
110
|
+
startTime?: number;
|
|
111
|
+
tokenCount?: number;
|
|
112
|
+
isThinking?: boolean;
|
|
113
|
+
}
|
|
114
|
+
|
|
36
115
|
/**
|
|
37
116
|
* Progress bar animation for processing state
|
|
38
|
-
*
|
|
117
|
+
* Claude Code style with time, tokens, and thinking status
|
|
39
118
|
*/
|
|
40
|
-
export function ProgressBar() {
|
|
119
|
+
export function ProgressBar({ startTime, tokenCount = 0, isThinking = false }: ProgressBarProps) {
|
|
41
120
|
const [frame, setFrame] = useState(0);
|
|
121
|
+
const [phraseIndex, setPhraseIndex] = useState(0);
|
|
122
|
+
const [elapsed, setElapsed] = useState(0);
|
|
42
123
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return () => clearInterval(timer);
|
|
124
|
+
// Pick a random animation style on mount
|
|
125
|
+
const animStyle = useMemo(() => {
|
|
126
|
+
const randomIndex = Math.floor(Math.random() * animationTypes.length);
|
|
127
|
+
return animationTypes[randomIndex];
|
|
48
128
|
}, []);
|
|
49
129
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
130
|
+
const currentAnim = animations[animStyle];
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
// Fast animation update
|
|
134
|
+
const animTimer = setInterval(() => {
|
|
135
|
+
setFrame((f) => (f + 1) % currentAnim.length);
|
|
136
|
+
}, 120);
|
|
137
|
+
|
|
138
|
+
// Slower phrase rotation (every 2.5 seconds)
|
|
139
|
+
const phraseTimer = setInterval(() => {
|
|
140
|
+
setPhraseIndex((p) => (p + 1) % thinkingPhrases.length);
|
|
141
|
+
}, 2500);
|
|
142
|
+
|
|
143
|
+
// Update elapsed time every second
|
|
144
|
+
const elapsedTimer = setInterval(() => {
|
|
145
|
+
if (startTime) {
|
|
146
|
+
setElapsed(Date.now() - startTime);
|
|
147
|
+
}
|
|
148
|
+
}, 1000);
|
|
149
|
+
|
|
150
|
+
return () => {
|
|
151
|
+
clearInterval(animTimer);
|
|
152
|
+
clearInterval(phraseTimer);
|
|
153
|
+
clearInterval(elapsedTimer);
|
|
154
|
+
};
|
|
155
|
+
}, [currentAnim.length, startTime]);
|
|
156
|
+
|
|
157
|
+
const animFrame = currentAnim[frame];
|
|
158
|
+
const phrase = thinkingPhrases[phraseIndex];
|
|
159
|
+
|
|
160
|
+
// Animated ellipsis
|
|
161
|
+
const ellipsis = '.'.repeat((frame % 3) + 1).padEnd(3, ' ');
|
|
162
|
+
|
|
163
|
+
// Build status parts
|
|
164
|
+
const parts: string[] = [];
|
|
165
|
+
if (startTime && elapsed > 0) {
|
|
166
|
+
parts.push(formatElapsed(elapsed));
|
|
167
|
+
}
|
|
168
|
+
if (tokenCount > 0) {
|
|
169
|
+
parts.push(`↓ ${formatTokens(tokenCount)} tokens`);
|
|
64
170
|
}
|
|
171
|
+
if (isThinking) {
|
|
172
|
+
parts.push('thinking');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const statusText = parts.length > 0 ? ` · ${parts.join(' · ')}` : '';
|
|
65
176
|
|
|
66
177
|
return (
|
|
67
178
|
<Box>
|
|
68
|
-
<Text color={colors.brand}>{
|
|
69
|
-
<Text color={colors.
|
|
179
|
+
<Text color={colors.brand}>{animFrame}</Text>
|
|
180
|
+
<Text color={colors.textSecondary}> {phrase}</Text>
|
|
181
|
+
<Text color={colors.textMuted}>{ellipsis}</Text>
|
|
182
|
+
<Text color={colors.textMuted}>(esc to stop{statusText})</Text>
|
|
70
183
|
</Box>
|
|
71
184
|
);
|
|
72
185
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TodoList Component - Display current todos in CLI
|
|
3
|
+
* Design: Minimal, clean, status-driven with clear visual hierarchy
|
|
4
|
+
*/
|
|
5
|
+
import { Box, Text } from 'ink';
|
|
6
|
+
import { colors } from './theme.js';
|
|
7
|
+
import type { TodoItem } from '../../tools/types.js';
|
|
8
|
+
|
|
9
|
+
interface TodoListProps {
|
|
10
|
+
todos: TodoItem[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function TodoList({ todos }: TodoListProps) {
|
|
14
|
+
if (todos.length === 0) return null;
|
|
15
|
+
|
|
16
|
+
const completed = todos.filter((t) => t.status === 'completed').length;
|
|
17
|
+
const total = todos.length;
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Box flexDirection="column" marginTop={1} marginLeft={2}>
|
|
21
|
+
{/* Header with count */}
|
|
22
|
+
<Text color={colors.textMuted}>
|
|
23
|
+
Tasks {completed}/{total}
|
|
24
|
+
</Text>
|
|
25
|
+
{/* Task list */}
|
|
26
|
+
{todos.map((todo, i) => {
|
|
27
|
+
const isCompleted = todo.status === 'completed';
|
|
28
|
+
const isInProgress = todo.status === 'in_progress';
|
|
29
|
+
|
|
30
|
+
// Status indicators: [x] done, [>] active, [ ] pending
|
|
31
|
+
let bracket: string;
|
|
32
|
+
let bracketColor: string;
|
|
33
|
+
|
|
34
|
+
if (isCompleted) {
|
|
35
|
+
bracket = '[x]';
|
|
36
|
+
bracketColor = colors.success;
|
|
37
|
+
} else if (isInProgress) {
|
|
38
|
+
bracket = '[>]';
|
|
39
|
+
bracketColor = colors.warning;
|
|
40
|
+
} else {
|
|
41
|
+
bracket = '[ ]';
|
|
42
|
+
bracketColor = colors.textMuted;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Text key={i} dimColor={isCompleted}>
|
|
47
|
+
<Text color={bracketColor}>{bracket}</Text>
|
|
48
|
+
<Text strikethrough={isCompleted}> {todo.content}</Text>
|
|
49
|
+
</Text>
|
|
50
|
+
);
|
|
51
|
+
})}
|
|
52
|
+
</Box>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -19,3 +19,9 @@ export { PromptInput, ConfirmPrompt } from './Input.js';
|
|
|
19
19
|
export { colors, icons } from './theme.js';
|
|
20
20
|
export { ModelSelector } from './ModelSelector.js';
|
|
21
21
|
export { CommandSuggestions, COMMANDS, getFilteredCommands } from './CommandSuggestions.js';
|
|
22
|
+
export {
|
|
23
|
+
PermissionPrompt,
|
|
24
|
+
SimpleConfirmPrompt,
|
|
25
|
+
PermissionRulesDisplay,
|
|
26
|
+
PermissionAuditDisplay,
|
|
27
|
+
} from './PermissionPrompt.js';
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Terminal Markdown Renderer
|
|
3
|
+
* Uses marked for parsing, chalk for ANSI colors
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { marked, type Tokens, type RendererObject, type Token } from 'marked';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
|
|
9
|
+
// Helper type for renderer context with parser access
|
|
10
|
+
type RendererContext = {
|
|
11
|
+
parser?: {
|
|
12
|
+
parseInline(tokens: Token[]): string;
|
|
13
|
+
parse(tokens: Token[]): string;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Helper to parse inline tokens from renderer context
|
|
18
|
+
function parseInline(ctx: unknown, tokens: Token[], fallback: string): string {
|
|
19
|
+
const context = ctx as RendererContext;
|
|
20
|
+
return context.parser?.parseInline(tokens) ?? fallback;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Helper to parse block tokens (like list item content)
|
|
24
|
+
function parseTokens(ctx: unknown, tokens: Token[], fallback: string): string {
|
|
25
|
+
const context = ctx as RendererContext;
|
|
26
|
+
// For list items, tokens may contain text tokens with nested inline tokens
|
|
27
|
+
// Use parse() for block-level token arrays
|
|
28
|
+
return context.parser?.parse(tokens).trim() ?? fallback;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Custom terminal renderer
|
|
32
|
+
const terminalRenderer: RendererObject = {
|
|
33
|
+
// Headings: colored and bold
|
|
34
|
+
heading(token: Tokens.Heading): string {
|
|
35
|
+
const colors = [
|
|
36
|
+
chalk.bold.magenta, // h1
|
|
37
|
+
chalk.bold.cyan, // h2
|
|
38
|
+
chalk.bold.green, // h3
|
|
39
|
+
chalk.bold.yellow, // h4+
|
|
40
|
+
];
|
|
41
|
+
const colorFn = colors[Math.min(token.depth - 1, 3)];
|
|
42
|
+
const content = parseInline(this, token.tokens, token.text);
|
|
43
|
+
return '\n' + colorFn(content) + '\n\n';
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
// Paragraphs - must parse inline tokens for bold/italic/etc
|
|
47
|
+
paragraph(token: Tokens.Paragraph): string {
|
|
48
|
+
const content = parseInline(this, token.tokens, token.text);
|
|
49
|
+
return content + '\n\n';
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// Bold text
|
|
53
|
+
strong(token: Tokens.Strong): string {
|
|
54
|
+
const content = parseInline(this, token.tokens, token.text);
|
|
55
|
+
return chalk.bold(content);
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// Italic text
|
|
59
|
+
em(token: Tokens.Em): string {
|
|
60
|
+
const content = parseInline(this, token.tokens, token.text);
|
|
61
|
+
return chalk.italic(content);
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Inline code
|
|
65
|
+
codespan({ text }: Tokens.Codespan): string {
|
|
66
|
+
return chalk.yellow('`' + text + '`');
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// Code blocks - clean format without ``` markers
|
|
70
|
+
code({ text, lang }: Tokens.Code): string {
|
|
71
|
+
const langHeader = lang ? chalk.dim(` [${lang}]`) + '\n' : '';
|
|
72
|
+
const lines = text.split('\n').map(line => chalk.cyan(' ' + line)).join('\n');
|
|
73
|
+
return '\n' + langHeader + lines + '\n\n';
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// List - parse block tokens for each item (they may contain nested text+inline tokens)
|
|
77
|
+
list(token: Tokens.List): string {
|
|
78
|
+
const result = token.items.map((item, i) => {
|
|
79
|
+
const bullet = token.ordered ? chalk.dim(`${i + 1}.`) : chalk.dim('•');
|
|
80
|
+
const content = parseTokens(this, item.tokens, item.text);
|
|
81
|
+
return ` ${bullet} ${content}`;
|
|
82
|
+
}).join('\n');
|
|
83
|
+
return result + '\n\n';
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// List item - use block parser since items contain text tokens with nested inline
|
|
87
|
+
listitem(token: Tokens.ListItem): string {
|
|
88
|
+
return parseTokens(this, token.tokens, token.text);
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Links
|
|
92
|
+
link(token: Tokens.Link): string {
|
|
93
|
+
const content = parseInline(this, token.tokens, token.text);
|
|
94
|
+
return chalk.blue.underline(content) + chalk.dim(` (${token.href})`);
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// Blockquotes
|
|
98
|
+
blockquote(token: Tokens.Blockquote): string {
|
|
99
|
+
const text = token.text.trim();
|
|
100
|
+
const lines = text.split('\n').map(line =>
|
|
101
|
+
chalk.dim('│ ') + chalk.italic(line)
|
|
102
|
+
).join('\n');
|
|
103
|
+
return '\n' + lines + '\n\n';
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// Horizontal rule
|
|
107
|
+
hr(): string {
|
|
108
|
+
return '\n' + chalk.dim('─'.repeat(40)) + '\n\n';
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Line break
|
|
112
|
+
br(): string {
|
|
113
|
+
return '\n';
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
// Delete/strikethrough
|
|
117
|
+
del(token: Tokens.Del): string {
|
|
118
|
+
const content = parseInline(this, token.tokens, token.text);
|
|
119
|
+
return chalk.strikethrough(content);
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
// Plain text - may contain nested inline tokens (like in list items)
|
|
123
|
+
text(token: Tokens.Text | Tokens.Escape): string {
|
|
124
|
+
// Tokens.Text can have nested tokens array with inline formatting
|
|
125
|
+
if ('tokens' in token && token.tokens && token.tokens.length > 0) {
|
|
126
|
+
return parseInline(this, token.tokens, token.text);
|
|
127
|
+
}
|
|
128
|
+
return token.text ?? '';
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// HTML (strip tags)
|
|
132
|
+
html(token: Tokens.HTML | Tokens.Tag): string {
|
|
133
|
+
const text = 'text' in token ? token.text : '';
|
|
134
|
+
return text.replace(/<[^>]*>/g, '');
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Configure marked with custom renderer
|
|
139
|
+
marked.use({ renderer: terminalRenderer });
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Render markdown text to terminal-formatted string
|
|
143
|
+
*/
|
|
144
|
+
export function renderMarkdown(text: string): string {
|
|
145
|
+
try {
|
|
146
|
+
const result = marked.parse(text);
|
|
147
|
+
// marked.parse can return string or Promise<string>
|
|
148
|
+
if (typeof result === 'string') {
|
|
149
|
+
return result.trim();
|
|
150
|
+
}
|
|
151
|
+
// If async, return original text (shouldn't happen with sync renderer)
|
|
152
|
+
return text;
|
|
153
|
+
} catch {
|
|
154
|
+
// On error, return original text
|
|
155
|
+
return text;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -14,6 +14,7 @@ export const colors = {
|
|
|
14
14
|
textMuted: '#64748B', // Slate 500
|
|
15
15
|
tool: '#C084FC', // Purple 400
|
|
16
16
|
separator: '#1E293B', // Slate 800
|
|
17
|
+
inputBg: '#111827', // Gray 900 - subtle background for user input
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
export const icons = {
|
|
@@ -29,8 +30,14 @@ export const icons = {
|
|
|
29
30
|
info: 'ℹ',
|
|
30
31
|
// Tools
|
|
31
32
|
tool: '⚡', // Lightning for tools
|
|
33
|
+
fetch: '●', // Filled circle for fetch (Claude Code style)
|
|
32
34
|
arrow: '→',
|
|
33
35
|
// UI
|
|
34
36
|
thinking: '✱', // Star for thinking state
|
|
35
37
|
cursor: '▋',
|
|
38
|
+
// Selection
|
|
39
|
+
radio: '●', // Filled radio for selected
|
|
40
|
+
radioEmpty: '○', // Empty radio for unselected
|
|
41
|
+
// Tree connectors
|
|
42
|
+
treeEnd: '└', // Tree end connector for tool results
|
|
36
43
|
};
|
package/src/cli/index.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { render } from 'ink';
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { App } from './components/App.js';
|
|
11
11
|
import type { AgentConfig } from '../agent/types.js';
|
|
12
|
-
import { SettingsManager, type Settings } from '../config/index.js';
|
|
12
|
+
import { SettingsManager, ProvidersConfigManager, type Settings, type ProviderName } from '../config/index.js';
|
|
13
13
|
|
|
14
14
|
// ============================================================================
|
|
15
15
|
// Proxy Setup
|
|
@@ -31,12 +31,17 @@ async function setupProxy(): Promise<void> {
|
|
|
31
31
|
// ============================================================================
|
|
32
32
|
// Configuration
|
|
33
33
|
// ============================================================================
|
|
34
|
-
function detectConfig(settings: Settings): AgentConfig {
|
|
35
|
-
let provider:
|
|
34
|
+
function detectConfig(settings: Settings, providersConfig: ProvidersConfigManager): AgentConfig {
|
|
35
|
+
let provider: ProviderName = 'gemini';
|
|
36
36
|
let model = 'gemini-2.0-flash';
|
|
37
37
|
|
|
38
|
+
// Check for explicit Vertex AI enablement first (highest priority for auto-detect)
|
|
39
|
+
if (process.env.GENCODE_USE_VERTEX === '1' || process.env.CLAUDE_CODE_USE_VERTEX === '1') {
|
|
40
|
+
provider = 'vertex-ai';
|
|
41
|
+
model = process.env.VERTEX_AI_MODEL ?? 'claude-sonnet-4-5@20250929';
|
|
42
|
+
}
|
|
38
43
|
// Auto-detect from API keys
|
|
39
|
-
if (process.env.ANTHROPIC_API_KEY) {
|
|
44
|
+
else if (process.env.ANTHROPIC_API_KEY) {
|
|
40
45
|
provider = 'anthropic';
|
|
41
46
|
model = 'claude-sonnet-4-20250514';
|
|
42
47
|
} else if (process.env.OPENAI_API_KEY) {
|
|
@@ -49,7 +54,7 @@ function detectConfig(settings: Settings): AgentConfig {
|
|
|
49
54
|
|
|
50
55
|
// Override from env vars
|
|
51
56
|
if (process.env.GENCODE_PROVIDER) {
|
|
52
|
-
provider = process.env.GENCODE_PROVIDER as
|
|
57
|
+
provider = process.env.GENCODE_PROVIDER as ProviderName;
|
|
53
58
|
}
|
|
54
59
|
if (process.env.GENCODE_MODEL) {
|
|
55
60
|
model = process.env.GENCODE_MODEL;
|
|
@@ -61,6 +66,13 @@ function detectConfig(settings: Settings): AgentConfig {
|
|
|
61
66
|
}
|
|
62
67
|
if (settings.model) {
|
|
63
68
|
model = settings.model;
|
|
69
|
+
// Auto-infer provider from model using providers.json (if not explicitly set)
|
|
70
|
+
if (!settings.provider) {
|
|
71
|
+
const inferredProvider = providersConfig.inferProvider(model);
|
|
72
|
+
if (inferredProvider) {
|
|
73
|
+
provider = inferredProvider;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
return {
|
|
@@ -76,10 +88,21 @@ function detectConfig(settings: Settings): AgentConfig {
|
|
|
76
88
|
// ============================================================================
|
|
77
89
|
function parseArgs() {
|
|
78
90
|
const args = process.argv.slice(2);
|
|
91
|
+
|
|
92
|
+
// Extract prompt value from -p "message" or --prompt "message"
|
|
93
|
+
let prompt: string | undefined;
|
|
94
|
+
for (let i = 0; i < args.length; i++) {
|
|
95
|
+
if ((args[i] === '-p' || args[i] === '--prompt') && args[i + 1]) {
|
|
96
|
+
prompt = args[i + 1];
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
79
101
|
return {
|
|
80
102
|
continue: args.includes('-c') || args.includes('--continue'),
|
|
81
103
|
resume: args.includes('-r') || args.includes('--resume'),
|
|
82
104
|
help: args.includes('-h') || args.includes('--help'),
|
|
105
|
+
prompt,
|
|
83
106
|
};
|
|
84
107
|
}
|
|
85
108
|
|
|
@@ -90,17 +113,47 @@ function printUsage(): void {
|
|
|
90
113
|
console.log(' Usage: gencode [options]');
|
|
91
114
|
console.log();
|
|
92
115
|
console.log(' Options:');
|
|
93
|
-
console.log(' -c, --continue
|
|
94
|
-
console.log(' -r, --resume
|
|
95
|
-
console.log(' -
|
|
116
|
+
console.log(' -c, --continue Resume the most recent session');
|
|
117
|
+
console.log(' -r, --resume Select a session interactively');
|
|
118
|
+
console.log(' -p, --prompt <msg> Run a single prompt (non-interactive)');
|
|
119
|
+
console.log(' -h, --help Show this help');
|
|
96
120
|
console.log();
|
|
97
121
|
console.log(' Examples:');
|
|
98
|
-
console.log(' gencode
|
|
99
|
-
console.log(' gencode -c
|
|
100
|
-
console.log(' gencode -r
|
|
122
|
+
console.log(' gencode Start new session');
|
|
123
|
+
console.log(' gencode -c Continue last session');
|
|
124
|
+
console.log(' gencode -r Pick a session');
|
|
125
|
+
console.log(' gencode -p "2+2" Run single prompt');
|
|
101
126
|
console.log();
|
|
102
127
|
}
|
|
103
128
|
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Non-interactive mode
|
|
131
|
+
// ============================================================================
|
|
132
|
+
async function runNonInteractive(prompt: string, config: AgentConfig): Promise<void> {
|
|
133
|
+
const { Agent } = await import('../agent/agent.js');
|
|
134
|
+
|
|
135
|
+
const agent = new Agent(config);
|
|
136
|
+
|
|
137
|
+
let response = '';
|
|
138
|
+
for await (const event of agent.run(prompt)) {
|
|
139
|
+
switch (event.type) {
|
|
140
|
+
case 'text':
|
|
141
|
+
response += event.text;
|
|
142
|
+
break;
|
|
143
|
+
case 'tool_start':
|
|
144
|
+
console.error(`[tool] ${event.name}`);
|
|
145
|
+
break;
|
|
146
|
+
case 'error':
|
|
147
|
+
console.error(`[error] ${event.error.message}`);
|
|
148
|
+
break;
|
|
149
|
+
case 'done':
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log(response);
|
|
155
|
+
}
|
|
156
|
+
|
|
104
157
|
// ============================================================================
|
|
105
158
|
// Main
|
|
106
159
|
// ============================================================================
|
|
@@ -114,11 +167,20 @@ async function main() {
|
|
|
114
167
|
|
|
115
168
|
await setupProxy();
|
|
116
169
|
|
|
117
|
-
// Load saved settings
|
|
170
|
+
// Load saved settings and providers config
|
|
118
171
|
const settingsManager = new SettingsManager();
|
|
119
172
|
const settings = await settingsManager.load();
|
|
120
173
|
|
|
121
|
-
const
|
|
174
|
+
const providersConfig = new ProvidersConfigManager();
|
|
175
|
+
await providersConfig.load();
|
|
176
|
+
|
|
177
|
+
const config = detectConfig(settings, providersConfig);
|
|
178
|
+
|
|
179
|
+
// Non-interactive mode with -p flag
|
|
180
|
+
if (args.prompt) {
|
|
181
|
+
await runNonInteractive(args.prompt, config);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
122
184
|
|
|
123
185
|
// Render the Ink app
|
|
124
186
|
render(
|
|
@@ -126,6 +188,7 @@ async function main() {
|
|
|
126
188
|
config={config}
|
|
127
189
|
settingsManager={settingsManager}
|
|
128
190
|
resumeLatest={args.continue}
|
|
191
|
+
permissionSettings={settings.permissions}
|
|
129
192
|
/>
|
|
130
193
|
);
|
|
131
194
|
}
|
package/src/config/index.ts
CHANGED
|
@@ -1,7 +1,82 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuration Module - Multi-level configuration system (Claude Code compatible)
|
|
3
|
+
*
|
|
4
|
+
* This module provides a hierarchical configuration system that:
|
|
5
|
+
* - Supports multiple levels: user, project, local, managed
|
|
6
|
+
* - Merges .gencode and .claude directories at each level (gencode wins)
|
|
7
|
+
* - Supports GENCODE_CONFIG_DIRS environment variable for extra config dirs
|
|
8
|
+
* - Enforces managed settings that cannot be overridden
|
|
3
9
|
*/
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
export type {
|
|
7
|
-
|
|
11
|
+
// Core types
|
|
12
|
+
export type {
|
|
13
|
+
Settings,
|
|
14
|
+
SettingsManagerOptions,
|
|
15
|
+
ProviderName,
|
|
16
|
+
PermissionRules,
|
|
17
|
+
ConfigLevelType,
|
|
18
|
+
ConfigLevel,
|
|
19
|
+
ConfigSource,
|
|
20
|
+
MergedConfig,
|
|
21
|
+
ProvidersConfig,
|
|
22
|
+
ProviderConnection,
|
|
23
|
+
CachedModel,
|
|
24
|
+
ProviderModels,
|
|
25
|
+
} from './types.js';
|
|
26
|
+
|
|
27
|
+
// Constants
|
|
28
|
+
export {
|
|
29
|
+
DEFAULT_SETTINGS_DIR,
|
|
30
|
+
PROJECT_SETTINGS_DIR,
|
|
31
|
+
FALLBACK_SETTINGS_DIR,
|
|
32
|
+
FALLBACK_PROJECT_DIR,
|
|
33
|
+
SETTINGS_FILE_NAME,
|
|
34
|
+
SETTINGS_LOCAL_FILE_NAME,
|
|
35
|
+
MANAGED_SETTINGS_FILE_NAME,
|
|
36
|
+
PROVIDERS_FILE_NAME,
|
|
37
|
+
GENCODE_DIR,
|
|
38
|
+
CLAUDE_DIR,
|
|
39
|
+
USER_GENCODE_DIR,
|
|
40
|
+
USER_CLAUDE_DIR,
|
|
41
|
+
GENCODE_CONFIG_DIRS_ENV,
|
|
42
|
+
getManagedPaths,
|
|
43
|
+
} from './types.js';
|
|
44
|
+
|
|
45
|
+
// Configuration levels
|
|
46
|
+
export {
|
|
47
|
+
findProjectRoot,
|
|
48
|
+
parseExtraConfigDirs,
|
|
49
|
+
getConfigLevels,
|
|
50
|
+
getPrimarySettingsDir,
|
|
51
|
+
getSettingsFilePath,
|
|
52
|
+
type ConfigPathInfo,
|
|
53
|
+
type ResolvedLevel,
|
|
54
|
+
} from './levels.js';
|
|
55
|
+
|
|
56
|
+
// Configuration loader
|
|
57
|
+
export {
|
|
58
|
+
loadAllSources,
|
|
59
|
+
loadSourcesByLevel,
|
|
60
|
+
loadUserSettings,
|
|
61
|
+
loadProjectSettings,
|
|
62
|
+
loadManagedSettings,
|
|
63
|
+
getConfigInfo,
|
|
64
|
+
getExistingConfigFiles,
|
|
65
|
+
} from './loader.js';
|
|
66
|
+
|
|
67
|
+
// Configuration merger
|
|
68
|
+
export {
|
|
69
|
+
deepMerge,
|
|
70
|
+
mergeSettings,
|
|
71
|
+
extractManagedDeny,
|
|
72
|
+
applyManagedRestrictions,
|
|
73
|
+
mergeAllSources,
|
|
74
|
+
mergeWithCliArgs,
|
|
75
|
+
createMergeSummary,
|
|
76
|
+
} from './merger.js';
|
|
77
|
+
|
|
78
|
+
// Configuration managers
|
|
79
|
+
export { ConfigManager, SettingsManager } from './manager.js';
|
|
80
|
+
|
|
81
|
+
// Providers configuration
|
|
82
|
+
export { ProvidersConfigManager } from './providers-config.js';
|