locadex 0.1.0-alpha.9 → 0.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/CHANGELOG.md +12 -0
- package/README.md +3 -5
- package/dist/cli.js +11 -10
- package/dist/cli.js.map +1 -1
- package/dist/commands/i18n.d.ts.map +1 -1
- package/dist/commands/i18n.js +15 -14
- package/dist/commands/i18n.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +15 -14
- package/dist/commands/setup.js.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/logging/console.js +2 -5
- package/dist/logging/console.js.map +1 -1
- package/dist/logging/logger.d.ts +4 -2
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +1 -4
- package/dist/logging/logger.js.map +1 -1
- package/dist/mcp/getDocs.js +1 -4
- package/dist/mcp/getDocs.js.map +1 -1
- package/dist/mcp/getGuide.js +1 -4
- package/dist/mcp/getGuide.js.map +1 -1
- package/dist/mcp/getPort.js +1 -4
- package/dist/mcp/getPort.js.map +1 -1
- package/dist/mcp/tools/docs.js +1 -4
- package/dist/mcp/tools/docs.js.map +1 -1
- package/dist/mcp/tools/guides.js +1 -4
- package/dist/mcp/tools/guides.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +57 -17
- package/dist/mcp.js.map +1 -1
- package/dist/prompts/system.js +1 -4
- package/dist/prompts/system.js.map +1 -1
- package/dist/tasks/concurrency.d.ts +72 -0
- package/dist/tasks/concurrency.d.ts.map +1 -0
- package/dist/tasks/concurrency.js +132 -0
- package/dist/tasks/concurrency.js.map +1 -0
- package/dist/tasks/i18n.d.ts.map +1 -1
- package/dist/tasks/i18n.js +60 -127
- package/dist/tasks/i18n.js.map +1 -1
- package/dist/tasks/setup.d.ts.map +1 -1
- package/dist/tasks/setup.js +38 -44
- package/dist/tasks/setup.js.map +1 -1
- package/dist/telemetry.js +1 -4
- package/dist/telemetry.js.map +1 -1
- package/dist/types/claude-sdk.d.ts +1 -1
- package/dist/types/claude-sdk.d.ts.map +1 -1
- package/dist/types/claude-sdk.js +1 -4
- package/dist/types/claude-sdk.js.map +1 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/cli.js +1 -4
- package/dist/types/cli.js.map +1 -1
- package/dist/utils/claudeCode.d.ts +6 -5
- package/dist/utils/claudeCode.d.ts.map +1 -1
- package/dist/utils/claudeCode.js +50 -17
- package/dist/utils/claudeCode.js.map +1 -1
- package/dist/utils/config.d.ts +4 -3
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +33 -20
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/dag/createDag.d.ts.map +1 -1
- package/dist/utils/dag/createDag.js +10 -11
- package/dist/utils/dag/createDag.js.map +1 -1
- package/dist/utils/dag/extractFiles.d.ts.map +1 -1
- package/dist/utils/dag/extractFiles.js +6 -9
- package/dist/utils/dag/extractFiles.js.map +1 -1
- package/dist/utils/dag/getFiles.d.ts +1 -12
- package/dist/utils/dag/getFiles.d.ts.map +1 -1
- package/dist/utils/dag/getFiles.js +5 -53
- package/dist/utils/dag/getFiles.js.map +1 -1
- package/dist/utils/dag/matchFiles.d.ts +2 -2
- package/dist/utils/dag/matchFiles.d.ts.map +1 -1
- package/dist/utils/dag/matchFiles.js +3 -6
- package/dist/utils/dag/matchFiles.js.map +1 -1
- package/dist/utils/fs/findConfigs.d.ts +4 -4
- package/dist/utils/fs/findConfigs.d.ts.map +1 -1
- package/dist/utils/fs/findConfigs.js +7 -13
- package/dist/utils/fs/findConfigs.js.map +1 -1
- package/dist/utils/fs/getFiles.d.ts +1 -1
- package/dist/utils/fs/getFiles.d.ts.map +1 -1
- package/dist/utils/fs/getFiles.js +3 -6
- package/dist/utils/fs/getFiles.js.map +1 -1
- package/dist/utils/fs/git.d.ts +6 -0
- package/dist/utils/fs/git.d.ts.map +1 -0
- package/dist/utils/fs/git.js +32 -0
- package/dist/utils/fs/git.js.map +1 -0
- package/dist/utils/fs/writeFiles.js +1 -4
- package/dist/utils/fs/writeFiles.js.map +1 -1
- package/dist/utils/getPaths.js +1 -4
- package/dist/utils/getPaths.js.map +1 -1
- package/dist/utils/locadexManager.d.ts +15 -5
- package/dist/utils/locadexManager.d.ts.map +1 -1
- package/dist/utils/locadexManager.js +80 -73
- package/dist/utils/locadexManager.js.map +1 -1
- package/dist/utils/lockfile.d.ts +2 -2
- package/dist/utils/lockfile.d.ts.map +1 -1
- package/dist/utils/lockfile.js +8 -17
- package/dist/utils/lockfile.js.map +1 -1
- package/dist/utils/packages/installPackage.d.ts +4 -0
- package/dist/utils/packages/installPackage.d.ts.map +1 -1
- package/dist/utils/packages/installPackage.js +41 -5
- package/dist/utils/packages/installPackage.js.map +1 -1
- package/dist/utils/session.js +1 -4
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/shared.js +1 -4
- package/dist/utils/shared.js.map +1 -1
- package/dist/utils/shutdown.d.ts.map +1 -1
- package/dist/utils/shutdown.js +1 -9
- package/dist/utils/shutdown.js.map +1 -1
- package/dist/utils/stats.js +1 -4
- package/dist/utils/stats.js.map +1 -1
- package/guides/next/advanced/var-outside-client-server-component.md +1 -1
- package/package.json +4 -6
- package/dist/mcp/debugger.d.ts +0 -3
- package/dist/mcp/debugger.d.ts.map +0 -1
- package/dist/mcp/debugger.js +0 -37
- package/dist/mcp/debugger.js.map +0 -1
- package/dist/mcp-sse.d.ts +0 -3
- package/dist/mcp-sse.d.ts.map +0 -1
- package/dist/mcp-sse.js +0 -77
- package/dist/mcp-sse.js.map +0 -1
package/dist/tasks/i18n.js
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="54eae907-9732-5dfd-ac3a-fcec8e6df321")}catch(e){}}();
|
|
3
1
|
import { createSpinner } from '../logging/console.js';
|
|
4
2
|
import { allMcpPrompt } from '../prompts/system.js';
|
|
5
3
|
import { exit } from '../utils/shutdown.js';
|
|
6
4
|
import { logger } from '../logging/logger.js';
|
|
7
5
|
import { LocadexManager } from '../utils/locadexManager.js';
|
|
8
6
|
import { addFilesToManager, markFileAsEdited, markFileAsInProgress, } from '../utils/dag/getFiles.js';
|
|
7
|
+
import { runParallelProcessing } from './concurrency.js';
|
|
9
8
|
import { outro } from '@clack/prompts';
|
|
10
9
|
import chalk from 'chalk';
|
|
11
10
|
import { appendFileSync } from 'node:fs';
|
|
12
|
-
import { validateInitialConfig } from '../utils/config.js';
|
|
13
11
|
import { detectFormatter, formatFiles } from 'gtx-cli/hooks/postProcess';
|
|
14
|
-
import { generateSettings } from 'gtx-cli/config/generateSettings';
|
|
15
12
|
import path from 'node:path';
|
|
16
13
|
import { updateLockfile, cleanupLockfile } from '../utils/lockfile.js';
|
|
17
14
|
import { installClaudeCode } from '../utils/packages/installPackage.js';
|
|
18
15
|
import { extractFiles } from '../utils/dag/extractFiles.js';
|
|
16
|
+
import { getPackageJson, isPackageInstalled } from 'gtx-cli/utils/packageJson';
|
|
17
|
+
import { deleteAddedFiles } from '../utils/fs/git.js';
|
|
19
18
|
export async function i18nTask() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
const manager = LocadexManager.getInstance();
|
|
20
|
+
// have to use the package.json from the appDir
|
|
21
|
+
const packageJson = await getPackageJson(manager.appDirectory);
|
|
22
|
+
const isUsingGTNext = packageJson
|
|
23
|
+
? isPackageInstalled('gt-next', packageJson)
|
|
24
|
+
: false;
|
|
25
|
+
if (!isUsingGTNext) {
|
|
26
|
+
logger.error(`gt-next not detected in ${manager.appDirectory}. Please specify the correct app directory with the --app-dir flag, or ensure that gt-next is correctly installed in the project.`);
|
|
24
27
|
await exit(1);
|
|
25
28
|
}
|
|
26
29
|
// Install claude-code if not installed
|
|
27
30
|
await installClaudeCode();
|
|
31
|
+
logger.debugMessage('App directory: ' + manager.appDirectory);
|
|
32
|
+
logger.debugMessage('Root directory: ' + manager.rootDirectory);
|
|
28
33
|
// Init message
|
|
29
34
|
const spinner = createSpinner();
|
|
30
35
|
spinner.start('Initializing Locadex...');
|
|
31
|
-
const manager = LocadexManager.getInstance();
|
|
32
36
|
const { files, dag } = extractFiles(manager);
|
|
33
37
|
if (files.length === 0) {
|
|
34
38
|
spinner.stop('No files have changed since last run');
|
|
@@ -50,150 +54,77 @@ export async function i18nTask() {
|
|
|
50
54
|
logger.initializeProgressBar(taskQueue.length);
|
|
51
55
|
const fileProcessingStartTime = Date.now();
|
|
52
56
|
logger.progressBar.start(`Processing ${taskQueue.length} files...`);
|
|
53
|
-
//
|
|
54
|
-
let processedCount = 0;
|
|
55
|
-
const agentAbortController = manager.getAgentAbortController();
|
|
56
|
-
let firstError = null;
|
|
57
|
-
// Mutex for task queue access
|
|
58
|
-
let taskQueueMutex = Promise.resolve();
|
|
59
|
-
// Shared across all agents
|
|
57
|
+
// Shared reports array for collecting results
|
|
60
58
|
const reports = [];
|
|
61
|
-
//
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
resolve(tasks);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const processTask = async () => {
|
|
71
|
-
while (taskQueue.length > 0 && !agentAbortController.signal.aborted) {
|
|
72
|
-
// Check if we should abort early
|
|
73
|
-
if (agentAbortController.signal.aborted) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
// Get an available agent atomically
|
|
77
|
-
const agentInfo = await manager.getAvailableAgent();
|
|
78
|
-
if (!agentInfo) {
|
|
79
|
-
// No available agents, wait a bit (but check for abort)
|
|
80
|
-
await new Promise((resolve) => {
|
|
81
|
-
const timeout = global.setTimeout(resolve, 100);
|
|
82
|
-
agentAbortController.signal.addEventListener('abort', () => {
|
|
83
|
-
global.clearTimeout(timeout);
|
|
84
|
-
resolve(undefined);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
const { id: agentId, agent, sessionId } = agentInfo;
|
|
90
|
-
// Get the next batch of tasks (thread-safe)
|
|
91
|
-
const tasks = await getNextTasks(batchSize);
|
|
92
|
-
if (tasks.length === 0) {
|
|
93
|
-
manager.markAgentFree(agentId);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
logger.debugMessage(`Using agent ${agentId} for ${batchSize} files. Files: ${tasks.join(', ')}`);
|
|
59
|
+
// Create i18n task processor
|
|
60
|
+
const i18nProcessor = {
|
|
61
|
+
preProcess: async (files, context) => {
|
|
62
|
+
const { dag, filesStateFilePath } = context;
|
|
63
|
+
logger.debugMessage(`Files: ${files.join(', ')}`);
|
|
97
64
|
// Mark tasks as in progress
|
|
98
|
-
await Promise.all(
|
|
65
|
+
await Promise.all(files.map((file) => markFileAsInProgress(file, filesStateFilePath)));
|
|
99
66
|
// Construct prompt
|
|
100
|
-
const dependencies = Object.fromEntries(
|
|
101
|
-
|
|
102
|
-
Array.from(new Set(dag.getDependencies(
|
|
67
|
+
const dependencies = Object.fromEntries(files.map((file) => [
|
|
68
|
+
file,
|
|
69
|
+
Array.from(new Set(dag.getDependencies(file))).map(String),
|
|
103
70
|
]));
|
|
104
|
-
const dependents = Object.fromEntries(
|
|
105
|
-
|
|
106
|
-
Array.from(new Set(dag.getDependents(
|
|
71
|
+
const dependents = Object.fromEntries(files.map((file) => [
|
|
72
|
+
file,
|
|
73
|
+
Array.from(new Set(dag.getDependents(file))).map(String),
|
|
107
74
|
]));
|
|
108
|
-
|
|
109
|
-
targetFile:
|
|
75
|
+
return getPrompt({
|
|
76
|
+
targetFile: files,
|
|
110
77
|
dependencyFiles: dependencies,
|
|
111
78
|
dependentFiles: dependents,
|
|
112
79
|
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
prompt,
|
|
117
|
-
sessionId,
|
|
118
|
-
}, {});
|
|
119
|
-
reports.push(agent.generateReport());
|
|
120
|
-
manager.markAgentFree(agentId);
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
// Check if this is an abort
|
|
124
|
-
if (agentAbortController.signal.aborted) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
// Capture the first error and signal all other agents to abort
|
|
128
|
-
if (!firstError) {
|
|
129
|
-
firstError = new Error(`Error in claude i18n process (${agentId}): ${error}`);
|
|
130
|
-
logger.debugMessage(firstError.message);
|
|
131
|
-
}
|
|
132
|
-
await exit(1); // Exit this agent's processing immediately
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
80
|
+
},
|
|
81
|
+
postProcess: async (files, context, agentReport) => {
|
|
82
|
+
const { filesStateFilePath } = context;
|
|
135
83
|
// Mark tasks as complete
|
|
136
|
-
await Promise.all(
|
|
137
|
-
|
|
138
|
-
|
|
84
|
+
await Promise.all(files.map((task) => markFileAsEdited(task, filesStateFilePath)));
|
|
85
|
+
// Add agent report
|
|
86
|
+
reports.push(agentReport);
|
|
87
|
+
// Update progress bar
|
|
88
|
+
logger.progressBar.advance(files.length, `Processed ${Number(((reports.length * files.length) / files.length) * 100).toFixed(2)}% of files`);
|
|
89
|
+
// Update stats
|
|
139
90
|
manager.stats.updateStats({
|
|
140
|
-
newProcessedFiles:
|
|
91
|
+
newProcessedFiles: files.length,
|
|
141
92
|
});
|
|
142
|
-
}
|
|
93
|
+
},
|
|
143
94
|
};
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
catch (error) {
|
|
152
|
-
// Check if this is an abort
|
|
153
|
-
if (agentAbortController.signal.aborted) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
// This shouldn't happen since we handle errors within processTask
|
|
157
|
-
logger.debugMessage(`Unexpected error in parallel processing: ${error}`);
|
|
158
|
-
if (!firstError) {
|
|
159
|
-
firstError = new Error(`Unexpected error in parallel processing: ${error}`);
|
|
160
|
-
}
|
|
95
|
+
// Run parallel processing
|
|
96
|
+
await runParallelProcessing(Array.from(taskQueue), i18nProcessor, { dag, files, filesStateFilePath }, {
|
|
97
|
+
concurrency,
|
|
98
|
+
batchSize,
|
|
99
|
+
}, 1);
|
|
100
|
+
if (manager.isAborted()) {
|
|
101
|
+
return;
|
|
161
102
|
}
|
|
162
103
|
logger.progressBar.stop(`Processed ${files.length} files [${Math.round((Date.now() - fileProcessingStartTime) / 1000)}s]`);
|
|
163
104
|
// TODO: uncomment
|
|
164
105
|
// // Always clean up the file list when done, regardless of success or failure
|
|
165
|
-
// logger.info(`Cleaning up file list: ${stateFilePath}`);
|
|
166
106
|
// cleanUp(stateFilePath);
|
|
167
|
-
// If there was an error, clean up and exit with code 1
|
|
168
|
-
if (firstError) {
|
|
169
|
-
logger.error(firstError.message);
|
|
170
|
-
outro(chalk.red('❌ Locadex i18n failed!'));
|
|
171
|
-
await exit(1);
|
|
172
|
-
}
|
|
173
107
|
// Create a clean agent for cleanup
|
|
174
108
|
const cleanupAgent = manager.createSingleAgent('claude_cleanup_agent');
|
|
175
109
|
logger.initializeSpinner();
|
|
176
110
|
logger.spinner.start('Fixing errors...');
|
|
177
|
-
const fixPrompt = getFixPrompt();
|
|
111
|
+
const fixPrompt = getFixPrompt(manager.appDirectory);
|
|
178
112
|
try {
|
|
179
|
-
await cleanupAgent.run(
|
|
113
|
+
await cleanupAgent.run(fixPrompt, { maxTurns: 200 }, 1000, 3);
|
|
180
114
|
reports.push(`## Fixed errors\n${cleanupAgent.generateReport()}`);
|
|
181
115
|
}
|
|
182
116
|
catch (error) {
|
|
183
|
-
// Check if this is an abort
|
|
184
|
-
if (agentAbortController.signal.aborted) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
117
|
logger.debugMessage(`[claude_cleanup_agent] Fixing errors failed: ${error}`);
|
|
188
118
|
manager.stats.recordTelemetry(false);
|
|
189
119
|
outro(chalk.red('❌ Locadex i18n failed!'));
|
|
190
120
|
await exit(1);
|
|
121
|
+
return;
|
|
191
122
|
}
|
|
192
123
|
logger.spinner.stop('Fixed errors');
|
|
193
124
|
// Generate report
|
|
194
125
|
const reportSummary = `# Summary of locadex i18n changes
|
|
195
126
|
${reports.join('\n')}`;
|
|
196
|
-
const summaryFilePath = path.join(manager.
|
|
127
|
+
const summaryFilePath = path.join(manager.getLogDirectory(), 'locadex-report.md');
|
|
197
128
|
appendFileSync(summaryFilePath, reportSummary);
|
|
198
129
|
logger.step(`Saved summary of changes to: ${summaryFilePath}`);
|
|
199
130
|
// cleanup
|
|
@@ -203,10 +134,13 @@ ${reports.join('\n')}`;
|
|
|
203
134
|
}
|
|
204
135
|
const lockfilePath = manager.getLockFilePath();
|
|
205
136
|
// Update lockfile with processed files
|
|
206
|
-
updateLockfile(files, lockfilePath);
|
|
137
|
+
updateLockfile(files, lockfilePath, manager.rootDirectory);
|
|
207
138
|
// Clean up stale entries from lockfile
|
|
208
|
-
cleanupLockfile(
|
|
139
|
+
cleanupLockfile(lockfilePath, manager.rootDirectory);
|
|
209
140
|
logger.message(chalk.dim(`Updated lockfile with ${files.length} files`));
|
|
141
|
+
deleteAddedFiles([
|
|
142
|
+
path.relative(manager.rootDirectory, manager.locadexDirectory),
|
|
143
|
+
]);
|
|
210
144
|
logger.info(chalk.dim(`Total Cost: $${manager.stats.getStats().totalCost.toFixed(2)}
|
|
211
145
|
Total wall time: ${Math.round((Date.now() - manager.stats.getStats().startTime) / 1000)}s
|
|
212
146
|
Total files processed: ${manager.stats.getStats().processedFiles}`));
|
|
@@ -254,7 +188,7 @@ function getPrompt({ targetFile, dependencyFiles, dependentFiles, }) {
|
|
|
254
188
|
- Minimize the footprint of your changes.
|
|
255
189
|
- Focus on internationalizing the content of the target files.
|
|
256
190
|
- NEVER move internationalized content to a different file. All content MUST remain in the same file where it came from.
|
|
257
|
-
- NEVER CREATE OR
|
|
191
|
+
- NEVER CREATE OR DELETE ANY FILES (especially .bak files)
|
|
258
192
|
- Internationalize all user facing content in the target files.
|
|
259
193
|
- NEVER EDIT FILES THAT ARE NOT GIVEN TO YOU.
|
|
260
194
|
|
|
@@ -287,7 +221,7 @@ ${allMcpPrompt}
|
|
|
287
221
|
return prompt;
|
|
288
222
|
}
|
|
289
223
|
// check (dry run and ts check) should be at the end
|
|
290
|
-
function getFixPrompt() {
|
|
224
|
+
function getFixPrompt(appDirectory) {
|
|
291
225
|
const prompt = `# Task: Fix internationalization errors in the project.
|
|
292
226
|
|
|
293
227
|
## INSTRUCTIONS
|
|
@@ -299,7 +233,6 @@ Your new task is as follows:
|
|
|
299
233
|
2. Fix all errors output by the gt-next validator.
|
|
300
234
|
3. Whenever you are finished with your changes, run the gt-next validator.
|
|
301
235
|
4. Repeat steps 1-3 until there are no more errors, or until you believe that you have fixed all errors.
|
|
302
|
-
5. If the project is setup with linting, lint the project and fix all lint errors.
|
|
303
236
|
|
|
304
237
|
## RULES:
|
|
305
238
|
- ONLY modify files that are relevant to the internationalization of the project.
|
|
@@ -308,8 +241,9 @@ Your new task is as follows:
|
|
|
308
241
|
- In particular, if a file contains user-facing content that should be internationalized and is not, you should internationalize it.
|
|
309
242
|
- Resolve missing imports from 'gt-next'. If a file is missing an import from 'gt-next', add it.
|
|
310
243
|
|
|
311
|
-
To run the gt-next validator, run the following command:
|
|
244
|
+
To run the gt-next validator, run the following command from the app root:
|
|
312
245
|
'npx locadex translate --dry-run'
|
|
246
|
+
The app root is: "${appDirectory}"
|
|
313
247
|
|
|
314
248
|
## MCP TOOLS
|
|
315
249
|
|
|
@@ -325,5 +259,4 @@ ${allMcpPrompt}
|
|
|
325
259
|
`;
|
|
326
260
|
return prompt;
|
|
327
261
|
}
|
|
328
|
-
//# sourceMappingURL=i18n.js.map
|
|
329
|
-
//# debugId=54eae907-9732-5dfd-ac3a-fcec8e6df321
|
|
262
|
+
//# sourceMappingURL=i18n.js.map
|
package/dist/tasks/i18n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.js","sources":["tasks/i18n.ts"],"sourceRoot":"/","sourcesContent":["import { createSpinner } from '../logging/console.js';\nimport { allMcpPrompt } from '../prompts/system.js';\nimport { exit } from '../utils/shutdown.js';\nimport { logger } from '../logging/logger.js';\nimport { LocadexManager } from '../utils/locadexManager.js';\nimport {\n addFilesToManager,\n markFileAsEdited,\n markFileAsInProgress,\n} from '../utils/dag/getFiles.js';\nimport { outro } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { appendFileSync } from 'node:fs';\nimport { validateInitialConfig } from '../utils/config.js';\nimport { detectFormatter, formatFiles } from 'gtx-cli/hooks/postProcess';\nimport { generateSettings } from 'gtx-cli/config/generateSettings';\nimport path from 'node:path';\nimport { updateLockfile, cleanupLockfile } from '../utils/lockfile.js';\nimport { installClaudeCode } from '../utils/packages/installPackage.js';\nimport { extractFiles } from '../utils/dag/extractFiles.js';\n\nexport async function i18nTask() {\n await validateInitialConfig();\n\n const gtSettings = await generateSettings({});\n if (gtSettings.framework !== 'next-app') {\n logger.error(\n 'Currently, locadex only supports Next.js App Router. Please use Next.js App Router.'\n );\n await exit(1);\n }\n\n // Install claude-code if not installed\n await installClaudeCode();\n\n // Init message\n const spinner = createSpinner();\n spinner.start('Initializing Locadex...');\n\n const manager = LocadexManager.getInstance();\n\n const { files, dag } = extractFiles(manager);\n\n if (files.length === 0) {\n spinner.stop('No files have changed since last run');\n outro(chalk.green('✅ Locadex i18n complete - no changes detected!'));\n await exit(0);\n }\n\n const filesStateFilePath = manager.getFilesStateFilePath();\n const concurrency = manager.getMaxConcurrency();\n const batchSize = manager.getBatchSize();\n\n // Create the list of files (aka tasks) to process\n const taskQueue = Array.from(files);\n\n // Add files to manager\n const stateFilePath = addFilesToManager(filesStateFilePath, taskQueue);\n spinner.stop('Locadex initialized');\n\n logger.verboseMessage(`Processing ${files.length} modified files`);\n logger.debugMessage(`Track progress here: ${stateFilePath}`);\n logger.debugMessage(`Order:\\n${taskQueue.join('\\n')}`);\n\n logger.message(`Using ${concurrency} concurrent agents`);\n logger.initializeProgressBar(taskQueue.length);\n\n const fileProcessingStartTime = Date.now();\n logger.progressBar.start(`Processing ${taskQueue.length} files...`);\n\n // Main parallel processing loop\n let processedCount = 0;\n const agentAbortController = manager.getAgentAbortController();\n let firstError: Error | null = null;\n\n // Mutex for task queue access\n let taskQueueMutex = Promise.resolve();\n\n // Shared across all agents\n const reports: string[] = [];\n\n // Helper function to safely get tasks from queue\n const getNextTasks = async (batchSize: number): Promise<string[]> => {\n return new Promise((resolve) => {\n taskQueueMutex = taskQueueMutex.then(() => {\n const tasks = taskQueue.splice(0, batchSize);\n resolve(tasks);\n });\n });\n };\n\n const processTask = async (): Promise<void> => {\n while (taskQueue.length > 0 && !agentAbortController.signal.aborted) {\n // Check if we should abort early\n if (agentAbortController.signal.aborted) {\n return;\n }\n\n // Get an available agent atomically\n const agentInfo = await manager.getAvailableAgent();\n if (!agentInfo) {\n // No available agents, wait a bit (but check for abort)\n await new Promise((resolve) => {\n const timeout = global.setTimeout(resolve, 100);\n agentAbortController.signal.addEventListener('abort', () => {\n global.clearTimeout(timeout);\n resolve(undefined);\n });\n });\n continue;\n }\n\n const { id: agentId, agent, sessionId } = agentInfo;\n\n // Get the next batch of tasks (thread-safe)\n const tasks = await getNextTasks(batchSize);\n if (tasks.length === 0) {\n manager.markAgentFree(agentId);\n break;\n }\n\n logger.debugMessage(\n `Using agent ${agentId} for ${batchSize} files. Files: ${tasks.join(\n ', '\n )}`\n );\n\n // Mark tasks as in progress\n await Promise.all(\n tasks.map((task) => markFileAsInProgress(task, filesStateFilePath))\n );\n\n // Construct prompt\n const dependencies = Object.fromEntries(\n tasks.map((task) => [\n task,\n Array.from(new Set(dag.getDependencies(task))),\n ])\n );\n const dependents = Object.fromEntries(\n tasks.map((task) => [\n task,\n Array.from(new Set(dag.getDependents(task))),\n ])\n );\n const prompt = getPrompt({\n targetFile: tasks,\n dependencyFiles: dependencies,\n dependentFiles: dependents,\n });\n\n // Claude call\n try {\n await agent.run(\n {\n prompt,\n sessionId,\n },\n {}\n );\n reports.push(agent.generateReport());\n manager.markAgentFree(agentId);\n } catch (error) {\n // Check if this is an abort\n if (agentAbortController.signal.aborted) {\n return;\n }\n\n // Capture the first error and signal all other agents to abort\n if (!firstError) {\n firstError = new Error(\n `Error in claude i18n process (${agentId}): ${error}`\n );\n logger.debugMessage(firstError.message);\n }\n await exit(1); // Exit this agent's processing immediately\n return;\n }\n\n // Mark tasks as complete\n await Promise.all(\n tasks.map((task) => markFileAsEdited(task, filesStateFilePath))\n );\n processedCount += tasks.length;\n logger.progressBar.advance(\n tasks.length,\n `Processed ${Number((processedCount / files.length) * 100).toFixed(2)}% of files`\n );\n manager.stats.updateStats({\n newProcessedFiles: tasks.length,\n });\n }\n };\n\n // Create agent pool\n manager.createAgentPool();\n\n // Start parallel processing\n const processingPromises = Array.from({ length: concurrency }, () =>\n processTask()\n );\n\n try {\n await Promise.all(processingPromises);\n } catch (error) {\n // Check if this is an abort\n if (agentAbortController.signal.aborted) {\n return;\n }\n\n // This shouldn't happen since we handle errors within processTask\n logger.debugMessage(`Unexpected error in parallel processing: ${error}`);\n if (!firstError) {\n firstError = new Error(\n `Unexpected error in parallel processing: ${error}`\n );\n }\n }\n\n logger.progressBar.stop(\n `Processed ${files.length} files [${Math.round(\n (Date.now() - fileProcessingStartTime) / 1000\n )}s]`\n );\n\n // TODO: uncomment\n // // Always clean up the file list when done, regardless of success or failure\n // logger.info(`Cleaning up file list: ${stateFilePath}`);\n // cleanUp(stateFilePath);\n\n // If there was an error, clean up and exit with code 1\n if (firstError) {\n logger.error(firstError.message);\n outro(chalk.red('❌ Locadex i18n failed!'));\n await exit(1);\n }\n\n // Create a clean agent for cleanup\n const cleanupAgent = manager.createSingleAgent('claude_cleanup_agent');\n logger.initializeSpinner();\n logger.spinner.start('Fixing errors...');\n const fixPrompt = getFixPrompt();\n try {\n await cleanupAgent.run(\n { prompt: fixPrompt, sessionId: cleanupAgent.getSessionId() },\n {}\n );\n reports.push(`## Fixed errors\\n${cleanupAgent.generateReport()}`);\n } catch (error) {\n // Check if this is an abort\n if (agentAbortController.signal.aborted) {\n return;\n }\n logger.debugMessage(\n `[claude_cleanup_agent] Fixing errors failed: ${error}`\n );\n manager.stats.recordTelemetry(false);\n outro(chalk.red('❌ Locadex i18n failed!'));\n await exit(1);\n }\n logger.spinner.stop('Fixed errors');\n\n // Generate report\n const reportSummary = `# Summary of locadex i18n changes\n${reports.join('\\n')}`;\n const summaryFilePath = path.join(\n manager.getWorkingDir(),\n 'locadex-report.md'\n );\n appendFileSync(summaryFilePath, reportSummary);\n logger.step(`Saved summary of changes to: ${summaryFilePath}`);\n\n // cleanup\n const formatter = await detectFormatter();\n if (formatter) {\n await formatFiles(files, formatter);\n }\n\n const lockfilePath = manager.getLockFilePath();\n\n // Update lockfile with processed files\n updateLockfile(files, lockfilePath);\n\n // Clean up stale entries from lockfile\n cleanupLockfile(files, lockfilePath);\n\n logger.message(chalk.dim(`Updated lockfile with ${files.length} files`));\n\n logger.info(\n chalk.dim(\n `Total Cost: $${manager.stats.getStats().totalCost.toFixed(2)}\nTotal wall time: ${Math.round(\n (Date.now() - manager.stats.getStats().startTime) / 1000\n )}s\nTotal files processed: ${manager.stats.getStats().processedFiles}`\n )\n );\n\n const finalStats = manager.stats.getStats();\n\n // Record telemetry for final stats\n manager.stats.recordTelemetry(true);\n\n logger.verboseMessage(\n `Total input tokens: ${finalStats.inputTokens}\nTotal cached input tokens: ${finalStats.cachedInputTokens}\nTotal output tokens: ${finalStats.outputTokens}\nTotal turns: ${finalStats.turns}`\n );\n\n outro(chalk.green('✅ Locadex i18n complete!'));\n await exit(0);\n}\n\nfunction getPrompt({\n targetFile,\n dependencyFiles,\n dependentFiles,\n}: {\n targetFile: string[];\n dependencyFiles: Record<string, string[]>;\n dependentFiles: Record<string, string[]>;\n}) {\n const prompt = `# Task: Internationalize the target file(s) using gt-next.\n\n## INSTRUCTIONS\n\n- You are given a list of target files and their corresponding dependency/dependent files.\n- The project is already setup for internationalization. Do not try to setup the project again for i18n.\n\n## Workflow:\n1. **Gather context** Read the target files closely (you should not have to read the dependency/dependent files).\n2. **Evaluate if i18n is necessary** Evaluate if the target files need to be internationalized using gt-next \n - If the target files have no relevant content, are already internationalized, or contain build-time code (e.g. nextjs plugins) they should never be internationalized.\n**IMPORTANT**: IF NONE OF THE TARGET FILES NEED TO BE INTERNATIONALIZED, YOUR TASK IS COMPLETE AND YOU MAY RETURN.\n3. **Identify the tools to use** Given the contents of the files, ask yourself which tools and guides you need to use to get the necessary knowledge to internationalize the target files. Here are some helpful questions to evaluate for tool selection:\n - 3.a. Does this file contain a component? If so, is it a server-side component or a client-side component?\n - 3.b. Is the content that needs to be i18ned being used in this same file, or is it being used in another file?\n - 3.c. Is there any string interpolation that needs to be i18ned?\n - 3.d. Is there any conditional logic or rendering that needs to be i18ned?\n - 3.e. Is the content that needs to be i18ned HTML/JSX or a string?\n4. **Internationalize** You now have the necessary knowledge. Internationalize the files using the information from the tools provided to you.\n - 4.a. Do not worry about running tsc. We will do that later.\n\n## RULES:\n- ALWAYS use the <T> component to internationalize HTML/JSX content.\n- ALWAYS use getGT() or useGT() and getDict() or useDict() to internationalize string content (strings created with '', \"\", or \\`\\`).\n - When possible, avoid using getDict() or useDict(); getGT() and useGT() are preferred.\n- DO NOT internationalize non-user facing content or content that is functional, such as ids, class names, error strings, logical strings, etc.\n- Do not add i18n middleware to the app.\n- When adding 'useGT()' or 'useDict()' to a client component, you must add 'use client' to the top of the file.\n- Always adhere to the guides provided via the 'mcp__locadex__' tools.\n - These guides provide additional knowledge about how to internationalize the content.\n- Minimize the footprint of your changes.\n- Focus on internationalizing the content of the target files.\n- NEVER move internationalized content to a different file. All content MUST remain in the same file where it came from.\n- NEVER CREATE OR REMOVE ANY FILES (especially .bak files)\n- Internationalize all user facing content in the target files. \n- NEVER EDIT FILES THAT ARE NOT GIVEN TO YOU.\n\n## TARGET FILE INFORMATION\n${targetFile.map(\n (file, index) => `\nTARGET FILE ${index + 1}:\n${file}\n\nDEPENDENCY FILES (files imported by target file ${index + 1}):\n${dependencyFiles[file].length > 0 ? ` ${dependencyFiles[file].join(', ')}` : 'none'}\n\nDEPENDENT FILES (files that import target file ${index + 1}):\n${dependentFiles[file].length > 0 ? ` ${dependentFiles[file].join(', ')}` : 'none'}\n`\n)}\n\n---\n\n## MCP TOOLS\n\n${allMcpPrompt}\n\n## Final output\n- When you are done, please return a brief summary of the files you modified, following this format.\n- **DO NOT** include any other text in your response. \n- If there were issues with some files, please include the issues in the list of changes for that file.\n\n[file 1 path]\n- List of changes to file 1\n`;\n\n return prompt;\n}\n\n// check (dry run and ts check) should be at the end\n\nfunction getFixPrompt() {\n const prompt = `# Task: Fix internationalization errors in the project.\n\n## INSTRUCTIONS\n\nPreviously, you helped me internationalize a set of files in this project.\nYour new task is as follows:\n\n1. Run the gt-next validator.\n2. Fix all errors output by the gt-next validator.\n3. Whenever you are finished with your changes, run the gt-next validator.\n4. Repeat steps 1-3 until there are no more errors, or until you believe that you have fixed all errors.\n5. If the project is setup with linting, lint the project and fix all lint errors.\n\n## RULES:\n- ONLY modify files that are relevant to the internationalization of the project.\n- ONLY fix errors that result from your current or previous implementation.\n- Resolve unused imports from 'gt-next'. \n - In particular, if a file contains user-facing content that should be internationalized and is not, you should internationalize it.\n- Resolve missing imports from 'gt-next'. If a file is missing an import from 'gt-next', add it.\n\nTo run the gt-next validator, run the following command:\n'npx locadex translate --dry-run'\n\n## MCP TOOLS\n\n${allMcpPrompt}\n\n## Final output\n- When you are done, please return a brief summary of the files you modified, following this format.\n- **DO NOT** include any other text in your response. \n- If there were issues with some files, please include the issues in the list of changes for that file.\n\n[file 1 path]\n- List of changes to file 1\n`;\n\n return prompt;\n}\n"],"names":[],"mappings":"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","debug_id":"54eae907-9732-5dfd-ac3a-fcec8e6df321"}
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"/","sources":["tasks/i18n.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSpinner } from '../logging/console.js';\nimport { allMcpPrompt } from '../prompts/system.js';\nimport { exit } from '../utils/shutdown.js';\nimport { logger } from '../logging/logger.js';\nimport { LocadexManager } from '../utils/locadexManager.js';\nimport {\n addFilesToManager,\n markFileAsEdited,\n markFileAsInProgress,\n} from '../utils/dag/getFiles.js';\nimport { runParallelProcessing, TaskProcessor } from './concurrency.js';\nimport { outro } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { appendFileSync } from 'node:fs';\nimport { detectFormatter, formatFiles } from 'gtx-cli/hooks/postProcess';\nimport path from 'node:path';\nimport { updateLockfile, cleanupLockfile } from '../utils/lockfile.js';\nimport { installClaudeCode } from '../utils/packages/installPackage.js';\nimport { extractFiles } from '../utils/dag/extractFiles.js';\nimport { Dag } from '../utils/dag/createDag.js';\nimport { getPackageJson, isPackageInstalled } from 'gtx-cli/utils/packageJson';\nimport { deleteAddedFiles } from '../utils/fs/git.js';\n\nexport async function i18nTask() {\n const manager = LocadexManager.getInstance();\n // have to use the package.json from the appDir\n const packageJson = await getPackageJson(manager.appDirectory);\n const isUsingGTNext = packageJson\n ? isPackageInstalled('gt-next', packageJson)\n : false;\n if (!isUsingGTNext) {\n logger.error(\n `gt-next not detected in ${manager.appDirectory}. Please specify the correct app directory with the --app-dir flag, or ensure that gt-next is correctly installed in the project.`\n );\n await exit(1);\n }\n\n // Install claude-code if not installed\n await installClaudeCode();\n\n logger.debugMessage('App directory: ' + manager.appDirectory);\n logger.debugMessage('Root directory: ' + manager.rootDirectory);\n\n // Init message\n const spinner = createSpinner();\n spinner.start('Initializing Locadex...');\n\n const { files, dag } = extractFiles(manager);\n\n if (files.length === 0) {\n spinner.stop('No files have changed since last run');\n outro(chalk.green('✅ Locadex i18n complete - no changes detected!'));\n await exit(0);\n }\n\n const filesStateFilePath = manager.getFilesStateFilePath();\n const concurrency = manager.getMaxConcurrency();\n const batchSize = manager.getBatchSize();\n\n // Create the list of files (aka tasks) to process\n const taskQueue = Array.from(files);\n\n // Add files to manager\n const stateFilePath = addFilesToManager(filesStateFilePath, taskQueue);\n spinner.stop('Locadex initialized');\n\n logger.verboseMessage(`Processing ${files.length} modified files`);\n logger.debugMessage(`Track progress here: ${stateFilePath}`);\n logger.debugMessage(`Order:\\n${taskQueue.join('\\n')}`);\n\n logger.message(`Using ${concurrency} concurrent agents`);\n logger.initializeProgressBar(taskQueue.length);\n\n const fileProcessingStartTime = Date.now();\n logger.progressBar.start(`Processing ${taskQueue.length} files...`);\n\n // Shared reports array for collecting results\n const reports: string[] = [];\n\n // Create i18n task processor\n const i18nProcessor: TaskProcessor<\n string,\n {\n dag: Dag;\n files: string[];\n filesStateFilePath: string;\n }\n > = {\n preProcess: async (files, context) => {\n const { dag, filesStateFilePath } = context;\n logger.debugMessage(`Files: ${files.join(', ')}`);\n // Mark tasks as in progress\n await Promise.all(\n files.map((file) => markFileAsInProgress(file, filesStateFilePath))\n );\n\n // Construct prompt\n const dependencies = Object.fromEntries(\n files.map((file) => [\n file,\n Array.from(new Set(dag.getDependencies(file))).map(String),\n ])\n );\n const dependents = Object.fromEntries(\n files.map((file) => [\n file,\n Array.from(new Set(dag.getDependents(file))).map(String),\n ])\n );\n\n return getPrompt({\n targetFile: files,\n dependencyFiles: dependencies,\n dependentFiles: dependents,\n });\n },\n postProcess: async (files, context, agentReport) => {\n const { filesStateFilePath } = context;\n\n // Mark tasks as complete\n await Promise.all(\n files.map((task) => markFileAsEdited(task, filesStateFilePath))\n );\n\n // Add agent report\n reports.push(agentReport);\n\n // Update progress bar\n logger.progressBar.advance(\n files.length,\n `Processed ${Number(((reports.length * files.length) / files.length) * 100).toFixed(2)}% of files`\n );\n\n // Update stats\n manager.stats.updateStats({\n newProcessedFiles: files.length,\n });\n },\n };\n\n // Run parallel processing\n await runParallelProcessing(\n Array.from(taskQueue),\n i18nProcessor,\n { dag, files, filesStateFilePath },\n {\n concurrency,\n batchSize,\n },\n 1\n );\n\n if (manager.isAborted()) {\n return;\n }\n\n logger.progressBar.stop(\n `Processed ${files.length} files [${Math.round(\n (Date.now() - fileProcessingStartTime) / 1000\n )}s]`\n );\n\n // TODO: uncomment\n // // Always clean up the file list when done, regardless of success or failure\n // cleanUp(stateFilePath);\n\n // Create a clean agent for cleanup\n const cleanupAgent = manager.createSingleAgent('claude_cleanup_agent');\n\n logger.initializeSpinner();\n logger.spinner.start('Fixing errors...');\n const fixPrompt = getFixPrompt(manager.appDirectory);\n try {\n await cleanupAgent.run(fixPrompt, { maxTurns: 200 }, 1000, 3);\n reports.push(`## Fixed errors\\n${cleanupAgent.generateReport()}`);\n } catch (error) {\n logger.debugMessage(\n `[claude_cleanup_agent] Fixing errors failed: ${error}`\n );\n manager.stats.recordTelemetry(false);\n outro(chalk.red('❌ Locadex i18n failed!'));\n await exit(1);\n return;\n }\n logger.spinner.stop('Fixed errors');\n\n // Generate report\n const reportSummary = `# Summary of locadex i18n changes\n${reports.join('\\n')}`;\n const summaryFilePath = path.join(\n manager.getLogDirectory(),\n 'locadex-report.md'\n );\n appendFileSync(summaryFilePath, reportSummary);\n logger.step(`Saved summary of changes to: ${summaryFilePath}`);\n\n // cleanup\n const formatter = await detectFormatter();\n if (formatter) {\n await formatFiles(files, formatter);\n }\n\n const lockfilePath = manager.getLockFilePath();\n\n // Update lockfile with processed files\n updateLockfile(files, lockfilePath, manager.rootDirectory);\n\n // Clean up stale entries from lockfile\n cleanupLockfile(lockfilePath, manager.rootDirectory);\n\n logger.message(chalk.dim(`Updated lockfile with ${files.length} files`));\n\n deleteAddedFiles([\n path.relative(manager.rootDirectory, manager.locadexDirectory),\n ]);\n\n logger.info(\n chalk.dim(\n `Total Cost: $${manager.stats.getStats().totalCost.toFixed(2)}\nTotal wall time: ${Math.round(\n (Date.now() - manager.stats.getStats().startTime) / 1000\n )}s\nTotal files processed: ${manager.stats.getStats().processedFiles}`\n )\n );\n\n const finalStats = manager.stats.getStats();\n\n // Record telemetry for final stats\n manager.stats.recordTelemetry(true);\n\n logger.verboseMessage(\n `Total input tokens: ${finalStats.inputTokens}\nTotal cached input tokens: ${finalStats.cachedInputTokens}\nTotal output tokens: ${finalStats.outputTokens}\nTotal turns: ${finalStats.turns}`\n );\n\n outro(chalk.green('✅ Locadex i18n complete!'));\n await exit(0);\n}\n\nfunction getPrompt({\n targetFile,\n dependencyFiles,\n dependentFiles,\n}: {\n targetFile: string[];\n dependencyFiles: Record<string, string[]>;\n dependentFiles: Record<string, string[]>;\n}) {\n const prompt = `# Task: Internationalize the target file(s) using gt-next.\n\n## INSTRUCTIONS\n\n- You are given a list of target files and their corresponding dependency/dependent files.\n- The project is already setup for internationalization. Do not try to setup the project again for i18n.\n\n## Workflow:\n1. **Gather context** Read the target files closely (you should not have to read the dependency/dependent files).\n2. **Evaluate if i18n is necessary** Evaluate if the target files need to be internationalized using gt-next \n - If the target files have no relevant content, are already internationalized, or contain build-time code (e.g. nextjs plugins) they should never be internationalized.\n**IMPORTANT**: IF NONE OF THE TARGET FILES NEED TO BE INTERNATIONALIZED, YOUR TASK IS COMPLETE AND YOU MAY RETURN.\n3. **Identify the tools to use** Given the contents of the files, ask yourself which tools and guides you need to use to get the necessary knowledge to internationalize the target files. Here are some helpful questions to evaluate for tool selection:\n - 3.a. Does this file contain a component? If so, is it a server-side component or a client-side component?\n - 3.b. Is the content that needs to be i18ned being used in this same file, or is it being used in another file?\n - 3.c. Is there any string interpolation that needs to be i18ned?\n - 3.d. Is there any conditional logic or rendering that needs to be i18ned?\n - 3.e. Is the content that needs to be i18ned HTML/JSX or a string?\n4. **Internationalize** You now have the necessary knowledge. Internationalize the files using the information from the tools provided to you.\n - 4.a. Do not worry about running tsc. We will do that later.\n\n## RULES:\n- ALWAYS use the <T> component to internationalize HTML/JSX content.\n- ALWAYS use getGT() or useGT() and getDict() or useDict() to internationalize string content (strings created with '', \"\", or \\`\\`).\n - When possible, avoid using getDict() or useDict(); getGT() and useGT() are preferred.\n- DO NOT internationalize non-user facing content or content that is functional, such as ids, class names, error strings, logical strings, etc.\n- Do not add i18n middleware to the app.\n- When adding 'useGT()' or 'useDict()' to a client component, you must add 'use client' to the top of the file.\n- Always adhere to the guides provided via the 'mcp__locadex__' tools.\n - These guides provide additional knowledge about how to internationalize the content.\n- Minimize the footprint of your changes.\n- Focus on internationalizing the content of the target files.\n- NEVER move internationalized content to a different file. All content MUST remain in the same file where it came from.\n- NEVER CREATE OR DELETE ANY FILES (especially .bak files)\n- Internationalize all user facing content in the target files. \n- NEVER EDIT FILES THAT ARE NOT GIVEN TO YOU.\n\n## TARGET FILE INFORMATION\n${targetFile.map(\n (file, index) => `\nTARGET FILE ${index + 1}:\n${file}\n\nDEPENDENCY FILES (files imported by target file ${index + 1}):\n${dependencyFiles[file].length > 0 ? ` ${dependencyFiles[file].join(', ')}` : 'none'}\n\nDEPENDENT FILES (files that import target file ${index + 1}):\n${dependentFiles[file].length > 0 ? ` ${dependentFiles[file].join(', ')}` : 'none'}\n`\n)}\n\n---\n\n## MCP TOOLS\n\n${allMcpPrompt}\n\n## Final output\n- When you are done, please return a brief summary of the files you modified, following this format.\n- **DO NOT** include any other text in your response. \n- If there were issues with some files, please include the issues in the list of changes for that file.\n\n[file 1 path]\n- List of changes to file 1\n`;\n\n return prompt;\n}\n\n// check (dry run and ts check) should be at the end\n\nfunction getFixPrompt(appDirectory: string) {\n const prompt = `# Task: Fix internationalization errors in the project.\n\n## INSTRUCTIONS\n\nPreviously, you helped me internationalize a set of files in this project.\nYour new task is as follows:\n\n1. Run the gt-next validator.\n2. Fix all errors output by the gt-next validator.\n3. Whenever you are finished with your changes, run the gt-next validator.\n4. Repeat steps 1-3 until there are no more errors, or until you believe that you have fixed all errors.\n\n## RULES:\n- ONLY modify files that are relevant to the internationalization of the project.\n- ONLY fix errors that result from your current or previous implementation.\n- Resolve unused imports from 'gt-next'. \n - In particular, if a file contains user-facing content that should be internationalized and is not, you should internationalize it.\n- Resolve missing imports from 'gt-next'. If a file is missing an import from 'gt-next', add it.\n\nTo run the gt-next validator, run the following command from the app root:\n'npx locadex translate --dry-run'\nThe app root is: \"${appDirectory}\"\n\n## MCP TOOLS\n\n${allMcpPrompt}\n\n## Final output\n- When you are done, please return a brief summary of the files you modified, following this format.\n- **DO NOT** include any other text in your response. \n- If there were issues with some files, please include the issues in the list of changes for that file.\n\n[file 1 path]\n- List of changes to file 1\n`;\n\n return prompt;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"/","sources":["tasks/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"/","sources":["tasks/setup.ts"],"names":[],"mappings":"AA4BA,wBAAsB,SAAS,CAC7B,aAAa,EAAE,OAAO,EACtB,uBAAuB,CAAC,EAAE,MAAM,iBA0HjC"}
|
package/dist/tasks/setup.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="31f685b0-cf93-5fcd-8a58-4c52de0fdfc1")}catch(e){}}();
|
|
3
1
|
import { createSpinner, promptConfirm } from '../logging/console.js';
|
|
4
|
-
import { getPackageJson, isPackageInstalled } from 'gtx-cli/utils/packageJson';
|
|
2
|
+
import { getPackageJson, isPackageInstalled, } from 'gtx-cli/utils/packageJson';
|
|
5
3
|
import { getPackageManager } from 'gtx-cli/utils/packageManager';
|
|
6
4
|
import { installPackage } from 'gtx-cli/utils/installPackage';
|
|
7
5
|
import chalk from 'chalk';
|
|
@@ -12,39 +10,38 @@ import { handleInitGT } from 'gtx-cli/next/parse/handleInitGT';
|
|
|
12
10
|
import { detectFormatter, formatFiles } from 'gtx-cli/hooks/postProcess';
|
|
13
11
|
import { createOrUpdateConfig } from 'gtx-cli/fs/config/setupConfig';
|
|
14
12
|
import { i18nTask } from '../tasks/i18n.js';
|
|
15
|
-
import { validateInitialConfig } from '../utils/config.js';
|
|
16
13
|
import { getNextDirectories } from '../utils/fs/getFiles.js';
|
|
17
14
|
import { LocadexManager } from '../utils/locadexManager.js';
|
|
18
15
|
import { outro } from '@clack/prompts';
|
|
19
16
|
import { appendFileSync } from 'node:fs';
|
|
20
17
|
import path from 'node:path';
|
|
21
18
|
import { exit } from '../utils/shutdown.js';
|
|
22
|
-
import { installClaudeCode } from '../utils/packages/installPackage.js';
|
|
19
|
+
import { addTranslateScript, installClaudeCode, installLocadex, } from '../utils/packages/installPackage.js';
|
|
23
20
|
export async function setupTask(bypassPrompts, specifiedPackageManager) {
|
|
24
|
-
await validateInitialConfig();
|
|
25
21
|
if (!bypassPrompts) {
|
|
26
|
-
|
|
22
|
+
await promptConfirm({
|
|
27
23
|
message: chalk.yellow(`Locadex will modify files! Make sure you have committed or stashed any changes. Do you want to continue?`),
|
|
28
24
|
defaultValue: true,
|
|
29
25
|
cancelMessage: 'Operation cancelled.',
|
|
30
26
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
}
|
|
28
|
+
const manager = LocadexManager.getInstance();
|
|
29
|
+
const packageManager = await getPackageManager(manager.rootDirectory, specifiedPackageManager);
|
|
30
|
+
const appPackageJson = await getPackageJson(manager.appDirectory);
|
|
31
|
+
if (appPackageJson) {
|
|
32
|
+
if (!isPackageInstalled('gt-next', appPackageJson)) {
|
|
33
|
+
const spinner = createSpinner('timer');
|
|
34
|
+
spinner.start(`Installing gt-next with ${packageManager.name}...`);
|
|
35
|
+
await installPackage('gt-next', packageManager, false, manager.appDirectory);
|
|
36
|
+
spinner.stop('Automatically installed gt-next.');
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
|
-
const packageJson = await getPackageJson();
|
|
37
|
-
const packageManager = await getPackageManager(specifiedPackageManager);
|
|
38
|
-
const spinner = createSpinner('timer');
|
|
39
|
-
spinner.start(`Installing gt-next with ${packageManager.name}...`);
|
|
40
|
-
await installPackage('gt-next', packageManager);
|
|
41
|
-
spinner.stop('Automatically installed gt-next.');
|
|
42
39
|
const nextConfigPath = findFilepaths([
|
|
43
40
|
'./next.config.js',
|
|
44
41
|
'./next.config.ts',
|
|
45
42
|
'./next.config.mjs',
|
|
46
43
|
'./next.config.mts',
|
|
47
|
-
])[0];
|
|
44
|
+
], manager.appDirectory)[0];
|
|
48
45
|
if (!nextConfigPath) {
|
|
49
46
|
logger.error('No next.config.[js|ts|mjs|mts] file found.');
|
|
50
47
|
await exit(1);
|
|
@@ -56,7 +53,7 @@ export async function setupTask(bypassPrompts, specifiedPackageManager) {
|
|
|
56
53
|
babel.start('Wrapping <GTProvider> tags...');
|
|
57
54
|
// Wrap all JSX elements in the src directory with a <T> tag, with unique ids
|
|
58
55
|
const { filesUpdated: filesUpdatedNext } = await wrapContentNext({
|
|
59
|
-
src: getNextDirectories(),
|
|
56
|
+
src: getNextDirectories(manager.appDirectory),
|
|
60
57
|
config: nextConfigPath,
|
|
61
58
|
disableIds: true,
|
|
62
59
|
disableFormatting: true,
|
|
@@ -69,24 +66,23 @@ export async function setupTask(bypassPrompts, specifiedPackageManager) {
|
|
|
69
66
|
await handleInitGT(nextConfigPath, errors, warnings, filesUpdated);
|
|
70
67
|
logger.step(`Added withGTConfig() to your ${nextConfigPath} file.`);
|
|
71
68
|
// Create gt.config.json
|
|
72
|
-
await createOrUpdateConfig('gt.config.json', {
|
|
69
|
+
await createOrUpdateConfig(path.resolve(manager.appDirectory, 'gt.config.json'), {
|
|
73
70
|
defaultLocale: 'en',
|
|
74
71
|
locales: ['es', 'fr', 'de', 'ja', 'zh'],
|
|
75
72
|
framework: 'next-app',
|
|
76
73
|
});
|
|
77
74
|
logger.success(`Feel free to edit ${chalk.cyan('gt.config.json')} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`);
|
|
75
|
+
// Add translate to scripts
|
|
76
|
+
if (appPackageJson) {
|
|
77
|
+
await addTranslateScript(manager, appPackageJson, packageManager);
|
|
78
|
+
}
|
|
78
79
|
// Install claude-code if not installed
|
|
79
80
|
await installClaudeCode();
|
|
80
81
|
// Install locadex if not installed
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const packageManager = await getPackageManager();
|
|
86
|
-
const spinner = createSpinner();
|
|
87
|
-
spinner.start(`Installing locadex as a dev dependency with ${packageManager.name}...`);
|
|
88
|
-
await installPackage('locadex', packageManager, true);
|
|
89
|
-
spinner.stop(chalk.green('Installed locadex.'));
|
|
82
|
+
const rootPackageJson = await getPackageJson(manager.rootDirectory);
|
|
83
|
+
if (rootPackageJson &&
|
|
84
|
+
!isPackageInstalled('locadex', rootPackageJson, true, true)) {
|
|
85
|
+
await installLocadex(manager);
|
|
90
86
|
}
|
|
91
87
|
// Set up locale selector
|
|
92
88
|
await setupLocaleSelector();
|
|
@@ -104,14 +100,14 @@ async function setupLocaleSelector() {
|
|
|
104
100
|
const manager = LocadexManager.getInstance();
|
|
105
101
|
const agent = manager.createSingleAgent('claude_setup_agent');
|
|
106
102
|
// Fix prompt
|
|
107
|
-
const localeSelectorPrompt = getLocaleSelectorPrompt();
|
|
103
|
+
const localeSelectorPrompt = getLocaleSelectorPrompt(manager.appDirectory);
|
|
108
104
|
try {
|
|
109
|
-
await agent.run({
|
|
105
|
+
await agent.run(localeSelectorPrompt, { maxTurns: 50 }, 1000, 3);
|
|
110
106
|
// Generate report
|
|
111
107
|
const report = agent.generateReport();
|
|
112
108
|
const reportSummary = `# Summary of locadex setup changes
|
|
113
109
|
${report}`;
|
|
114
|
-
const summaryFilePath = path.join(manager.
|
|
110
|
+
const summaryFilePath = path.join(manager.getLogDirectory(), 'locadex-report.md');
|
|
115
111
|
appendFileSync(summaryFilePath, reportSummary);
|
|
116
112
|
}
|
|
117
113
|
catch (error) {
|
|
@@ -125,15 +121,16 @@ ${report}`;
|
|
|
125
121
|
}
|
|
126
122
|
logger.spinner.stop('Locale selector setup complete');
|
|
127
123
|
}
|
|
128
|
-
function getLocaleSelectorPrompt() {
|
|
129
|
-
const prompt = `# Task: Add a locale selector to the
|
|
124
|
+
function getLocaleSelectorPrompt(appDirectory) {
|
|
125
|
+
const prompt = `# Task: Add a locale selector to the app
|
|
130
126
|
|
|
131
127
|
## Instructions
|
|
132
128
|
- The locale selector should be a dropdown that allows the user to select the locale.
|
|
129
|
+
- The app root is: "${appDirectory}"
|
|
133
130
|
|
|
134
131
|
## LOCALE SELECTOR USAGE
|
|
135
132
|
(1) Import the locale selector component from 'gt-next/client'
|
|
136
|
-
(2) Add the locale selector to the
|
|
133
|
+
(2) Add the locale selector to the app
|
|
137
134
|
|
|
138
135
|
For example:
|
|
139
136
|
import { LocaleSelector } from 'gt-next/client';
|
|
@@ -147,19 +144,16 @@ function MyComponent() {
|
|
|
147
144
|
);
|
|
148
145
|
}
|
|
149
146
|
|
|
150
|
-
##
|
|
151
|
-
- The locale selector should be added to a header or footer or some other very obvious place in the
|
|
147
|
+
## RULES
|
|
148
|
+
- The locale selector should be added to a header or footer or some other very obvious place in the app.
|
|
152
149
|
- Scan across files to find the best place to add the locale selector.
|
|
150
|
+
- **DO NOT** create new files. You may only modify existing files.
|
|
151
|
+
- You do not need to mark the component containing the LocaleSelector with 'use client'. The LocaleSelector component is already internally marked with 'use client'.
|
|
153
152
|
|
|
154
153
|
## Final output
|
|
155
|
-
- When you are done, please return a brief summary of the files you modified
|
|
156
|
-
- **DO NOT** include any other text in your response.
|
|
157
|
-
- If there were issues with some files, please include the issues in the list of changes for that file.
|
|
158
|
-
|
|
159
|
-
[file 1 path]
|
|
160
|
-
- List of changes to file 1
|
|
154
|
+
- When you are done, please return a **brief summary** of the files you modified.
|
|
155
|
+
- **DO NOT** include any other text in your response.
|
|
161
156
|
`;
|
|
162
157
|
return prompt;
|
|
163
158
|
}
|
|
164
|
-
//# sourceMappingURL=setup.js.map
|
|
165
|
-
//# debugId=31f685b0-cf93-5fcd-8a58-4c52de0fdfc1
|
|
159
|
+
//# sourceMappingURL=setup.js.map
|