compact-agent 1.1.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.
- package/README.md +394 -0
- package/bin/anycode.js +2 -0
- package/bin/crowcoder.js +19 -0
- package/bin/ecc-hooks.cjs +138 -0
- package/dist/agents.d.ts +17 -0
- package/dist/agents.js +1603 -0
- package/dist/agents.js.map +1 -0
- package/dist/api.d.ts +16 -0
- package/dist/api.js +115 -0
- package/dist/api.js.map +1 -0
- package/dist/autonomous-loops.d.ts +108 -0
- package/dist/autonomous-loops.js +526 -0
- package/dist/autonomous-loops.js.map +1 -0
- package/dist/codemaps.d.ts +53 -0
- package/dist/codemaps.js +325 -0
- package/dist/codemaps.js.map +1 -0
- package/dist/compaction.d.ts +30 -0
- package/dist/compaction.js +125 -0
- package/dist/compaction.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/content-engine.d.ts +97 -0
- package/dist/content-engine.js +721 -0
- package/dist/content-engine.js.map +1 -0
- package/dist/cost-tracker.d.ts +49 -0
- package/dist/cost-tracker.js +150 -0
- package/dist/cost-tracker.js.map +1 -0
- package/dist/counter-button.d.ts +35 -0
- package/dist/counter-button.js +48 -0
- package/dist/counter-button.js.map +1 -0
- package/dist/counter.d.ts +21 -0
- package/dist/counter.js +31 -0
- package/dist/counter.js.map +1 -0
- package/dist/coverage.d.ts +23 -0
- package/dist/coverage.js +215 -0
- package/dist/coverage.js.map +1 -0
- package/dist/docs-sync.d.ts +23 -0
- package/dist/docs-sync.js +266 -0
- package/dist/docs-sync.js.map +1 -0
- package/dist/ecc.d.ts +41 -0
- package/dist/ecc.js +644 -0
- package/dist/ecc.js.map +1 -0
- package/dist/evaluation.d.ts +24 -0
- package/dist/evaluation.js +412 -0
- package/dist/evaluation.js.map +1 -0
- package/dist/export.d.ts +22 -0
- package/dist/export.js +109 -0
- package/dist/export.js.map +1 -0
- package/dist/git-workflow.d.ts +22 -0
- package/dist/git-workflow.js +197 -0
- package/dist/git-workflow.js.map +1 -0
- package/dist/hook-controls.d.ts +34 -0
- package/dist/hook-controls.js +90 -0
- package/dist/hook-controls.js.map +1 -0
- package/dist/hooks.d.ts +30 -0
- package/dist/hooks.js +130 -0
- package/dist/hooks.js.map +1 -0
- package/dist/html-parser.d.ts +18 -0
- package/dist/html-parser.js +101 -0
- package/dist/html-parser.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1230 -0
- package/dist/index.js.map +1 -0
- package/dist/learning.d.ts +35 -0
- package/dist/learning.js +238 -0
- package/dist/learning.js.map +1 -0
- package/dist/login.d.ts +37 -0
- package/dist/login.js +191 -0
- package/dist/login.js.map +1 -0
- package/dist/memory.d.ts +39 -0
- package/dist/memory.js +183 -0
- package/dist/memory.js.map +1 -0
- package/dist/model-router.d.ts +23 -0
- package/dist/model-router.js +145 -0
- package/dist/model-router.js.map +1 -0
- package/dist/modes.d.ts +17 -0
- package/dist/modes.js +217 -0
- package/dist/modes.js.map +1 -0
- package/dist/orchestration.d.ts +37 -0
- package/dist/orchestration.js +139 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/package-detect.d.ts +36 -0
- package/dist/package-detect.js +529 -0
- package/dist/package-detect.js.map +1 -0
- package/dist/permissions.d.ts +25 -0
- package/dist/permissions.js +50 -0
- package/dist/permissions.js.map +1 -0
- package/dist/pm2-manager.d.ts +40 -0
- package/dist/pm2-manager.js +127 -0
- package/dist/pm2-manager.js.map +1 -0
- package/dist/query.d.ts +15 -0
- package/dist/query.js +278 -0
- package/dist/query.js.map +1 -0
- package/dist/refactor.d.ts +22 -0
- package/dist/refactor.js +226 -0
- package/dist/refactor.js.map +1 -0
- package/dist/retry.d.ts +20 -0
- package/dist/retry.js +88 -0
- package/dist/retry.js.map +1 -0
- package/dist/rules.d.ts +34 -0
- package/dist/rules.js +942 -0
- package/dist/rules.js.map +1 -0
- package/dist/schema.d.ts +23 -0
- package/dist/schema.js +12 -0
- package/dist/schema.js.map +1 -0
- package/dist/search-first.d.ts +17 -0
- package/dist/search-first.js +301 -0
- package/dist/search-first.js.map +1 -0
- package/dist/security.d.ts +10 -0
- package/dist/security.js +145 -0
- package/dist/security.js.map +1 -0
- package/dist/sessions.d.ts +21 -0
- package/dist/sessions.js +112 -0
- package/dist/sessions.js.map +1 -0
- package/dist/skill-create.d.ts +38 -0
- package/dist/skill-create.js +389 -0
- package/dist/skill-create.js.map +1 -0
- package/dist/skills.d.ts +34 -0
- package/dist/skills.js +161 -0
- package/dist/skills.js.map +1 -0
- package/dist/strategic-compaction.d.ts +24 -0
- package/dist/strategic-compaction.js +144 -0
- package/dist/strategic-compaction.js.map +1 -0
- package/dist/system-prompt.d.ts +3 -0
- package/dist/system-prompt.js +101 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/theme.d.ts +60 -0
- package/dist/theme.js +220 -0
- package/dist/theme.js.map +1 -0
- package/dist/tools/bash.d.ts +2 -0
- package/dist/tools/bash.js +49 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.js +76 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +2 -0
- package/dist/tools/glob.js +54 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +2 -0
- package/dist/tools/grep.js +64 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +27 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-dir.d.ts +2 -0
- package/dist/tools/list-dir.js +51 -0
- package/dist/tools/list-dir.js.map +1 -0
- package/dist/tools/read.d.ts +2 -0
- package/dist/tools/read.js +56 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/types.d.ts +45 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/web-fetch.d.ts +2 -0
- package/dist/tools/web-fetch.js +41 -0
- package/dist/tools/web-fetch.js.map +1 -0
- package/dist/tools/web-search.d.ts +27 -0
- package/dist/tools/web-search.js +139 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/write.d.ts +2 -0
- package/dist/tools/write.js +36 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.js +57 -0
- package/dist/types.js.map +1 -0
- package/dist/users.d.ts +51 -0
- package/dist/users.js +193 -0
- package/dist/users.js.map +1 -0
- package/dist/verification.d.ts +73 -0
- package/dist/verification.js +269 -0
- package/dist/verification.js.map +1 -0
- package/dist/walkthrough.d.ts +10 -0
- package/dist/walkthrough.js +121 -0
- package/dist/walkthrough.js.map +1 -0
- package/package.json +58 -0
- package/resources/ecc/agents/architect.json +16 -0
- package/resources/ecc/agents/architect.md +212 -0
- package/resources/ecc/agents/build-error-resolver.json +17 -0
- package/resources/ecc/agents/build-error-resolver.md +116 -0
- package/resources/ecc/agents/chief-of-staff.json +17 -0
- package/resources/ecc/agents/chief-of-staff.md +153 -0
- package/resources/ecc/agents/code-reviewer.json +16 -0
- package/resources/ecc/agents/code-reviewer.md +238 -0
- package/resources/ecc/agents/database-reviewer.json +16 -0
- package/resources/ecc/agents/database-reviewer.md +92 -0
- package/resources/ecc/agents/doc-updater.json +16 -0
- package/resources/ecc/agents/doc-updater.md +108 -0
- package/resources/ecc/agents/e2e-runner.json +17 -0
- package/resources/ecc/agents/e2e-runner.md +109 -0
- package/resources/ecc/agents/go-build-resolver.json +17 -0
- package/resources/ecc/agents/go-build-resolver.md +96 -0
- package/resources/ecc/agents/go-reviewer.json +16 -0
- package/resources/ecc/agents/go-reviewer.md +77 -0
- package/resources/ecc/agents/harness-optimizer.json +15 -0
- package/resources/ecc/agents/harness-optimizer.md +34 -0
- package/resources/ecc/agents/loop-operator.json +16 -0
- package/resources/ecc/agents/loop-operator.md +36 -0
- package/resources/ecc/agents/planner.json +15 -0
- package/resources/ecc/agents/planner.md +212 -0
- package/resources/ecc/agents/python-reviewer.json +16 -0
- package/resources/ecc/agents/python-reviewer.md +99 -0
- package/resources/ecc/agents/refactor-cleaner.json +17 -0
- package/resources/ecc/agents/refactor-cleaner.md +87 -0
- package/resources/ecc/agents/security-reviewer.json +16 -0
- package/resources/ecc/agents/security-reviewer.md +109 -0
- package/resources/ecc/agents/tdd-guide.json +17 -0
- package/resources/ecc/agents/tdd-guide.md +93 -0
- package/resources/ecc/commands/add-language-rules.md +39 -0
- package/resources/ecc/commands/database-migration.md +36 -0
- package/resources/ecc/commands/feature-development.md +38 -0
- package/resources/ecc/prompts/build-fix.prompt.md +47 -0
- package/resources/ecc/prompts/code-review.prompt.md +56 -0
- package/resources/ecc/prompts/plan.prompt.md +52 -0
- package/resources/ecc/prompts/refactor.prompt.md +50 -0
- package/resources/ecc/prompts/security-review.prompt.md +70 -0
- package/resources/ecc/prompts/tdd.prompt.md +47 -0
- package/resources/ecc/rules/common-agents.md +53 -0
- package/resources/ecc/rules/common-coding-style.md +52 -0
- package/resources/ecc/rules/common-development-workflow.md +33 -0
- package/resources/ecc/rules/common-git-workflow.md +28 -0
- package/resources/ecc/rules/common-hooks.md +34 -0
- package/resources/ecc/rules/common-patterns.md +35 -0
- package/resources/ecc/rules/common-performance.md +59 -0
- package/resources/ecc/rules/common-security.md +33 -0
- package/resources/ecc/rules/common-testing.md +33 -0
- package/resources/ecc/rules/golang-coding-style.md +31 -0
- package/resources/ecc/rules/golang-hooks.md +16 -0
- package/resources/ecc/rules/golang-patterns.md +44 -0
- package/resources/ecc/rules/golang-security.md +33 -0
- package/resources/ecc/rules/golang-testing.md +30 -0
- package/resources/ecc/rules/kotlin-coding-style.md +39 -0
- package/resources/ecc/rules/kotlin-hooks.md +16 -0
- package/resources/ecc/rules/kotlin-patterns.md +50 -0
- package/resources/ecc/rules/kotlin-security.md +58 -0
- package/resources/ecc/rules/kotlin-testing.md +38 -0
- package/resources/ecc/rules/php-coding-style.md +25 -0
- package/resources/ecc/rules/php-hooks.md +21 -0
- package/resources/ecc/rules/php-patterns.md +23 -0
- package/resources/ecc/rules/php-security.md +24 -0
- package/resources/ecc/rules/php-testing.md +26 -0
- package/resources/ecc/rules/python-coding-style.md +42 -0
- package/resources/ecc/rules/python-hooks.md +19 -0
- package/resources/ecc/rules/python-patterns.md +39 -0
- package/resources/ecc/rules/python-security.md +30 -0
- package/resources/ecc/rules/python-testing.md +38 -0
- package/resources/ecc/rules/swift-coding-style.md +47 -0
- package/resources/ecc/rules/swift-hooks.md +20 -0
- package/resources/ecc/rules/swift-patterns.md +66 -0
- package/resources/ecc/rules/swift-security.md +33 -0
- package/resources/ecc/rules/swift-testing.md +45 -0
- package/resources/ecc/rules/typescript-coding-style.md +63 -0
- package/resources/ecc/rules/typescript-hooks.md +20 -0
- package/resources/ecc/rules/typescript-patterns.md +50 -0
- package/resources/ecc/rules/typescript-security.md +26 -0
- package/resources/ecc/rules/typescript-testing.md +16 -0
- package/resources/ecc/skills/agent-introspection-debugging/SKILL.md +152 -0
- package/resources/ecc/skills/agent-introspection-debugging/agents/openai.yaml +7 -0
- package/resources/ecc/skills/agent-sort/SKILL.md +214 -0
- package/resources/ecc/skills/agent-sort/agents/openai.yaml +7 -0
- package/resources/ecc/skills/api-design/SKILL.md +522 -0
- package/resources/ecc/skills/api-design/agents/openai.yaml +7 -0
- package/resources/ecc/skills/article-writing/SKILL.md +78 -0
- package/resources/ecc/skills/article-writing/agents/openai.yaml +7 -0
- package/resources/ecc/skills/backend-patterns/SKILL.md +597 -0
- package/resources/ecc/skills/backend-patterns/agents/openai.yaml +7 -0
- package/resources/ecc/skills/brand-voice/SKILL.md +96 -0
- package/resources/ecc/skills/brand-voice/agents/openai.yaml +7 -0
- package/resources/ecc/skills/brand-voice/references/voice-profile-schema.md +55 -0
- package/resources/ecc/skills/bun-runtime/SKILL.md +83 -0
- package/resources/ecc/skills/bun-runtime/agents/openai.yaml +7 -0
- package/resources/ecc/skills/coding-standards/SKILL.md +548 -0
- package/resources/ecc/skills/coding-standards/agents/openai.yaml +7 -0
- package/resources/ecc/skills/content-engine/SKILL.md +130 -0
- package/resources/ecc/skills/content-engine/agents/openai.yaml +7 -0
- package/resources/ecc/skills/crosspost/SKILL.md +110 -0
- package/resources/ecc/skills/crosspost/agents/openai.yaml +7 -0
- package/resources/ecc/skills/deep-research/SKILL.md +154 -0
- package/resources/ecc/skills/deep-research/agents/openai.yaml +7 -0
- package/resources/ecc/skills/dmux-workflows/SKILL.md +143 -0
- package/resources/ecc/skills/dmux-workflows/agents/openai.yaml +7 -0
- package/resources/ecc/skills/documentation-lookup/SKILL.md +89 -0
- package/resources/ecc/skills/documentation-lookup/agents/openai.yaml +7 -0
- package/resources/ecc/skills/e2e-testing/SKILL.md +325 -0
- package/resources/ecc/skills/e2e-testing/agents/openai.yaml +7 -0
- package/resources/ecc/skills/eval-harness/SKILL.md +235 -0
- package/resources/ecc/skills/eval-harness/agents/openai.yaml +7 -0
- package/resources/ecc/skills/everything-claude-code/SKILL.md +442 -0
- package/resources/ecc/skills/everything-claude-code/agents/openai.yaml +7 -0
- package/resources/ecc/skills/exa-search/SKILL.md +169 -0
- package/resources/ecc/skills/exa-search/agents/openai.yaml +7 -0
- package/resources/ecc/skills/fal-ai-media/SKILL.md +276 -0
- package/resources/ecc/skills/fal-ai-media/agents/openai.yaml +7 -0
- package/resources/ecc/skills/frontend-patterns/SKILL.md +647 -0
- package/resources/ecc/skills/frontend-patterns/agents/openai.yaml +7 -0
- package/resources/ecc/skills/frontend-slides/SKILL.md +183 -0
- package/resources/ecc/skills/frontend-slides/STYLE_PRESETS.md +330 -0
- package/resources/ecc/skills/frontend-slides/agents/openai.yaml +7 -0
- package/resources/ecc/skills/investor-materials/SKILL.md +95 -0
- package/resources/ecc/skills/investor-materials/agents/openai.yaml +7 -0
- package/resources/ecc/skills/investor-outreach/SKILL.md +90 -0
- package/resources/ecc/skills/investor-outreach/agents/openai.yaml +7 -0
- package/resources/ecc/skills/market-research/SKILL.md +74 -0
- package/resources/ecc/skills/market-research/agents/openai.yaml +7 -0
- package/resources/ecc/skills/mcp-server-patterns/SKILL.md +66 -0
- package/resources/ecc/skills/mcp-server-patterns/agents/openai.yaml +7 -0
- package/resources/ecc/skills/mle-workflow/SKILL.md +346 -0
- package/resources/ecc/skills/mle-workflow/agents/openai.yaml +7 -0
- package/resources/ecc/skills/nextjs-turbopack/SKILL.md +43 -0
- package/resources/ecc/skills/nextjs-turbopack/agents/openai.yaml +7 -0
- package/resources/ecc/skills/product-capability/SKILL.md +140 -0
- package/resources/ecc/skills/product-capability/agents/openai.yaml +7 -0
- package/resources/ecc/skills/security-review/SKILL.md +494 -0
- package/resources/ecc/skills/security-review/agents/openai.yaml +7 -0
- package/resources/ecc/skills/strategic-compact/SKILL.md +102 -0
- package/resources/ecc/skills/strategic-compact/agents/openai.yaml +7 -0
- package/resources/ecc/skills/tdd-workflow/SKILL.md +409 -0
- package/resources/ecc/skills/tdd-workflow/agents/openai.yaml +7 -0
- package/resources/ecc/skills/verification-loop/SKILL.md +125 -0
- package/resources/ecc/skills/verification-loop/agents/openai.yaml +7 -0
- package/resources/ecc/skills/video-editing/SKILL.md +307 -0
- package/resources/ecc/skills/video-editing/agents/openai.yaml +7 -0
- package/resources/ecc/skills/x-api/SKILL.md +229 -0
- package/resources/ecc/skills/x-api/agents/openai.yaml +7 -0
package/dist/codemaps.js
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Map System — Project structure tracking and context injection.
|
|
3
|
+
* Maintains a map of project structure, modules, and file relationships.
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
import { existsSync, readFileSync, readdirSync, writeFileSync, mkdirSync, statSync, } from 'node:fs';
|
|
7
|
+
import { join, relative, extname } from 'node:path';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
/**
|
|
10
|
+
* Detect language from file extension
|
|
11
|
+
*/
|
|
12
|
+
function detectLanguage(filePath) {
|
|
13
|
+
const ext = extname(filePath).toLowerCase();
|
|
14
|
+
const langMap = {
|
|
15
|
+
'.ts': 'typescript',
|
|
16
|
+
'.tsx': 'typescript',
|
|
17
|
+
'.js': 'javascript',
|
|
18
|
+
'.jsx': 'javascript',
|
|
19
|
+
'.py': 'python',
|
|
20
|
+
'.go': 'go',
|
|
21
|
+
'.rs': 'rust',
|
|
22
|
+
'.java': 'java',
|
|
23
|
+
'.c': 'c',
|
|
24
|
+
'.cpp': 'cpp',
|
|
25
|
+
'.h': 'c-header',
|
|
26
|
+
'.hpp': 'cpp-header',
|
|
27
|
+
'.json': 'json',
|
|
28
|
+
'.yaml': 'yaml',
|
|
29
|
+
'.yml': 'yaml',
|
|
30
|
+
'.md': 'markdown',
|
|
31
|
+
};
|
|
32
|
+
return langMap[ext] || 'unknown';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extract exports from a code file using regex
|
|
36
|
+
*/
|
|
37
|
+
function extractExports(content, language) {
|
|
38
|
+
const exports = new Set();
|
|
39
|
+
let match;
|
|
40
|
+
if (language === 'typescript' || language === 'javascript') {
|
|
41
|
+
// Match "export function name", "export const name", "export class name", etc.
|
|
42
|
+
const exportRegex = /export\s+(?:default\s+)?(?:async\s+)?(?:function|const|class|interface|type)\s+(\w+)/g;
|
|
43
|
+
while ((match = exportRegex.exec(content)) !== null) {
|
|
44
|
+
exports.add(match[1]);
|
|
45
|
+
}
|
|
46
|
+
// Match "export { name }"
|
|
47
|
+
const destructureRegex = /export\s*\{\s*([^}]+)\s*\}/g;
|
|
48
|
+
while ((match = destructureRegex.exec(content)) !== null) {
|
|
49
|
+
const names = match[1].split(',').map((n) => n.trim().split(' as ')[0]);
|
|
50
|
+
names.forEach((n) => n && exports.add(n));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (language === 'python') {
|
|
54
|
+
// Match "def name" and "class name" at module level
|
|
55
|
+
const defRegex = /^(?:def|class)\s+(\w+)/gm;
|
|
56
|
+
while ((match = defRegex.exec(content)) !== null) {
|
|
57
|
+
exports.add(match[1]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return Array.from(exports).slice(0, 20); // Limit to 20 exports
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Extract imports from a code file
|
|
64
|
+
*/
|
|
65
|
+
function extractImports(content, language) {
|
|
66
|
+
const imports = new Set();
|
|
67
|
+
let match;
|
|
68
|
+
if (language === 'typescript' || language === 'javascript') {
|
|
69
|
+
// Match "import { x } from 'y'"
|
|
70
|
+
const importRegex = /import\s+(?:\{([^}]+)\}|(\w+))\s+from\s+['"]([^'"]+)['"]/g;
|
|
71
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
72
|
+
const source = match[3];
|
|
73
|
+
if (!source.startsWith('.')) {
|
|
74
|
+
// External module
|
|
75
|
+
imports.add(source.split('/')[0]); // Get package name
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (language === 'python') {
|
|
80
|
+
// Match "import x" and "from x import y"
|
|
81
|
+
const importRegex = /^(?:import\s+(\w+)|from\s+(\w+)\s+import)/gm;
|
|
82
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
83
|
+
const module = match[1] || match[2];
|
|
84
|
+
if (module)
|
|
85
|
+
imports.add(module);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return Array.from(imports).slice(0, 15); // Limit to 15 imports
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Count lines in a file
|
|
92
|
+
*/
|
|
93
|
+
function countLines(filePath) {
|
|
94
|
+
try {
|
|
95
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
96
|
+
return content.split('\n').length;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Walk directory tree and collect file information
|
|
104
|
+
*/
|
|
105
|
+
function walkDirectory(dir, rootDir, ignorePatterns = ['node_modules', 'dist', '.git', 'build', 'coverage']) {
|
|
106
|
+
const entries = [];
|
|
107
|
+
const codeExtensions = [
|
|
108
|
+
'.ts',
|
|
109
|
+
'.tsx',
|
|
110
|
+
'.js',
|
|
111
|
+
'.jsx',
|
|
112
|
+
'.py',
|
|
113
|
+
'.go',
|
|
114
|
+
'.rs',
|
|
115
|
+
'.java',
|
|
116
|
+
'.c',
|
|
117
|
+
'.cpp',
|
|
118
|
+
'.h',
|
|
119
|
+
'.hpp',
|
|
120
|
+
'.json',
|
|
121
|
+
'.yaml',
|
|
122
|
+
'.yml',
|
|
123
|
+
];
|
|
124
|
+
try {
|
|
125
|
+
const files = readdirSync(dir, { withFileTypes: true });
|
|
126
|
+
for (const file of files) {
|
|
127
|
+
const fullPath = join(dir, file.name);
|
|
128
|
+
const relPath = relative(rootDir, fullPath);
|
|
129
|
+
// Check if should ignore
|
|
130
|
+
if (ignorePatterns.some((pattern) => relPath.includes(pattern))) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (file.isDirectory()) {
|
|
134
|
+
entries.push(...walkDirectory(fullPath, rootDir, ignorePatterns));
|
|
135
|
+
}
|
|
136
|
+
else if (codeExtensions.includes(extname(file.name))) {
|
|
137
|
+
try {
|
|
138
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
139
|
+
const language = detectLanguage(file.name);
|
|
140
|
+
const lineCount = content.split('\n').length;
|
|
141
|
+
const stats = statSync(fullPath);
|
|
142
|
+
entries.push({
|
|
143
|
+
path: relPath,
|
|
144
|
+
language,
|
|
145
|
+
lineCount,
|
|
146
|
+
exports: extractExports(content, language),
|
|
147
|
+
imports: extractImports(content, language),
|
|
148
|
+
size: stats.size,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// Skip files we can't read
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Ignore directory read errors
|
|
159
|
+
}
|
|
160
|
+
return entries;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Group files into modules by directory structure
|
|
164
|
+
*/
|
|
165
|
+
function groupIntoModules(files) {
|
|
166
|
+
const modules = new Map();
|
|
167
|
+
for (const file of files) {
|
|
168
|
+
const parts = file.path.split('/');
|
|
169
|
+
const moduleName = parts.length > 1 ? parts[0] : 'root';
|
|
170
|
+
if (!modules.has(moduleName)) {
|
|
171
|
+
modules.set(moduleName, []);
|
|
172
|
+
}
|
|
173
|
+
modules.get(moduleName).push(file.path);
|
|
174
|
+
}
|
|
175
|
+
return Array.from(modules.entries()).map(([name, files]) => ({
|
|
176
|
+
name,
|
|
177
|
+
files,
|
|
178
|
+
description: `Module ${name} with ${files.length} files`,
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generate a code map by scanning the project
|
|
183
|
+
*/
|
|
184
|
+
export function generateCodeMap(cwd) {
|
|
185
|
+
if (!existsSync(cwd)) {
|
|
186
|
+
throw new Error(`Directory not found: ${cwd}`);
|
|
187
|
+
}
|
|
188
|
+
const files = walkDirectory(cwd, cwd);
|
|
189
|
+
const modules = groupIntoModules(files);
|
|
190
|
+
const totalLines = files.reduce((sum, f) => sum + f.lineCount, 0);
|
|
191
|
+
return {
|
|
192
|
+
projectRoot: cwd,
|
|
193
|
+
files,
|
|
194
|
+
modules,
|
|
195
|
+
generatedAt: new Date().toISOString(),
|
|
196
|
+
totalFiles: files.length,
|
|
197
|
+
totalLines,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Save code map to disk
|
|
202
|
+
*/
|
|
203
|
+
export function saveCodeMap(cwd, map) {
|
|
204
|
+
const codemapDir = join(cwd, '.crowcoder');
|
|
205
|
+
if (!existsSync(codemapDir)) {
|
|
206
|
+
mkdirSync(codemapDir, { recursive: true });
|
|
207
|
+
}
|
|
208
|
+
const codemapFile = join(codemapDir, 'codemap.json');
|
|
209
|
+
writeFileSync(codemapFile, JSON.stringify(map, null, 2), 'utf-8');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Load code map from disk
|
|
213
|
+
*/
|
|
214
|
+
export function loadCodeMap(cwd) {
|
|
215
|
+
const codemapFile = join(cwd, '.crowcoder', 'codemap.json');
|
|
216
|
+
if (!existsSync(codemapFile)) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const content = readFileSync(codemapFile, 'utf-8');
|
|
221
|
+
return JSON.parse(content);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Check if code map is stale (any source files modified since generation)
|
|
229
|
+
*/
|
|
230
|
+
export function isCodeMapStale(cwd) {
|
|
231
|
+
const map = loadCodeMap(cwd);
|
|
232
|
+
if (!map)
|
|
233
|
+
return true;
|
|
234
|
+
const mapTime = new Date(map.generatedAt).getTime();
|
|
235
|
+
try {
|
|
236
|
+
// Check if any source files are newer than the map
|
|
237
|
+
const result = execSync(`find "${cwd}/src" -type f \\( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \\) -newermt "${map.generatedAt}" 2>/dev/null | head -1`, { encoding: 'utf-8', timeout: 5_000 });
|
|
238
|
+
return result.trim().length > 0;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Pretty-print the code map
|
|
246
|
+
*/
|
|
247
|
+
export function printCodeMap(map) {
|
|
248
|
+
console.log(chalk.cyan('\n📊 Code Map'));
|
|
249
|
+
console.log(chalk.gray(`Generated: ${new Date(map.generatedAt).toLocaleString()}\n`));
|
|
250
|
+
console.log(chalk.blue('Project Statistics:'));
|
|
251
|
+
console.log(chalk.gray(` Total files: ${map.totalFiles}`));
|
|
252
|
+
console.log(chalk.gray(` Total lines: ${map.totalLines.toLocaleString()}`));
|
|
253
|
+
console.log(chalk.gray(` Modules: ${map.modules.length}\n`));
|
|
254
|
+
console.log(chalk.blue('Modules:'));
|
|
255
|
+
for (const module of map.modules.slice(0, 10)) {
|
|
256
|
+
const files = module.files.slice(0, 3).join(', ');
|
|
257
|
+
const more = module.files.length > 3 ? ` (+${module.files.length - 3} more)` : '';
|
|
258
|
+
console.log(chalk.gray(` ${module.name}: ${files}${more}`));
|
|
259
|
+
}
|
|
260
|
+
console.log(chalk.blue('\nTop Files (by line count):'));
|
|
261
|
+
const sorted = [...map.files].sort((a, b) => b.lineCount - a.lineCount);
|
|
262
|
+
for (const file of sorted.slice(0, 10)) {
|
|
263
|
+
console.log(chalk.gray(` ${file.path}: ${file.lineCount} lines`));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Build a code map context string for system prompt injection
|
|
268
|
+
*/
|
|
269
|
+
export function buildCodemapContext(cwd) {
|
|
270
|
+
const map = loadCodeMap(cwd);
|
|
271
|
+
if (!map) {
|
|
272
|
+
return '';
|
|
273
|
+
}
|
|
274
|
+
let context = '\n## Project Structure\n';
|
|
275
|
+
context += `**Statistics:**\n`;
|
|
276
|
+
context += `- Total files: ${map.totalFiles}\n`;
|
|
277
|
+
context += `- Total lines of code: ${map.totalLines.toLocaleString()}\n`;
|
|
278
|
+
context += `- Modules: ${map.modules.length}\n\n`;
|
|
279
|
+
context += `**Module Overview:**\n`;
|
|
280
|
+
for (const module of map.modules) {
|
|
281
|
+
context += `- \`${module.name}\`: ${module.files.length} files\n`;
|
|
282
|
+
}
|
|
283
|
+
context += `\n**Key Exports:**\n`;
|
|
284
|
+
const topExports = map.files
|
|
285
|
+
.filter((f) => f.exports.length > 0)
|
|
286
|
+
.slice(0, 5)
|
|
287
|
+
.flatMap((f) => f.exports.map((e) => `\`${f.path}#${e}\``));
|
|
288
|
+
if (topExports.length > 0) {
|
|
289
|
+
context += topExports.join(', ') + '\n';
|
|
290
|
+
}
|
|
291
|
+
context += `\n**External Dependencies:**\n`;
|
|
292
|
+
const deps = new Set();
|
|
293
|
+
for (const file of map.files) {
|
|
294
|
+
for (const imp of file.imports) {
|
|
295
|
+
deps.add(imp);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
Array.from(deps)
|
|
299
|
+
.slice(0, 15)
|
|
300
|
+
.forEach((dep) => {
|
|
301
|
+
context += `- \`${dep}\`\n`;
|
|
302
|
+
});
|
|
303
|
+
return context;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Print code map generation status
|
|
307
|
+
*/
|
|
308
|
+
export function printCodemapStatus(cwd) {
|
|
309
|
+
const map = loadCodeMap(cwd);
|
|
310
|
+
const stale = isCodeMapStale(cwd);
|
|
311
|
+
console.log(chalk.cyan('\n📋 Code Map Status'));
|
|
312
|
+
if (map) {
|
|
313
|
+
console.log(chalk.green(`✓ Code map exists (${map.totalFiles} files)`));
|
|
314
|
+
console.log(chalk.gray(` Generated: ${new Date(map.generatedAt).toLocaleString()}`));
|
|
315
|
+
if (stale) {
|
|
316
|
+
console.log(chalk.yellow(' ⚠ Code map is stale (source files have been modified)'));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.log(chalk.gray('✗ No code map found'));
|
|
321
|
+
console.log(chalk.gray(' Run: generateCodeMap(cwd) then saveCodeMap(cwd, map)'));
|
|
322
|
+
}
|
|
323
|
+
console.log();
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=codemaps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codemaps.js","sourceRoot":"","sources":["../src/codemaps.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAqB,MAAM,WAAW,CAAC;AACvE,OAAO,KAAK,MAAM,OAAO,CAAC;AA2B1B;;GAEG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,OAAO,GAA2B;QACtC,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,UAAU;KAClB,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,QAAgB;IACvD,MAAM,OAAO,GAAgB,IAAI,GAAG,EAAE,CAAC;IACvC,IAAI,KAA6B,CAAC;IAElC,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC3D,+EAA+E;QAC/E,MAAM,WAAW,GAAG,uFAAuF,CAAC;QAC5G,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;QAED,0BAA0B;QAC1B,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;QACvD,OAAO,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,oDAAoD;QACpD,MAAM,QAAQ,GAAG,0BAA0B,CAAC;QAC5C,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB;AACjE,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,QAAgB;IACvD,MAAM,OAAO,GAAgB,IAAI,GAAG,EAAE,CAAC;IACvC,IAAI,KAA6B,CAAC;IAElC,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC3D,gCAAgC;QAChC,MAAM,WAAW,GACf,2DAA2D,CAAC;QAC9D,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,kBAAkB;gBAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB;YACxD,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,yCAAyC;QACzC,MAAM,WAAW,GAAG,6CAA6C,CAAC;QAClE,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,MAAM;gBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB;AACjE,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,QAAgB;IAClC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,GAAW,EACX,OAAe,EACf,iBAA2B,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC;IAEhF,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,cAAc,GAAG;QACrB,KAAK;QACL,MAAM;QACN,KAAK;QACL,MAAM;QACN,KAAK;QACL,KAAK;QACL,KAAK;QACL,OAAO;QACP,IAAI;QACJ,MAAM;QACN,IAAI;QACJ,MAAM;QACN,OAAO;QACP,OAAO;QACP,MAAM;KACP,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAExD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAE5C,yBAAyB;YACzB,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBAChE,SAAS;YACX,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;YACpE,CAAC;iBAAM,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;oBAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBAEjC,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,QAAQ;wBACR,SAAS;wBACT,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC;wBAC1C,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC;wBAC1C,IAAI,EAAE,KAAK,CAAC,IAAI;qBACjB,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,2BAA2B;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAkB;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAExD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3D,IAAI;QACJ,KAAK;QACL,WAAW,EAAE,UAAU,IAAI,SAAS,KAAK,CAAC,MAAM,QAAQ;KACzD,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAElE,OAAO;QACL,WAAW,EAAE,GAAG;QAChB,KAAK;QACL,OAAO;QACP,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,GAAY;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACrD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;IAC5D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,mDAAmD;QACnD,MAAM,MAAM,GAAG,QAAQ,CACrB,SAAS,GAAG,kGAAkG,GAAG,CAAC,WAAW,yBAAyB,EACtJ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CACtC,CAAC;QAEF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;IAEtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAE9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,KAAK,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IACxE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,OAAO,GAAG,0BAA0B,CAAC;IAEzC,OAAO,IAAI,mBAAmB,CAAC;IAC/B,OAAO,IAAI,kBAAkB,GAAG,CAAC,UAAU,IAAI,CAAC;IAChD,OAAO,IAAI,0BAA0B,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE,IAAI,CAAC;IACzE,OAAO,IAAI,cAAc,GAAG,CAAC,OAAO,CAAC,MAAM,MAAM,CAAC;IAElD,OAAO,IAAI,wBAAwB,CAAC;IACpC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,OAAO,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC;IACpE,CAAC;IAED,OAAO,IAAI,sBAAsB,CAAC;IAClC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACnC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,gCAAgC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,OAAO,IAAI,OAAO,GAAG,MAAM,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAElC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAChD,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,UAAU,SAAS,CAAC,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;QACtF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Message, CrowcoderConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Estimate tokens accounting for content type and message overhead.
|
|
4
|
+
* - English prose: ~3.5 chars per token
|
|
5
|
+
* - Code: ~3 chars per token (more special chars)
|
|
6
|
+
* - Message overhead: ~4 tokens per message for role/structure
|
|
7
|
+
*/
|
|
8
|
+
export declare function estimateTokens(messages: Message[]): number;
|
|
9
|
+
export interface CompactionConfig {
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
triggerTokens: number;
|
|
12
|
+
keepRecentMessages: number;
|
|
13
|
+
targetTokens: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEFAULT_COMPACTION: CompactionConfig;
|
|
16
|
+
export declare function shouldCompact(messages: Message[], config: CompactionConfig): boolean;
|
|
17
|
+
export declare function getCompactionStats(messages: Message[]): {
|
|
18
|
+
messageCount: number;
|
|
19
|
+
estimatedTokens: number;
|
|
20
|
+
needsCompaction: boolean;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Compact messages by summarizing older ones with the AI model.
|
|
24
|
+
* Returns a new messages array with a summary + recent messages.
|
|
25
|
+
*/
|
|
26
|
+
export declare function compactMessages(messages: Message[], config: CrowcoderConfig, compactionConfig?: CompactionConfig): Promise<Message[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Quick local compaction without API call — just truncates tool results.
|
|
29
|
+
*/
|
|
30
|
+
export declare function quickCompact(messages: Message[]): Message[];
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context compaction — auto-summarize old messages when context grows large.
|
|
3
|
+
* Keeps recent messages intact, summarizes older ones to free token space.
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { streamChat } from './api.js';
|
|
7
|
+
/**
|
|
8
|
+
* Estimate tokens accounting for content type and message overhead.
|
|
9
|
+
* - English prose: ~3.5 chars per token
|
|
10
|
+
* - Code: ~3 chars per token (more special chars)
|
|
11
|
+
* - Message overhead: ~4 tokens per message for role/structure
|
|
12
|
+
*/
|
|
13
|
+
export function estimateTokens(messages) {
|
|
14
|
+
let tokens = 0;
|
|
15
|
+
for (const m of messages) {
|
|
16
|
+
// Add message overhead (role, message structure, etc)
|
|
17
|
+
tokens += 4;
|
|
18
|
+
if (typeof m.content === 'string' && m.content) {
|
|
19
|
+
// Detect if content is code (common code indicators)
|
|
20
|
+
const isCode = /^(```| | \t|function|class|def|const|let|var|import|export|fn |pub |async|await)/m.test(m.content);
|
|
21
|
+
const charsPerToken = isCode ? 3 : 3.5;
|
|
22
|
+
tokens += Math.ceil(m.content.length / charsPerToken);
|
|
23
|
+
}
|
|
24
|
+
if (m.tool_calls) {
|
|
25
|
+
const toolJson = JSON.stringify(m.tool_calls);
|
|
26
|
+
// Tool calls are structured data (mostly code), use 3 chars per token
|
|
27
|
+
tokens += Math.ceil(toolJson.length / 3);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return tokens;
|
|
31
|
+
}
|
|
32
|
+
export const DEFAULT_COMPACTION = {
|
|
33
|
+
enabled: true,
|
|
34
|
+
triggerTokens: 80_000, // ~80k tokens triggers compaction
|
|
35
|
+
keepRecentMessages: 10, // keep last 10 messages verbatim
|
|
36
|
+
targetTokens: 20_000, // aim to reduce to ~20k tokens
|
|
37
|
+
};
|
|
38
|
+
export function shouldCompact(messages, config) {
|
|
39
|
+
if (!config.enabled)
|
|
40
|
+
return false;
|
|
41
|
+
return estimateTokens(messages) > config.triggerTokens;
|
|
42
|
+
}
|
|
43
|
+
export function getCompactionStats(messages) {
|
|
44
|
+
const tokens = estimateTokens(messages);
|
|
45
|
+
return {
|
|
46
|
+
messageCount: messages.length,
|
|
47
|
+
estimatedTokens: tokens,
|
|
48
|
+
needsCompaction: tokens > DEFAULT_COMPACTION.triggerTokens,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Compact messages by summarizing older ones with the AI model.
|
|
53
|
+
* Returns a new messages array with a summary + recent messages.
|
|
54
|
+
*/
|
|
55
|
+
export async function compactMessages(messages, config, compactionConfig = DEFAULT_COMPACTION) {
|
|
56
|
+
if (messages.length <= compactionConfig.keepRecentMessages) {
|
|
57
|
+
return messages;
|
|
58
|
+
}
|
|
59
|
+
const keepCount = compactionConfig.keepRecentMessages;
|
|
60
|
+
const oldMessages = messages.slice(0, -keepCount);
|
|
61
|
+
const recentMessages = messages.slice(-keepCount);
|
|
62
|
+
console.log(chalk.dim(` [compaction] Summarizing ${oldMessages.length} old messages...`));
|
|
63
|
+
// Build a summary request
|
|
64
|
+
const summaryPrompt = [
|
|
65
|
+
{
|
|
66
|
+
role: 'system',
|
|
67
|
+
content: `You are a conversation summarizer. Summarize the following conversation between a user and an AI coding assistant.
|
|
68
|
+
Focus on:
|
|
69
|
+
- What files were read, created, or modified
|
|
70
|
+
- Key decisions made
|
|
71
|
+
- Current state of the work
|
|
72
|
+
- Important context the assistant needs to continue
|
|
73
|
+
|
|
74
|
+
Be concise but thorough. Output a structured summary.`,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
role: 'user',
|
|
78
|
+
content: oldMessages
|
|
79
|
+
.filter((m) => m.role === 'user' || m.role === 'assistant')
|
|
80
|
+
.map((m) => `[${m.role}]: ${typeof m.content === 'string' ? m.content?.slice(0, 2000) : '(tool call)'}`)
|
|
81
|
+
.join('\n\n'),
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
try {
|
|
85
|
+
let summary = '';
|
|
86
|
+
for await (const event of streamChat(config, summaryPrompt, [])) {
|
|
87
|
+
if (event.type === 'text' && event.content) {
|
|
88
|
+
summary += event.content;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (!summary) {
|
|
92
|
+
console.log(chalk.yellow(' [compaction] Summary generation failed, keeping messages'));
|
|
93
|
+
return messages;
|
|
94
|
+
}
|
|
95
|
+
// Build compacted message array
|
|
96
|
+
// Use 'assistant' role instead of 'system' since some providers ignore system messages mid-conversation
|
|
97
|
+
const compactedMessages = [
|
|
98
|
+
{
|
|
99
|
+
role: 'assistant',
|
|
100
|
+
content: `<<CONVERSATION SUMMARY - ${oldMessages.length} messages compacted>>\n${summary}`,
|
|
101
|
+
},
|
|
102
|
+
...recentMessages,
|
|
103
|
+
];
|
|
104
|
+
const oldTokens = estimateTokens(messages);
|
|
105
|
+
const newTokens = estimateTokens(compactedMessages);
|
|
106
|
+
console.log(chalk.green(` [compaction] Reduced: ~${oldTokens.toLocaleString()} → ~${newTokens.toLocaleString()} tokens (${Math.round((1 - newTokens / oldTokens) * 100)}% reduction)`));
|
|
107
|
+
return compactedMessages;
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
console.log(chalk.yellow(` [compaction] Error: ${err instanceof Error ? err.message : err}`));
|
|
111
|
+
return messages;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Quick local compaction without API call — just truncates tool results.
|
|
116
|
+
*/
|
|
117
|
+
export function quickCompact(messages) {
|
|
118
|
+
return messages.map((m) => {
|
|
119
|
+
if (m.role === 'tool' && typeof m.content === 'string' && m.content.length > 5000) {
|
|
120
|
+
return { ...m, content: m.content.slice(0, 2000) + '\n... (truncated)' };
|
|
121
|
+
}
|
|
122
|
+
return m;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=compaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.js","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CrowcoderConfig } from './types.js';
|
|
2
|
+
export declare function getConfigDir(): string;
|
|
3
|
+
export declare function loadConfig(): CrowcoderConfig;
|
|
4
|
+
export declare function saveConfig(config: CrowcoderConfig): void;
|
|
5
|
+
export declare function configExists(): boolean;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
// CROWCODER_HOME lets tests / sandboxed runs point at a temp config dir
|
|
5
|
+
// instead of clobbering the user's real ~/.crowcoder/config.json. Default
|
|
6
|
+
// is the real home dir so production behavior is unchanged.
|
|
7
|
+
const CONFIG_DIR = process.env.CROWCODER_HOME || join(homedir(), '.crowcoder');
|
|
8
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
9
|
+
const DEFAULT_CONFIG = {
|
|
10
|
+
apiKey: '',
|
|
11
|
+
baseURL: 'https://openrouter.ai/api/v1',
|
|
12
|
+
model: 'anthropic/claude-sonnet-4',
|
|
13
|
+
provider: 'OpenRouter',
|
|
14
|
+
maxTokens: 8192,
|
|
15
|
+
temperature: 0.3,
|
|
16
|
+
permissionMode: 'ask',
|
|
17
|
+
};
|
|
18
|
+
export function getConfigDir() {
|
|
19
|
+
return CONFIG_DIR;
|
|
20
|
+
}
|
|
21
|
+
export function loadConfig() {
|
|
22
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
23
|
+
return { ...DEFAULT_CONFIG };
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const raw = readFileSync(CONFIG_FILE, 'utf-8');
|
|
27
|
+
const loaded = JSON.parse(raw);
|
|
28
|
+
const config = { ...DEFAULT_CONFIG, ...loaded };
|
|
29
|
+
validateConfig(config);
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.warn(`Warning: Failed to load config: ${err instanceof Error ? err.message : err}`);
|
|
34
|
+
return { ...DEFAULT_CONFIG };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function validateConfig(config) {
|
|
38
|
+
// Validate baseURL
|
|
39
|
+
if (config.baseURL && typeof config.baseURL === 'string') {
|
|
40
|
+
try {
|
|
41
|
+
new URL(config.baseURL);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
console.warn(`Warning: Invalid baseURL: ${config.baseURL}`);
|
|
45
|
+
config.baseURL = DEFAULT_CONFIG.baseURL;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Validate model
|
|
49
|
+
if (!config.model || typeof config.model !== 'string' || config.model.trim() === '') {
|
|
50
|
+
console.warn('Warning: Invalid model name, using default');
|
|
51
|
+
config.model = DEFAULT_CONFIG.model;
|
|
52
|
+
}
|
|
53
|
+
// Validate permissionMode
|
|
54
|
+
const validModes = ['ask', 'auto', 'yolo'];
|
|
55
|
+
if (!validModes.includes(config.permissionMode)) {
|
|
56
|
+
console.warn(`Warning: Invalid permissionMode: ${config.permissionMode}, using 'ask'`);
|
|
57
|
+
config.permissionMode = 'ask';
|
|
58
|
+
}
|
|
59
|
+
// Warn on unexpected fields
|
|
60
|
+
const expectedFields = new Set(['apiKey', 'baseURL', 'model', 'provider', 'maxTokens', 'temperature', 'permissionMode', 'dryRun', 'theme', 'showThinking']);
|
|
61
|
+
for (const key in config) {
|
|
62
|
+
if (!expectedFields.has(key)) {
|
|
63
|
+
console.warn(`Warning: Unexpected config field: ${key}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export function saveConfig(config) {
|
|
68
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
69
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
export function configExists() {
|
|
72
|
+
const cfg = loadConfig();
|
|
73
|
+
return !!(cfg.apiKey || !requiresKey(cfg));
|
|
74
|
+
}
|
|
75
|
+
function requiresKey(cfg) {
|
|
76
|
+
// Local providers don't need API keys
|
|
77
|
+
return !cfg.baseURL.includes('localhost') && !cfg.baseURL.includes('127.0.0.1');
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|