gencode-ai 0.1.3 ā 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/agent/agent.d.ts +44 -2
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +130 -11
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/types.d.ts +11 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/checkpointing/checkpoint-manager.d.ts +87 -0
- package/dist/checkpointing/checkpoint-manager.d.ts.map +1 -0
- package/dist/checkpointing/checkpoint-manager.js +281 -0
- package/dist/checkpointing/checkpoint-manager.js.map +1 -0
- package/dist/checkpointing/index.d.ts +29 -0
- package/dist/checkpointing/index.d.ts.map +1 -0
- package/dist/checkpointing/index.js +29 -0
- package/dist/checkpointing/index.js.map +1 -0
- package/dist/checkpointing/types.d.ts +98 -0
- package/dist/checkpointing/types.d.ts.map +1 -0
- package/dist/checkpointing/types.js +7 -0
- package/dist/checkpointing/types.js.map +1 -0
- package/dist/cli/components/App.d.ts.map +1 -1
- package/dist/cli/components/App.js +171 -14
- 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 +5 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -1
- package/dist/cli/components/Messages.d.ts +7 -1
- package/dist/cli/components/Messages.d.ts.map +1 -1
- package/dist/cli/components/Messages.js +12 -3
- package/dist/cli/components/Messages.js.map +1 -1
- package/dist/cli/components/ModeIndicator.d.ts +42 -0
- package/dist/cli/components/ModeIndicator.d.ts.map +1 -0
- package/dist/cli/components/ModeIndicator.js +52 -0
- package/dist/cli/components/ModeIndicator.js.map +1 -0
- package/dist/cli/components/ModelSelector.d.ts +4 -3
- package/dist/cli/components/ModelSelector.d.ts.map +1 -1
- package/dist/cli/components/ModelSelector.js +54 -37
- package/dist/cli/components/ModelSelector.js.map +1 -1
- package/dist/cli/components/PlanApproval.d.ts +36 -0
- package/dist/cli/components/PlanApproval.d.ts.map +1 -0
- package/dist/cli/components/PlanApproval.js +154 -0
- package/dist/cli/components/PlanApproval.js.map +1 -0
- package/dist/cli/components/ProviderManager.d.ts +2 -2
- package/dist/cli/components/ProviderManager.d.ts.map +1 -1
- package/dist/cli/components/ProviderManager.js +137 -156
- package/dist/cli/components/ProviderManager.js.map +1 -1
- package/dist/cli/components/theme.d.ts +2 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +3 -0
- package/dist/cli/components/theme.js.map +1 -1
- package/dist/cli/index.js +30 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/levels.d.ts +5 -5
- package/dist/config/levels.d.ts.map +1 -1
- package/dist/config/levels.js +20 -20
- package/dist/config/levels.js.map +1 -1
- package/dist/config/merger.js +1 -1
- package/dist/config/merger.js.map +1 -1
- package/dist/config/providers-config.d.ts +8 -5
- package/dist/config/providers-config.d.ts.map +1 -1
- package/dist/config/providers-config.js +19 -22
- package/dist/config/providers-config.js.map +1 -1
- package/dist/config/test-utils.d.ts +2 -2
- package/dist/config/test-utils.d.ts.map +1 -1
- package/dist/config/test-utils.js +4 -4
- package/dist/config/test-utils.js.map +1 -1
- package/dist/config/types.d.ts +23 -17
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +14 -14
- package/dist/config/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/memory-manager.d.ts +25 -12
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +241 -112
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/memory/test-utils.d.ts +1 -1
- package/dist/memory/test-utils.d.ts.map +1 -1
- package/dist/memory/test-utils.js +3 -3
- package/dist/memory/test-utils.js.map +1 -1
- package/dist/memory/types.d.ts +20 -10
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +13 -13
- package/dist/memory/types.js.map +1 -1
- package/dist/migration/migrate.d.ts +24 -0
- package/dist/migration/migrate.d.ts.map +1 -0
- package/dist/migration/migrate.js +164 -0
- package/dist/migration/migrate.js.map +1 -0
- package/dist/permissions/persistence.d.ts +2 -2
- package/dist/permissions/persistence.js +4 -4
- package/dist/permissions/persistence.js.map +1 -1
- package/dist/planning/index.d.ts +13 -0
- package/dist/planning/index.d.ts.map +1 -0
- package/dist/planning/index.js +15 -0
- package/dist/planning/index.js.map +1 -0
- package/dist/planning/plan-file.d.ts +59 -0
- package/dist/planning/plan-file.d.ts.map +1 -0
- package/dist/planning/plan-file.js +278 -0
- package/dist/planning/plan-file.js.map +1 -0
- package/dist/planning/state.d.ts +127 -0
- package/dist/planning/state.d.ts.map +1 -0
- package/dist/planning/state.js +261 -0
- package/dist/planning/state.js.map +1 -0
- package/dist/planning/tools/enter-plan-mode.d.ts +25 -0
- package/dist/planning/tools/enter-plan-mode.d.ts.map +1 -0
- package/dist/planning/tools/enter-plan-mode.js +98 -0
- package/dist/planning/tools/enter-plan-mode.js.map +1 -0
- package/dist/planning/tools/exit-plan-mode.d.ts +24 -0
- package/dist/planning/tools/exit-plan-mode.d.ts.map +1 -0
- package/dist/planning/tools/exit-plan-mode.js +149 -0
- package/dist/planning/tools/exit-plan-mode.js.map +1 -0
- package/dist/planning/types.d.ts +100 -0
- package/dist/planning/types.d.ts.map +1 -0
- package/dist/planning/types.js +28 -0
- package/dist/planning/types.js.map +1 -0
- package/dist/pricing/calculator.d.ts +21 -0
- package/dist/pricing/calculator.d.ts.map +1 -0
- package/dist/pricing/calculator.js +59 -0
- package/dist/pricing/calculator.js.map +1 -0
- package/dist/pricing/index.d.ts +7 -0
- package/dist/pricing/index.d.ts.map +1 -0
- package/dist/pricing/index.js +7 -0
- package/dist/pricing/index.js.map +1 -0
- package/dist/pricing/models.d.ts +20 -0
- package/dist/pricing/models.d.ts.map +1 -0
- package/dist/pricing/models.js +322 -0
- package/dist/pricing/models.js.map +1 -0
- package/dist/pricing/types.d.ts +30 -0
- package/dist/pricing/types.d.ts.map +1 -0
- package/dist/pricing/types.js +5 -0
- package/dist/pricing/types.js.map +1 -0
- package/dist/prompts/index.d.ts +5 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +11 -8
- package/dist/prompts/index.js.map +1 -1
- package/dist/providers/anthropic.d.ts +2 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +24 -10
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/gemini.d.ts +2 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +28 -14
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/index.d.ts +20 -10
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +48 -24
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai.d.ts +2 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +19 -8
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +48 -34
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +72 -88
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/store.d.ts +43 -17
- package/dist/providers/store.d.ts.map +1 -1
- package/dist/providers/store.js +112 -19
- package/dist/providers/store.js.map +1 -1
- package/dist/providers/types.d.ts +25 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/vertex-ai.d.ts +15 -7
- package/dist/providers/vertex-ai.d.ts.map +1 -1
- package/dist/providers/vertex-ai.js +63 -23
- package/dist/providers/vertex-ai.js.map +1 -1
- package/dist/session/manager.d.ts +4 -0
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +8 -0
- package/dist/session/manager.js.map +1 -1
- package/dist/session/types.js +1 -1
- package/dist/session/types.js.map +1 -1
- package/dist/tools/index.d.ts +7 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +13 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +79 -2
- package/dist/tools/registry.js.map +1 -1
- package/docs/config-system-comparison.md +50 -50
- package/docs/cost-tracking-comparison.md +904 -0
- package/docs/memory-system.md +124 -31
- package/docs/operating-modes.md +96 -0
- package/docs/permissions.md +2 -2
- package/docs/proposals/0006-memory-system.md +4 -4
- package/docs/proposals/0008-checkpointing.md +109 -2
- package/docs/proposals/0011-custom-commands.md +2 -1
- package/docs/proposals/0021-skills-system.md +2 -1
- package/docs/proposals/0023-permission-enhancements.md +2 -2
- package/docs/proposals/0025-cost-tracking.md +60 -2
- package/docs/proposals/0033-enterprise-deployment.md +1 -1
- package/docs/proposals/0041-configuration-system.md +17 -19
- package/docs/proposals/0042-prompt-optimization.md +17 -9
- package/docs/proposals/README.md +6 -6
- package/docs/providers.md +94 -9
- package/examples/test-checkpointing.ts +121 -0
- package/examples/test-cost-tracking.ts +77 -0
- package/examples/test-interrupt-cleanup.ts +94 -0
- package/package.json +3 -2
- package/scripts/migrate.ts +449 -0
- package/src/agent/agent.ts +161 -12
- package/src/agent/types.ts +11 -1
- package/src/checkpointing/checkpoint-manager.ts +327 -0
- package/src/checkpointing/index.ts +45 -0
- package/src/checkpointing/types.ts +104 -0
- package/src/cli/components/App.tsx +221 -13
- package/src/cli/components/CommandSuggestions.tsx +5 -0
- package/src/cli/components/Messages.tsx +24 -5
- package/src/cli/components/ModeIndicator.tsx +174 -0
- package/src/cli/components/ModelSelector.tsx +62 -43
- package/src/cli/components/PlanApproval.tsx +327 -0
- package/src/cli/components/ProviderManager.tsx +278 -323
- package/src/cli/components/theme.ts +3 -0
- package/src/cli/index.tsx +36 -17
- package/src/config/index.ts +5 -3
- package/src/config/levels.test.ts +22 -22
- package/src/config/levels.ts +22 -22
- package/src/config/loader.test.ts +14 -14
- package/src/config/manager.test.ts +19 -19
- package/src/config/merger.test.ts +23 -23
- package/src/config/merger.ts +1 -1
- package/src/config/providers-config.ts +23 -21
- package/src/config/test-utils.ts +6 -6
- package/src/config/types.ts +30 -20
- package/src/index.ts +15 -0
- package/src/memory/memory-manager.test.ts +242 -24
- package/src/memory/memory-manager.ts +270 -141
- package/src/memory/test-utils.ts +4 -4
- package/src/memory/types.ts +28 -17
- package/src/permissions/persistence.ts +4 -4
- package/src/planning/index.ts +53 -0
- package/src/planning/plan-file.ts +326 -0
- package/src/planning/state.ts +305 -0
- package/src/planning/tools/enter-plan-mode.ts +111 -0
- package/src/planning/tools/exit-plan-mode.ts +170 -0
- package/src/planning/types.ts +150 -0
- package/src/pricing/calculator.ts +71 -0
- package/src/pricing/index.ts +7 -0
- package/src/pricing/models.ts +334 -0
- package/src/pricing/types.ts +32 -0
- package/src/prompts/index.ts +13 -9
- package/src/providers/anthropic.ts +30 -10
- package/src/providers/gemini.ts +34 -14
- package/src/providers/index.ts +76 -33
- package/src/providers/openai.ts +26 -8
- package/src/providers/registry.ts +116 -111
- package/src/providers/store.ts +130 -28
- package/src/providers/types.ts +36 -1
- package/src/providers/vertex-ai.ts +70 -23
- package/src/session/manager.ts +9 -0
- package/src/session/types.ts +1 -1
- package/src/tools/index.ts +8 -0
- package/src/tools/registry.ts +95 -2
- package/.gencode/settings.local.json +0 -7
- package/CLAUDE.md +0 -86
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gencode-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "An open-source AI assistant for your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"start": "node dist/cli/index.js",
|
|
15
15
|
"start:dev": "npx tsx src/cli/index.tsx",
|
|
16
16
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
17
|
-
"example": "npx tsx examples/basic.ts"
|
|
17
|
+
"example": "npx tsx examples/basic.ts",
|
|
18
|
+
"migrate": "npx tsx scripts/migrate.ts"
|
|
18
19
|
},
|
|
19
20
|
"keywords": [
|
|
20
21
|
"agent",
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Migration Script: .gencode ā .gen
|
|
4
|
+
*
|
|
5
|
+
* Migrates GenCode configuration from old naming to new:
|
|
6
|
+
* - ~/.gencode/ ā ~/.gen/
|
|
7
|
+
* - ./.gencode/ ā ./.gen/
|
|
8
|
+
* - AGENT.md ā GEN.md
|
|
9
|
+
* - AGENT.local.md ā GEN.local.md
|
|
10
|
+
* - providers.json: Old format ā New format (provider:authMethod keys)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* npm run migrate # Run migration
|
|
14
|
+
* tsx scripts/migrate.ts # Direct execution
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import * as fs from 'fs/promises';
|
|
18
|
+
import * as path from 'path';
|
|
19
|
+
import * as os from 'os';
|
|
20
|
+
import * as readline from 'readline';
|
|
21
|
+
|
|
22
|
+
interface MigrationResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
migratedPaths: string[];
|
|
25
|
+
errors: string[];
|
|
26
|
+
warnings: string[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if a path exists
|
|
31
|
+
*/
|
|
32
|
+
async function pathExists(p: string): Promise<boolean> {
|
|
33
|
+
try {
|
|
34
|
+
await fs.access(p);
|
|
35
|
+
return true;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Rename files within a directory (AGENT.md ā GEN.md, AGENT.local.md ā GEN.local.md)
|
|
43
|
+
*/
|
|
44
|
+
async function renameFilesInDir(dir: string): Promise<string[]> {
|
|
45
|
+
const renamed: string[] = [];
|
|
46
|
+
|
|
47
|
+
// Rename AGENT.md ā GEN.md
|
|
48
|
+
const agentPath = path.join(dir, 'AGENT.md');
|
|
49
|
+
const genPath = path.join(dir, 'GEN.md');
|
|
50
|
+
|
|
51
|
+
if (await pathExists(agentPath)) {
|
|
52
|
+
if (await pathExists(genPath)) {
|
|
53
|
+
console.log(` ā ļø Skipping ${agentPath} (${genPath} already exists)`);
|
|
54
|
+
} else {
|
|
55
|
+
try {
|
|
56
|
+
await fs.rename(agentPath, genPath);
|
|
57
|
+
renamed.push(`${agentPath} ā ${genPath}`);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw new Error(`Failed to rename ${agentPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Rename AGENT.local.md ā GEN.local.md
|
|
65
|
+
const agentLocalPath = path.join(dir, 'AGENT.local.md');
|
|
66
|
+
const genLocalPath = path.join(dir, 'GEN.local.md');
|
|
67
|
+
|
|
68
|
+
if (await pathExists(agentLocalPath)) {
|
|
69
|
+
if (await pathExists(genLocalPath)) {
|
|
70
|
+
console.log(` ā ļø Skipping ${agentLocalPath} (${genLocalPath} already exists)`);
|
|
71
|
+
} else {
|
|
72
|
+
try {
|
|
73
|
+
await fs.rename(agentLocalPath, genLocalPath);
|
|
74
|
+
renamed.push(`${agentLocalPath} ā ${genLocalPath}`);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
throw new Error(`Failed to rename ${agentLocalPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return renamed;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Migrate providers.json from old format to new format
|
|
86
|
+
* Old format: models[provider] = { provider, authMethod, cachedAt, list }
|
|
87
|
+
* New format: models["provider:authMethod"] = { cachedAt, list }
|
|
88
|
+
*/
|
|
89
|
+
async function migrateProvidersJson(dryRun = false): Promise<MigrationResult> {
|
|
90
|
+
const result: MigrationResult = {
|
|
91
|
+
success: true,
|
|
92
|
+
migratedPaths: [],
|
|
93
|
+
errors: [],
|
|
94
|
+
warnings: [],
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const providersPath = path.join(os.homedir(), '.gen', 'providers.json');
|
|
98
|
+
|
|
99
|
+
// Check if providers.json exists
|
|
100
|
+
if (!(await pathExists(providersPath))) {
|
|
101
|
+
return result; // Nothing to migrate
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
// Read current config
|
|
106
|
+
const content = await fs.readFile(providersPath, 'utf-8');
|
|
107
|
+
const config = JSON.parse(content);
|
|
108
|
+
|
|
109
|
+
// Check if migration is needed
|
|
110
|
+
let needsMigration = false;
|
|
111
|
+
const newModels: Record<string, any> = {};
|
|
112
|
+
|
|
113
|
+
if (config.models) {
|
|
114
|
+
for (const [key, value] of Object.entries(config.models)) {
|
|
115
|
+
// Detect old format: key doesn't contain ':' AND value has provider/authMethod fields
|
|
116
|
+
if (
|
|
117
|
+
!key.includes(':') &&
|
|
118
|
+
typeof value === 'object' &&
|
|
119
|
+
value !== null &&
|
|
120
|
+
'provider' in value &&
|
|
121
|
+
'authMethod' in value
|
|
122
|
+
) {
|
|
123
|
+
needsMigration = true;
|
|
124
|
+
const oldCache = value as any;
|
|
125
|
+
const newKey = `${oldCache.provider}:${oldCache.authMethod}`;
|
|
126
|
+
newModels[newKey] = {
|
|
127
|
+
cachedAt: oldCache.cachedAt,
|
|
128
|
+
list: oldCache.list,
|
|
129
|
+
};
|
|
130
|
+
} else {
|
|
131
|
+
// Already new format
|
|
132
|
+
newModels[key] = value;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!needsMigration) {
|
|
138
|
+
return result; // Already in new format
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (dryRun) {
|
|
142
|
+
result.migratedPaths.push(`[DRY RUN] providers.json: Old format ā New format (provider:authMethod keys)`);
|
|
143
|
+
const oldKeys = Object.keys(config.models || {}).filter(k => !k.includes(':'));
|
|
144
|
+
const newKeys = Object.keys(newModels).filter(k => k.includes(':'));
|
|
145
|
+
result.migratedPaths.push(` Old keys: ${oldKeys.join(', ') || 'none'}`);
|
|
146
|
+
result.migratedPaths.push(` New keys: ${newKeys.join(', ') || 'none'}`);
|
|
147
|
+
} else {
|
|
148
|
+
// Backup old config
|
|
149
|
+
const backupPath = `${providersPath}.backup`;
|
|
150
|
+
await fs.copyFile(providersPath, backupPath);
|
|
151
|
+
|
|
152
|
+
// Update config with new format
|
|
153
|
+
config.models = newModels;
|
|
154
|
+
|
|
155
|
+
// Also update connections to ensure authMethod is set
|
|
156
|
+
if (config.connections) {
|
|
157
|
+
for (const [provider, connection] of Object.entries(config.connections)) {
|
|
158
|
+
if (typeof connection === 'object' && connection !== null && !('authMethod' in connection)) {
|
|
159
|
+
// Try to infer authMethod from connection method name
|
|
160
|
+
const method = (connection as any).method;
|
|
161
|
+
if (method?.includes('Vertex')) {
|
|
162
|
+
(connection as any).authMethod = 'vertex';
|
|
163
|
+
} else if (method?.includes('Bedrock')) {
|
|
164
|
+
(connection as any).authMethod = 'bedrock';
|
|
165
|
+
} else if (method?.includes('Azure')) {
|
|
166
|
+
(connection as any).authMethod = 'azure';
|
|
167
|
+
} else {
|
|
168
|
+
(connection as any).authMethod = 'api_key';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Write new config
|
|
175
|
+
await fs.writeFile(providersPath, JSON.stringify(config, null, 2));
|
|
176
|
+
|
|
177
|
+
result.migratedPaths.push(`providers.json: Migrated to new format`);
|
|
178
|
+
result.migratedPaths.push(` Backup saved: ${backupPath}`);
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
result.errors.push(`Failed to migrate providers.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
182
|
+
result.success = false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Migrate .gencode to .gen
|
|
190
|
+
*/
|
|
191
|
+
async function migrateToGen(dryRun = false): Promise<MigrationResult> {
|
|
192
|
+
const result: MigrationResult = {
|
|
193
|
+
success: true,
|
|
194
|
+
migratedPaths: [],
|
|
195
|
+
errors: [],
|
|
196
|
+
warnings: [],
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// 1. Migrate user directory (~/.gencode ā ~/.gen)
|
|
200
|
+
const homeGencodePath = path.join(os.homedir(), '.gencode');
|
|
201
|
+
const homeGenPath = path.join(os.homedir(), '.gen');
|
|
202
|
+
|
|
203
|
+
if (await pathExists(homeGencodePath)) {
|
|
204
|
+
if (await pathExists(homeGenPath)) {
|
|
205
|
+
result.errors.push(`~/.gen already exists! Please manually merge ~/.gencode into it.`);
|
|
206
|
+
result.success = false;
|
|
207
|
+
} else {
|
|
208
|
+
if (!dryRun) {
|
|
209
|
+
try {
|
|
210
|
+
await fs.rename(homeGencodePath, homeGenPath);
|
|
211
|
+
const renamedFiles = await renameFilesInDir(homeGenPath);
|
|
212
|
+
result.migratedPaths.push(`${homeGencodePath} ā ${homeGenPath}`);
|
|
213
|
+
result.migratedPaths.push(...renamedFiles);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
result.errors.push(`Failed to migrate ${homeGencodePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
216
|
+
result.success = false;
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
result.migratedPaths.push(`[DRY RUN] ${homeGencodePath} ā ${homeGenPath}`);
|
|
220
|
+
result.migratedPaths.push(`[DRY RUN] Will rename AGENT.md ā GEN.md in ${homeGenPath}`);
|
|
221
|
+
result.migratedPaths.push(`[DRY RUN] Will rename AGENT.local.md ā GEN.local.md in ${homeGenPath}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 2. Migrate project directory (./.gencode ā ./.gen)
|
|
227
|
+
const cwd = process.cwd();
|
|
228
|
+
const projectGencodePath = path.join(cwd, '.gencode');
|
|
229
|
+
const projectGenPath = path.join(cwd, '.gen');
|
|
230
|
+
|
|
231
|
+
if (await pathExists(projectGencodePath)) {
|
|
232
|
+
if (await pathExists(projectGenPath)) {
|
|
233
|
+
result.errors.push(`./.gen already exists! Please manually merge ./.gencode into it.`);
|
|
234
|
+
result.success = false;
|
|
235
|
+
} else {
|
|
236
|
+
if (!dryRun) {
|
|
237
|
+
try {
|
|
238
|
+
await fs.rename(projectGencodePath, projectGenPath);
|
|
239
|
+
const renamedFiles = await renameFilesInDir(projectGenPath);
|
|
240
|
+
result.migratedPaths.push(`${projectGencodePath} ā ${projectGenPath}`);
|
|
241
|
+
result.migratedPaths.push(...renamedFiles);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
result.errors.push(`Failed to migrate ${projectGencodePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
244
|
+
result.success = false;
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
result.migratedPaths.push(`[DRY RUN] ${projectGencodePath} ā ${projectGenPath}`);
|
|
248
|
+
result.migratedPaths.push(`[DRY RUN] Will rename AGENT.md ā GEN.md in ${projectGenPath}`);
|
|
249
|
+
result.migratedPaths.push(`[DRY RUN] Will rename AGENT.local.md ā GEN.local.md in ${projectGenPath}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// 3. Migrate root-level files (./AGENT.md ā ./GEN.md)
|
|
255
|
+
const rootAgentPath = path.join(cwd, 'AGENT.md');
|
|
256
|
+
const rootGenPath = path.join(cwd, 'GEN.md');
|
|
257
|
+
|
|
258
|
+
if (await pathExists(rootAgentPath)) {
|
|
259
|
+
if (await pathExists(rootGenPath)) {
|
|
260
|
+
result.warnings.push(`./GEN.md already exists! Skipping ./AGENT.md migration.`);
|
|
261
|
+
} else {
|
|
262
|
+
if (!dryRun) {
|
|
263
|
+
try {
|
|
264
|
+
await fs.rename(rootAgentPath, rootGenPath);
|
|
265
|
+
result.migratedPaths.push(`${rootAgentPath} ā ${rootGenPath}`);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
result.errors.push(`Failed to migrate ${rootAgentPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
268
|
+
result.success = false;
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
result.migratedPaths.push(`[DRY RUN] ${rootAgentPath} ā ${rootGenPath}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 4. Migrate root-level local files (./AGENT.local.md ā ./GEN.local.md)
|
|
277
|
+
const rootAgentLocalPath = path.join(cwd, 'AGENT.local.md');
|
|
278
|
+
const rootGenLocalPath = path.join(cwd, 'GEN.local.md');
|
|
279
|
+
|
|
280
|
+
if (await pathExists(rootAgentLocalPath)) {
|
|
281
|
+
if (await pathExists(rootGenLocalPath)) {
|
|
282
|
+
result.warnings.push(`./GEN.local.md already exists! Skipping ./AGENT.local.md migration.`);
|
|
283
|
+
} else {
|
|
284
|
+
if (!dryRun) {
|
|
285
|
+
try {
|
|
286
|
+
await fs.rename(rootAgentLocalPath, rootGenLocalPath);
|
|
287
|
+
result.migratedPaths.push(`${rootAgentLocalPath} ā ${rootGenLocalPath}`);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
result.errors.push(`Failed to migrate ${rootAgentLocalPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
290
|
+
result.success = false;
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
result.migratedPaths.push(`[DRY RUN] ${rootAgentLocalPath} ā ${rootGenLocalPath}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// If no migrations needed
|
|
299
|
+
if (result.migratedPaths.length === 0 && result.errors.length === 0) {
|
|
300
|
+
result.warnings.push('No .gencode directories or AGENT.md files found. Already using .gen?');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Check if migration is needed
|
|
308
|
+
*/
|
|
309
|
+
async function needsMigration(): Promise<boolean> {
|
|
310
|
+
const homeGencodePath = path.join(os.homedir(), '.gencode');
|
|
311
|
+
const projectGencodePath = path.join(process.cwd(), '.gencode');
|
|
312
|
+
const rootAgentPath = path.join(process.cwd(), 'AGENT.md');
|
|
313
|
+
const rootAgentLocalPath = path.join(process.cwd(), 'AGENT.local.md');
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
(await pathExists(homeGencodePath)) ||
|
|
317
|
+
(await pathExists(projectGencodePath)) ||
|
|
318
|
+
(await pathExists(rootAgentPath)) ||
|
|
319
|
+
(await pathExists(rootAgentLocalPath))
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Prompt user for confirmation
|
|
325
|
+
*/
|
|
326
|
+
async function confirm(message: string): Promise<boolean> {
|
|
327
|
+
const rl = readline.createInterface({
|
|
328
|
+
input: process.stdin,
|
|
329
|
+
output: process.stdout,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
return new Promise((resolve) => {
|
|
333
|
+
rl.question(`${message} (y/N): `, (answer) => {
|
|
334
|
+
rl.close();
|
|
335
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Main migration flow
|
|
342
|
+
*/
|
|
343
|
+
async function main() {
|
|
344
|
+
console.log('š GenCode Migration: .gencode ā .gen\n');
|
|
345
|
+
|
|
346
|
+
// Check if migration is needed
|
|
347
|
+
const needs = await needsMigration();
|
|
348
|
+
if (!needs) {
|
|
349
|
+
console.log('ā
No .gencode directories or AGENT.md files found.');
|
|
350
|
+
console.log(' Already using .gen? Nothing to migrate.\n');
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Always check providers.json migration (even if .gencode migration not needed)
|
|
354
|
+
console.log('š Scanning for files to migrate...\n');
|
|
355
|
+
|
|
356
|
+
// Perform dry run for providers.json
|
|
357
|
+
const providersResult = await migrateProvidersJson(true);
|
|
358
|
+
|
|
359
|
+
// Perform dry run for .gencode
|
|
360
|
+
const dryRunResult = await migrateToGen(true);
|
|
361
|
+
|
|
362
|
+
// Merge results
|
|
363
|
+
const allMigrations = [...providersResult.migratedPaths, ...dryRunResult.migratedPaths];
|
|
364
|
+
const allErrors = [...providersResult.errors, ...dryRunResult.errors];
|
|
365
|
+
const allWarnings = [...providersResult.warnings, ...dryRunResult.warnings];
|
|
366
|
+
|
|
367
|
+
if (allMigrations.length === 0 && allErrors.length === 0) {
|
|
368
|
+
console.log('ā
All configurations are up to date. Nothing to migrate.\n');
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (allMigrations.length > 0) {
|
|
373
|
+
console.log('š¦ Migration Plan:\n');
|
|
374
|
+
for (const path of allMigrations) {
|
|
375
|
+
console.log(` ā ${path}`);
|
|
376
|
+
}
|
|
377
|
+
console.log('');
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (allErrors.length > 0) {
|
|
381
|
+
console.log('ā Errors:\n');
|
|
382
|
+
for (const error of allErrors) {
|
|
383
|
+
console.log(` ā ${error}`);
|
|
384
|
+
}
|
|
385
|
+
console.log('\nā ļø Migration aborted. Please resolve conflicts manually.\n');
|
|
386
|
+
process.exit(1);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (allWarnings.length > 0) {
|
|
390
|
+
console.log('ā ļø Warnings:\n');
|
|
391
|
+
for (const warning of allWarnings) {
|
|
392
|
+
console.log(` ⢠${warning}`);
|
|
393
|
+
}
|
|
394
|
+
console.log('');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Ask for confirmation
|
|
398
|
+
const confirmed = await confirm('Proceed with migration?');
|
|
399
|
+
if (!confirmed) {
|
|
400
|
+
console.log('\nā Migration cancelled.\n');
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Execute migration
|
|
405
|
+
console.log('\nš Executing migration...\n');
|
|
406
|
+
|
|
407
|
+
// Migrate providers.json first
|
|
408
|
+
const providersExecResult = await migrateProvidersJson(false);
|
|
409
|
+
|
|
410
|
+
// Then migrate .gencode
|
|
411
|
+
const result = await migrateToGen(false);
|
|
412
|
+
|
|
413
|
+
const allSuccess = providersExecResult.success && result.success;
|
|
414
|
+
const allMigratedPaths = [...providersExecResult.migratedPaths, ...result.migratedPaths];
|
|
415
|
+
const allExecErrors = [...providersExecResult.errors, ...result.errors];
|
|
416
|
+
|
|
417
|
+
if (allSuccess) {
|
|
418
|
+
console.log('ā
Migration completed successfully!\n');
|
|
419
|
+
if (allMigratedPaths.length > 0) {
|
|
420
|
+
console.log('Migrated paths:\n');
|
|
421
|
+
for (const path of allMigratedPaths) {
|
|
422
|
+
console.log(` ā ${path}`);
|
|
423
|
+
}
|
|
424
|
+
console.log('');
|
|
425
|
+
}
|
|
426
|
+
console.log('š Next steps:\n');
|
|
427
|
+
console.log(' 1. Update environment variables: GENCODE_* ā GEN_*');
|
|
428
|
+
console.log(' - GENCODE_PROVIDER ā GEN_PROVIDER');
|
|
429
|
+
console.log(' - GENCODE_MODEL ā GEN_MODEL');
|
|
430
|
+
console.log(' - GENCODE_CONFIG_DIRS ā GEN_CONFIG\n');
|
|
431
|
+
console.log(' 2. Update any scripts or CI/CD configs\n');
|
|
432
|
+
console.log(' 3. Restart GenCode to load from .gen directories\n');
|
|
433
|
+
} else {
|
|
434
|
+
console.log('ā Migration failed!\n');
|
|
435
|
+
if (allExecErrors.length > 0) {
|
|
436
|
+
console.log('Errors:\n');
|
|
437
|
+
for (const error of allExecErrors) {
|
|
438
|
+
console.log(` ā ${error}`);
|
|
439
|
+
}
|
|
440
|
+
console.log('');
|
|
441
|
+
}
|
|
442
|
+
process.exit(1);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
main().catch((error) => {
|
|
447
|
+
console.error('ā Unexpected error:', error);
|
|
448
|
+
process.exit(1);
|
|
449
|
+
});
|