locadex 0.1.4 → 0.1.6
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 +15 -0
- package/dist/resources/getResource.d.ts +5 -0
- package/dist/resources/getResource.d.ts.map +1 -0
- package/dist/resources/getResource.js +16 -0
- package/dist/resources/getResource.js.map +1 -0
- package/dist/tasks/concurrency.js +2 -2
- package/dist/tasks/concurrency.js.map +1 -1
- package/dist/tasks/i18n.d.ts.map +1 -1
- package/dist/tasks/i18n.js +24 -6
- package/dist/tasks/i18n.js.map +1 -1
- package/dist/tasks/setup.d.ts.map +1 -1
- package/dist/tasks/setup.js +28 -3
- package/dist/tasks/setup.js.map +1 -1
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +6 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/exec.d.ts +2 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +43 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/fs/git.d.ts +3 -2
- package/dist/utils/fs/git.d.ts.map +1 -1
- package/dist/utils/fs/git.js +8 -5
- package/dist/utils/fs/git.js.map +1 -1
- package/package.json +4 -3
- package/resources/ghaYaml.yml +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# locadex
|
|
2
2
|
|
|
3
|
+
## 0.1.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#391](https://github.com/generaltranslation/gt/pull/391) [`dd41343`](https://github.com/generaltranslation/gt/commit/dd413435742930d995c9fdb84368a91381da3d65) Thanks [@brian-lou](https://github.com/brian-lou)! - Improve logs for cli; Improve QOL setup for locadex
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`dd41343`](https://github.com/generaltranslation/gt/commit/dd413435742930d995c9fdb84368a91381da3d65)]:
|
|
10
|
+
- gtx-cli@1.2.26
|
|
11
|
+
|
|
12
|
+
## 0.1.5
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#384](https://github.com/generaltranslation/gt/pull/384) [`1690a7b`](https://github.com/generaltranslation/gt/commit/1690a7b0361cd00dbadb85d15182f6e97a46d877) Thanks [@brian-lou](https://github.com/brian-lou)! - Update default matchingFiles value
|
|
17
|
+
|
|
3
18
|
## 0.1.4
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getResource.d.ts","sourceRoot":"/","sources":["resources/getResource.ts"],"names":[],"mappings":"AAKA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CASA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { fromPackageRoot } from '../utils/getPaths.js';
|
|
4
|
+
import { logger } from '../logging/logger.js';
|
|
5
|
+
export function getResource(path) {
|
|
6
|
+
try {
|
|
7
|
+
const filePath = fromPackageRoot(join('resources', path));
|
|
8
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
9
|
+
return { content };
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
logger.log(`Error reading resource ${path}: ${error}`);
|
|
13
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=getResource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getResource.js","sourceRoot":"/","sources":["resources/getResource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,UAAU,WAAW,CAAC,IAAY;IAItC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,0BAA0B,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3E,CAAC;AACH,CAAC","sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { fromPackageRoot } from '../utils/getPaths.js';\nimport { logger } from '../logging/logger.js';\n\nexport function getResource(path: string): {\n content?: string;\n error?: string;\n} {\n try {\n const filePath = fromPackageRoot(join('resources', path));\n const content = readFileSync(filePath, 'utf-8');\n return { content };\n } catch (error) {\n logger.log(`Error reading resource ${path}: ${error}`);\n return { error: error instanceof Error ? error.message : String(error) };\n }\n}\n"]}
|
|
@@ -37,7 +37,7 @@ import { outro } from '@clack/prompts';
|
|
|
37
37
|
* );
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
|
-
export async function runParallelProcessing(taskQueue, processor, context, options, maxRetries =
|
|
40
|
+
export async function runParallelProcessing(taskQueue, processor, context, options, maxRetries = 3) {
|
|
41
41
|
const { concurrency, batchSize } = options;
|
|
42
42
|
const manager = LocadexManager.getInstance();
|
|
43
43
|
const agentAbortController = manager.getAgentAbortController();
|
|
@@ -88,7 +88,7 @@ export async function runParallelProcessing(taskQueue, processor, context, optio
|
|
|
88
88
|
// Claude call with timeout and retry (handled inside agent.run)
|
|
89
89
|
await agent.run(prompt, {
|
|
90
90
|
timeoutSec: dynamicTimeoutSec,
|
|
91
|
-
maxRetries
|
|
91
|
+
maxRetries,
|
|
92
92
|
}, {});
|
|
93
93
|
const agentReport = agent.generateReport();
|
|
94
94
|
manager.markAgentFree(agentId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"concurrency.js","sourceRoot":"/","sources":["tasks/concurrency.ts"],"names":[],"mappings":"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","sourcesContent":["import { LocadexManager } from '../utils/locadexManager.js';\nimport { logger } from '../logging/logger.js';\nimport { exit } from '../utils/shutdown.js';\nimport chalk from 'chalk';\nimport { outro } from '@clack/prompts';\n\n/**\n * Interface for defining how to process tasks in parallel.\n * Separates task preparation (preProcess) from result handling (postProcess).\n *\n * @template TTask - The type of individual tasks being processed\n * @template TContext - The type of shared context/configuration\n */\nexport interface TaskProcessor<TTask, TContext> {\n /**\n * Prepares tasks for processing and generates the prompt for the AI agent.\n * Called before each batch is sent to an agent.\n *\n * @param tasks - Batch of tasks to process\n * @param context - Shared context containing configuration and state\n * @returns Promise that resolves to the prompt string for the AI agent\n */\n preProcess: (tasks: TTask[], context: TContext) => Promise<string>;\n\n /**\n * Handles the results after the AI agent completes processing.\n * Called after each batch is successfully processed.\n *\n * @param tasks - The batch of tasks that were processed\n * @param context - Shared context containing configuration and state\n * @param agentReport - The report/output generated by the AI agent\n */\n postProcess: (\n tasks: TTask[],\n context: TContext,\n agentReport: string\n ) => Promise<void>;\n}\n\n/**\n * Configuration options for parallel processing behavior.\n */\nexport interface ParallelProcessingOptions {\n /** Number of concurrent agents to run in parallel */\n concurrency: number;\n /** Number of tasks to process in each batch */\n batchSize: number;\n}\n\n/**\n * Executes tasks in parallel using a pool of agents with proper concurrency control.\n *\n * This is a generic parallel processing framework that handles:\n * - Task queue management with thread-safe access\n * - Agent pool creation and lifecycle management\n * - Error handling and abort signal propagation\n * - Proper cleanup and resource management\n *\n * @template TTask - The type of tasks to process (e.g., string, object, etc.)\n * @template TContext - The type of context passed to the processor functions\n *\n * @param taskQueue - Array of tasks to process. Will be consumed (mutated) during processing.\n * @param processor - Object implementing preProcess and postProcess methods for task handling\n * @param context - Context object passed to processor methods, containing shared state/config\n * @param options - Configuration for parallel processing (concurrency level, batch size)\n *\n * @throws {Error} If processing fails or is aborted\n *\n * @example\n * ```typescript\n * const processor: TaskProcessor<string, { config: Config }> = {\n * preProcess: async (files, context) => generatePrompt(files, context.config),\n * postProcess: async (files, context, report) => handleResults(files, report)\n * };\n *\n * await runParallelProcessing(\n * ['file1.ts', 'file2.ts'],\n * processor,\n * { config: myConfig },\n * { concurrency: 3, batchSize: 2 }\n * );\n * ```\n */\nexport async function runParallelProcessing<TTask, TContext>(\n taskQueue: TTask[],\n processor: TaskProcessor<TTask, TContext>,\n context: TContext,\n options: ParallelProcessingOptions,\n maxRetries: number = 1\n): Promise<void> {\n const { concurrency, batchSize } = options;\n const manager = LocadexManager.getInstance();\n const agentAbortController = manager.getAgentAbortController();\n\n // Mutex for task queue access\n let taskQueueMutex = Promise.resolve();\n\n // Helper function to safely get tasks from queue\n const getNextTasks = async (batchSize: number): Promise<TTask[]> => {\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 } = 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(`Using agent ${agentId} for ${tasks.length} tasks.`);\n\n // Process tasks using the provided processor\n try {\n // Pre-process: generate prompt\n const prompt = await processor.preProcess(tasks, context);\n\n // dynamic timeout based on the number of tasks\n const dynamicTimeoutSec = manager.getTimeoutFactor() * tasks.length;\n\n // Claude call with timeout and retry (handled inside agent.run)\n await agent.run(\n prompt,\n {\n timeoutSec: dynamicTimeoutSec,\n maxRetries: 1,\n },\n {}\n );\n\n const agentReport = agent.generateReport();\n manager.markAgentFree(agentId);\n\n // Post-process: handle reports, progress, etc.\n await processor.postProcess(tasks, context, agentReport);\n } catch (error) {\n logger.debugMessage(`[${agentId}] error: ${error}`);\n throw error;\n }\n }\n };\n\n // Create agent pool with 100 (soft) turns cutoff\n manager.createAgentPool({ softTurnLimit: 100 });\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 manager.getAgentPool().forEach((agentInfo) => {\n agentInfo.agent.aggregateStats();\n });\n manager.stats.recordTelemetry(false); // do this after aggregateStats()\n\n // Check if this is a manual abort\n if (agentAbortController.signal.aborted) {\n return;\n }\n\n outro(\n chalk.red('❌ Locadex failed with error: ' + (error as Error).message)\n );\n await exit(1); // Exit the process\n }\n manager.getAgentPool().forEach((agentInfo) => {\n agentInfo.agent.aggregateStats();\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"concurrency.js","sourceRoot":"/","sources":["tasks/concurrency.ts"],"names":[],"mappings":"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","sourcesContent":["import { LocadexManager } from '../utils/locadexManager.js';\nimport { logger } from '../logging/logger.js';\nimport { exit } from '../utils/shutdown.js';\nimport chalk from 'chalk';\nimport { outro } from '@clack/prompts';\n\n/**\n * Interface for defining how to process tasks in parallel.\n * Separates task preparation (preProcess) from result handling (postProcess).\n *\n * @template TTask - The type of individual tasks being processed\n * @template TContext - The type of shared context/configuration\n */\nexport interface TaskProcessor<TTask, TContext> {\n /**\n * Prepares tasks for processing and generates the prompt for the AI agent.\n * Called before each batch is sent to an agent.\n *\n * @param tasks - Batch of tasks to process\n * @param context - Shared context containing configuration and state\n * @returns Promise that resolves to the prompt string for the AI agent\n */\n preProcess: (tasks: TTask[], context: TContext) => Promise<string>;\n\n /**\n * Handles the results after the AI agent completes processing.\n * Called after each batch is successfully processed.\n *\n * @param tasks - The batch of tasks that were processed\n * @param context - Shared context containing configuration and state\n * @param agentReport - The report/output generated by the AI agent\n */\n postProcess: (\n tasks: TTask[],\n context: TContext,\n agentReport: string\n ) => Promise<void>;\n}\n\n/**\n * Configuration options for parallel processing behavior.\n */\nexport interface ParallelProcessingOptions {\n /** Number of concurrent agents to run in parallel */\n concurrency: number;\n /** Number of tasks to process in each batch */\n batchSize: number;\n}\n\n/**\n * Executes tasks in parallel using a pool of agents with proper concurrency control.\n *\n * This is a generic parallel processing framework that handles:\n * - Task queue management with thread-safe access\n * - Agent pool creation and lifecycle management\n * - Error handling and abort signal propagation\n * - Proper cleanup and resource management\n *\n * @template TTask - The type of tasks to process (e.g., string, object, etc.)\n * @template TContext - The type of context passed to the processor functions\n *\n * @param taskQueue - Array of tasks to process. Will be consumed (mutated) during processing.\n * @param processor - Object implementing preProcess and postProcess methods for task handling\n * @param context - Context object passed to processor methods, containing shared state/config\n * @param options - Configuration for parallel processing (concurrency level, batch size)\n *\n * @throws {Error} If processing fails or is aborted\n *\n * @example\n * ```typescript\n * const processor: TaskProcessor<string, { config: Config }> = {\n * preProcess: async (files, context) => generatePrompt(files, context.config),\n * postProcess: async (files, context, report) => handleResults(files, report)\n * };\n *\n * await runParallelProcessing(\n * ['file1.ts', 'file2.ts'],\n * processor,\n * { config: myConfig },\n * { concurrency: 3, batchSize: 2 }\n * );\n * ```\n */\nexport async function runParallelProcessing<TTask, TContext>(\n taskQueue: TTask[],\n processor: TaskProcessor<TTask, TContext>,\n context: TContext,\n options: ParallelProcessingOptions,\n maxRetries: number = 3\n): Promise<void> {\n const { concurrency, batchSize } = options;\n const manager = LocadexManager.getInstance();\n const agentAbortController = manager.getAgentAbortController();\n\n // Mutex for task queue access\n let taskQueueMutex = Promise.resolve();\n\n // Helper function to safely get tasks from queue\n const getNextTasks = async (batchSize: number): Promise<TTask[]> => {\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 } = 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(`Using agent ${agentId} for ${tasks.length} tasks.`);\n\n // Process tasks using the provided processor\n try {\n // Pre-process: generate prompt\n const prompt = await processor.preProcess(tasks, context);\n\n // dynamic timeout based on the number of tasks\n const dynamicTimeoutSec = manager.getTimeoutFactor() * tasks.length;\n\n // Claude call with timeout and retry (handled inside agent.run)\n await agent.run(\n prompt,\n {\n timeoutSec: dynamicTimeoutSec,\n maxRetries,\n },\n {}\n );\n\n const agentReport = agent.generateReport();\n manager.markAgentFree(agentId);\n\n // Post-process: handle reports, progress, etc.\n await processor.postProcess(tasks, context, agentReport);\n } catch (error) {\n logger.debugMessage(`[${agentId}] error: ${error}`);\n throw error;\n }\n }\n };\n\n // Create agent pool with 100 (soft) turns cutoff\n manager.createAgentPool({ softTurnLimit: 100 });\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 manager.getAgentPool().forEach((agentInfo) => {\n agentInfo.agent.aggregateStats();\n });\n manager.stats.recordTelemetry(false); // do this after aggregateStats()\n\n // Check if this is a manual abort\n if (agentAbortController.signal.aborted) {\n return;\n }\n\n outro(\n chalk.red('❌ Locadex failed with error: ' + (error as Error).message)\n );\n await exit(1); // Exit the process\n }\n manager.getAgentPool().forEach((agentInfo) => {\n agentInfo.agent.aggregateStats();\n });\n}\n"]}
|
package/dist/tasks/i18n.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"/","sources":["tasks/i18n.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"/","sources":["tasks/i18n.ts"],"names":[],"mappings":"AA4BA,wBAAsB,QAAQ,kBAoM7B"}
|
package/dist/tasks/i18n.js
CHANGED
|
@@ -18,6 +18,8 @@ import { CLAUDE_CODE_VERSION } from '../utils/shared.js';
|
|
|
18
18
|
import { installGlobalPackage } from '../utils/packages/installPackage.js';
|
|
19
19
|
import { fixErrorsTask } from './fixErrors.js';
|
|
20
20
|
import { getLocadexVersion } from '../utils/getPaths.js';
|
|
21
|
+
import { execFunction } from '../utils/exec.js';
|
|
22
|
+
import { isGTAuthConfigured } from '../utils/config.js';
|
|
21
23
|
export async function i18nTask() {
|
|
22
24
|
const manager = LocadexManager.getInstance();
|
|
23
25
|
// have to use the package.json from the appDir
|
|
@@ -101,8 +103,10 @@ export async function i18nTask() {
|
|
|
101
103
|
await runParallelProcessing(Array.from(taskQueue), i18nProcessor, { dag, files, filesStateFilePath }, {
|
|
102
104
|
concurrency,
|
|
103
105
|
batchSize,
|
|
104
|
-
},
|
|
106
|
+
}, 3);
|
|
105
107
|
if (manager.isAborted()) {
|
|
108
|
+
cleanupOnExit();
|
|
109
|
+
await exit(1);
|
|
106
110
|
return;
|
|
107
111
|
}
|
|
108
112
|
logger.progressBar.stop(`Processed ${files.length} files [${Math.round((Date.now() - fileProcessingStartTime) / 1000)}s]`);
|
|
@@ -127,9 +131,25 @@ ${reports.join('\n')}`;
|
|
|
127
131
|
// Clean up stale entries from lockfile
|
|
128
132
|
cleanupLockfile(lockfilePath, manager.rootDirectory);
|
|
129
133
|
logger.message(chalk.dim(`Updated lockfile with ${files.length} files`));
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
// Delete any files the AI may have arbitrarily created
|
|
135
|
+
deleteAddedFiles([path.relative(manager.rootDirectory, manager.locadexDirectory)], ['dictionary.json', 'gt.config.json', 'locadex.yml']);
|
|
136
|
+
cleanupOnExit();
|
|
137
|
+
// Run translate cmd
|
|
138
|
+
if (isGTAuthConfigured()) {
|
|
139
|
+
try {
|
|
140
|
+
await execFunction('locadex', ['translate'], false, manager.appDirectory);
|
|
141
|
+
logger.step(`Translations generated!`);
|
|
142
|
+
}
|
|
143
|
+
catch (error) { }
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
logger.step(`No GT_API_KEY or GT_PROJECT_ID found. Skipping translation...`);
|
|
147
|
+
}
|
|
148
|
+
outro(chalk.green('✅ Locadex i18n complete!'));
|
|
149
|
+
await exit(0);
|
|
150
|
+
}
|
|
151
|
+
function cleanupOnExit() {
|
|
152
|
+
const manager = LocadexManager.getInstance();
|
|
133
153
|
logger.info(chalk.dim(`Total Cost: $${manager.stats.getStats().totalCost.toFixed(2)}
|
|
134
154
|
Total wall time: ${Math.round((Date.now() - manager.stats.getStats().startTime) / 1000)}s
|
|
135
155
|
Total files processed: ${manager.stats.getStats().processedFiles}`));
|
|
@@ -140,8 +160,6 @@ Total files processed: ${manager.stats.getStats().processedFiles}`));
|
|
|
140
160
|
Total cached input tokens: ${finalStats.cachedInputTokens}
|
|
141
161
|
Total output tokens: ${finalStats.outputTokens}
|
|
142
162
|
Total turns: ${finalStats.turns}`);
|
|
143
|
-
outro(chalk.green('✅ Locadex i18n complete!'));
|
|
144
|
-
await exit(0);
|
|
145
163
|
}
|
|
146
164
|
function getPrompt({ targetFile, dependencyFiles, dependentFiles, }) {
|
|
147
165
|
const prompt = `# Task: Internationalize the target file(s) using gt-next.
|
package/dist/tasks/i18n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 { 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';\nimport { CLAUDE_CODE_VERSION } from '../utils/shared.js';\nimport { installGlobalPackage } from '../utils/packages/installPackage.js';\nimport { fixErrorsTask } from './fixErrors.js';\nimport { getLocadexVersion } from '../utils/getPaths.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 installGlobalPackage('@anthropic-ai/claude-code', CLAUDE_CODE_VERSION);\n // Install locadex if not installed\n await installGlobalPackage('locadex', getLocadexVersion());\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 (processedFiles, context, agentReport) => {\n const { filesStateFilePath } = context;\n\n // Mark tasks as complete\n await Promise.all(\n processedFiles.map((file) => markFileAsEdited(file, filesStateFilePath))\n );\n\n // Add agent report\n reports.push(agentReport);\n\n // Update stats\n manager.stats.updateStats({\n newProcessedFiles: processedFiles.length,\n });\n\n // Update progress bar\n logger.progressBar.advance(\n processedFiles.length,\n `Processed ${Number((manager.stats.getStats().processedFiles / files.length) * 100).toFixed(2)}% of files`\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 const cleanupReports = await fixErrorsTask();\n if (cleanupReports) {\n reports.push(...cleanupReports);\n }\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. Is the content that needs to be i18ned being used in this same file, or is it being used in another file?\n - 3.b. Is there any string interpolation that needs to be i18ned?\n - 3.c. Is there any conditional logic or rendering that needs to be i18ned?\n - 3.d. 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 run validation checks such as tsc. We will do that later.\n\n## RULES:\n- ALWAYS use the <T> component to internationalize HTML/JSX content.\n- ALWAYS use useGT() or useTranslations() to internationalize string content (strings created with '', \"\", or \\`\\`).\n - When possible, avoid using useTranslations(); useGT() is always 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- 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 all user facing content in the target files. \n- NEVER move 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- 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"]}
|
|
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 { 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';\nimport { CLAUDE_CODE_VERSION } from '../utils/shared.js';\nimport { installGlobalPackage } from '../utils/packages/installPackage.js';\nimport { fixErrorsTask } from './fixErrors.js';\nimport { getLocadexVersion } from '../utils/getPaths.js';\nimport { execFunction } from '../utils/exec.js';\nimport { isGTAuthConfigured } from '../utils/config.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 installGlobalPackage('@anthropic-ai/claude-code', CLAUDE_CODE_VERSION);\n // Install locadex if not installed\n await installGlobalPackage('locadex', getLocadexVersion());\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 (processedFiles, context, agentReport) => {\n const { filesStateFilePath } = context;\n\n // Mark tasks as complete\n await Promise.all(\n processedFiles.map((file) => markFileAsEdited(file, filesStateFilePath))\n );\n\n // Add agent report\n reports.push(agentReport);\n\n // Update stats\n manager.stats.updateStats({\n newProcessedFiles: processedFiles.length,\n });\n\n // Update progress bar\n logger.progressBar.advance(\n processedFiles.length,\n `Processed ${Number((manager.stats.getStats().processedFiles / files.length) * 100).toFixed(2)}% of files`\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 3\n );\n\n if (manager.isAborted()) {\n cleanupOnExit();\n await exit(1);\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 const cleanupReports = await fixErrorsTask();\n if (cleanupReports) {\n reports.push(...cleanupReports);\n }\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 // Delete any files the AI may have arbitrarily created\n deleteAddedFiles(\n [path.relative(manager.rootDirectory, manager.locadexDirectory)],\n ['dictionary.json', 'gt.config.json', 'locadex.yml']\n );\n\n cleanupOnExit();\n\n // Run translate cmd\n if (isGTAuthConfigured()) {\n try {\n await execFunction('locadex', ['translate'], false, manager.appDirectory);\n logger.step(`Translations generated!`);\n } catch (error) {}\n } else {\n logger.step(\n `No GT_API_KEY or GT_PROJECT_ID found. Skipping translation...`\n );\n }\n\n outro(chalk.green('✅ Locadex i18n complete!'));\n await exit(0);\n}\n\nfunction cleanupOnExit() {\n const manager = LocadexManager.getInstance();\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\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. Is the content that needs to be i18ned being used in this same file, or is it being used in another file?\n - 3.b. Is there any string interpolation that needs to be i18ned?\n - 3.c. Is there any conditional logic or rendering that needs to be i18ned?\n - 3.d. 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 run validation checks such as tsc. We will do that later.\n\n## RULES:\n- ALWAYS use the <T> component to internationalize HTML/JSX content.\n- ALWAYS use useGT() or useTranslations() to internationalize string content (strings created with '', \"\", or \\`\\`).\n - When possible, avoid using useTranslations(); useGT() is always 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- 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 all user facing content in the target files. \n- NEVER move 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- 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"]}
|
|
@@ -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":"AA0BA,wBAAsB,SAAS,CAC7B,aAAa,EAAE,OAAO,EACtB,uBAAuB,CAAC,EAAE,MAAM,iBA4HjC"}
|
package/dist/tasks/setup.js
CHANGED
|
@@ -13,12 +13,13 @@ import { i18nTask } from '../tasks/i18n.js';
|
|
|
13
13
|
import { getNextDirectories } from '../utils/fs/getFiles.js';
|
|
14
14
|
import { LocadexManager } from '../utils/locadexManager.js';
|
|
15
15
|
import { outro } from '@clack/prompts';
|
|
16
|
-
import { appendFileSync, existsSync, writeFileSync } from 'node:fs';
|
|
16
|
+
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { exit } from '../utils/shutdown.js';
|
|
19
19
|
import { addTranslateScript, installGlobalPackage, } from '../utils/packages/installPackage.js';
|
|
20
20
|
import { CLAUDE_CODE_VERSION } from '../utils/shared.js';
|
|
21
21
|
import { getLocadexVersion } from '../utils/getPaths.js';
|
|
22
|
+
import { getResource } from '../resources/getResource.js';
|
|
22
23
|
export async function setupTask(bypassPrompts, specifiedPackageManager) {
|
|
23
24
|
if (!bypassPrompts) {
|
|
24
25
|
await promptConfirm({
|
|
@@ -88,6 +89,8 @@ export async function setupTask(bypassPrompts, specifiedPackageManager) {
|
|
|
88
89
|
await setupLocaleSelector();
|
|
89
90
|
// Create dictionary.json file if not exists
|
|
90
91
|
setupDictionary(manager);
|
|
92
|
+
// Add locadex github action if not exists
|
|
93
|
+
setupGithubAction(manager);
|
|
91
94
|
const formatter = await detectFormatter();
|
|
92
95
|
if (formatter && filesUpdated.length > 0) {
|
|
93
96
|
await formatFiles(filesUpdated, formatter);
|
|
@@ -104,6 +107,28 @@ function setupDictionary(manager) {
|
|
|
104
107
|
writeFileSync(dictionaryPath, '{}');
|
|
105
108
|
logger.step(`Created ${chalk.cyan('dictionary.json')} file at ${chalk.cyan(dictionaryPath)}.`);
|
|
106
109
|
}
|
|
110
|
+
else {
|
|
111
|
+
logger.step(`Found ${chalk.cyan('dictionary.json')} file at ${chalk.cyan(dictionaryPath)}. Skipping creation...`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function setupGithubAction(manager) {
|
|
115
|
+
const githubActionPath = path.join(manager.rootDirectory, '.github', 'workflows', 'locadex.yml');
|
|
116
|
+
if (!existsSync(githubActionPath)) {
|
|
117
|
+
mkdirSync(path.join(manager.rootDirectory, '.github', 'workflows'), {
|
|
118
|
+
recursive: true,
|
|
119
|
+
});
|
|
120
|
+
const resource = getResource('ghaYaml.yml');
|
|
121
|
+
if (resource.content) {
|
|
122
|
+
writeFileSync(githubActionPath, resource.content);
|
|
123
|
+
logger.step(`Created ${chalk.cyan('locadex.yml')} Github Action at ${chalk.cyan(githubActionPath)}.`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
logger.error(`Error reading resource ghaYaml.yml: ${resource.error}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
logger.step(`Found ${chalk.cyan('locadex.yml')} Github Action at ${chalk.cyan(githubActionPath)}. Skipping creation...`);
|
|
131
|
+
}
|
|
107
132
|
}
|
|
108
133
|
async function setupLocaleSelector() {
|
|
109
134
|
logger.initializeSpinner();
|
|
@@ -147,11 +172,11 @@ function getLocaleSelectorPrompt(appDirectory) {
|
|
|
147
172
|
- The app root is: "${appDirectory}"
|
|
148
173
|
|
|
149
174
|
## LOCALE SELECTOR USAGE
|
|
150
|
-
(1) Import the locale selector component from 'gt-next
|
|
175
|
+
(1) Import the locale selector component from 'gt-next'
|
|
151
176
|
(2) Add the locale selector to the app
|
|
152
177
|
|
|
153
178
|
For example:
|
|
154
|
-
import { LocaleSelector } from 'gt-next
|
|
179
|
+
import { LocaleSelector } from 'gt-next';
|
|
155
180
|
|
|
156
181
|
function MyComponent() {
|
|
157
182
|
return (
|
package/dist/tasks/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"/","sources":["tasks/setup.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSpinner, promptConfirm } from '../logging/console.js';\nimport { getPackageJson, isPackageInstalled } from 'gtx-cli/utils/packageJson';\nimport { getPackageManager } from 'gtx-cli/utils/packageManager';\nimport { installPackage } from 'gtx-cli/utils/installPackage';\nimport chalk from 'chalk';\nimport { logger } from '../logging/logger.js';\nimport { findFilepaths } from '../utils/fs/findConfigs.js';\nimport { wrapContentNext } from 'gtx-cli/next/parse/wrapContent';\nimport { handleInitGT } from 'gtx-cli/next/parse/handleInitGT';\nimport { detectFormatter, formatFiles } from 'gtx-cli/hooks/postProcess';\nimport { createOrUpdateConfig } from 'gtx-cli/fs/config/setupConfig';\nimport { i18nTask } from '../tasks/i18n.js';\nimport { getNextDirectories } from '../utils/fs/getFiles.js';\nimport { LocadexManager } from '../utils/locadexManager.js';\nimport { outro } from '@clack/prompts';\nimport { appendFileSync, existsSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { exit } from '../utils/shutdown.js';\nimport {\n addTranslateScript,\n installGlobalPackage,\n} from '../utils/packages/installPackage.js';\nimport { CLAUDE_CODE_VERSION } from '../utils/shared.js';\nimport { getLocadexVersion } from '../utils/getPaths.js';\n\nexport async function setupTask(\n bypassPrompts: boolean,\n specifiedPackageManager?: string\n) {\n if (!bypassPrompts) {\n await promptConfirm({\n message: chalk.yellow(\n `Locadex will modify files! Make sure you have committed or stashed any changes. Do you want to continue?`\n ),\n defaultValue: true,\n cancelMessage: 'Operation cancelled.',\n });\n }\n\n const manager = LocadexManager.getInstance();\n\n const packageManager = await getPackageManager(\n manager.rootDirectory,\n specifiedPackageManager\n );\n let appPackageJson = await getPackageJson(manager.appDirectory);\n\n if (appPackageJson) {\n if (!isPackageInstalled('gt-next', appPackageJson)) {\n const spinner = createSpinner('timer');\n spinner.start(`Installing gt-next with ${packageManager.name}...`);\n await installPackage(\n 'gt-next',\n packageManager,\n false,\n manager.appDirectory\n );\n spinner.stop('Automatically installed gt-next.');\n }\n }\n\n const nextConfigPath = findFilepaths(\n [\n './next.config.js',\n './next.config.ts',\n './next.config.mjs',\n './next.config.mts',\n ],\n manager.appDirectory\n )[0];\n\n if (!nextConfigPath) {\n logger.error('No next.config.[js|ts|mjs|mts] file found.');\n await exit(1);\n }\n\n const errors: string[] = [];\n const warnings: string[] = [];\n let filesUpdated: string[] = [];\n\n const babel = createSpinner();\n\n babel.start('Wrapping <GTProvider> tags...');\n\n // Wrap all JSX elements in the src directory with a <T> tag, with unique ids\n const { filesUpdated: filesUpdatedNext } = await wrapContentNext(\n {\n src: getNextDirectories(manager.appDirectory),\n config: nextConfigPath,\n disableIds: true,\n disableFormatting: true,\n skipTs: true,\n addGTProvider: true,\n },\n 'gt-next',\n errors,\n warnings\n );\n filesUpdated = [...filesUpdated, ...filesUpdatedNext];\n\n babel.stop(`Modified ${filesUpdated.length} files.`);\n\n // Add the withGTConfig() function to the next.config.js file\n await handleInitGT(nextConfigPath, errors, warnings, filesUpdated);\n logger.step(`Added withGTConfig() to your ${nextConfigPath} file.`);\n\n // Create gt.config.json\n await createOrUpdateConfig(\n path.resolve(manager.appDirectory, 'gt.config.json'),\n {\n defaultLocale: 'en',\n locales: ['es', 'fr', 'de', 'ja', 'zh'],\n framework: 'next-app',\n }\n );\n\n logger.success(\n `Feel free to edit ${chalk.cyan(\n 'gt.config.json'\n )} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`\n );\n\n // Add translate to scripts\n // Re-get the package.json to make sure it's updated\n appPackageJson = await getPackageJson(manager.appDirectory);\n if (appPackageJson) {\n await addTranslateScript(manager, appPackageJson, packageManager);\n }\n\n // Install claude-code if not installed\n await installGlobalPackage('@anthropic-ai/claude-code', CLAUDE_CODE_VERSION);\n\n // Install locadex if not installed\n await installGlobalPackage('locadex', getLocadexVersion());\n\n // Set up locale selector\n await setupLocaleSelector();\n\n // Create dictionary.json file if not exists\n setupDictionary(manager);\n\n const formatter = await detectFormatter();\n if (formatter && filesUpdated.length > 0) {\n await formatFiles(filesUpdated, formatter);\n }\n\n // Run i18n command\n await i18nTask();\n}\n\nfunction setupDictionary(manager: LocadexManager) {\n const usingSrcDirectory = existsSync(path.join(manager.appDirectory, 'src'));\n const dictionaryPath = usingSrcDirectory\n ? path.join(manager.appDirectory, 'src', 'dictionary.json')\n : path.join(manager.appDirectory, 'dictionary.json');\n if (!existsSync(dictionaryPath)) {\n writeFileSync(dictionaryPath, '{}');\n logger.step(\n `Created ${chalk.cyan(\n 'dictionary.json'\n )} file at ${chalk.cyan(dictionaryPath)}.`\n );\n }\n}\n\nasync function setupLocaleSelector() {\n logger.initializeSpinner();\n logger.spinner.start('Creating locale selector...');\n\n // Create agent\n const manager = LocadexManager.getInstance();\n\n const agent = manager.createSingleAgent('claude_setup_agent', {});\n\n // Fix prompt\n const localeSelectorPrompt = getLocaleSelectorPrompt(manager.appDirectory);\n try {\n await agent.run(\n localeSelectorPrompt,\n {\n maxTurns: 50,\n timeoutSec: 120,\n maxRetries: 1,\n },\n {}\n );\n\n // Generate report\n const report = agent.generateReport();\n const reportSummary = `# Summary of locadex setup changes\n${report}`;\n const summaryFilePath = path.join(\n manager.getLogDirectory(),\n 'locadex-report.md'\n );\n appendFileSync(summaryFilePath, reportSummary);\n } catch (error) {\n agent.aggregateStats();\n // Check if this is an abort\n if (manager.getAgentAbortController().signal.aborted) {\n return;\n }\n logger.debugMessage(`[setup] Adding locale selector failed: ${error}`);\n outro(chalk.red('❌ Locadex setup failed!'));\n await exit(1);\n }\n agent.aggregateStats();\n\n logger.spinner.stop('Locale selector setup complete');\n}\n\nfunction getLocaleSelectorPrompt(appDirectory: string) {\n const prompt = `# Task: Add a locale selector to the app\n\n## Instructions\n- The locale selector should be a dropdown that allows the user to select the locale.\n- The app root is: \"${appDirectory}\"\n\n## LOCALE SELECTOR USAGE\n(1) Import the locale selector component from 'gt-next/client'\n(2) Add the locale selector to the app\n\nFor example:\nimport { LocaleSelector } from 'gt-next/client';\n\nfunction MyComponent() {\n return (\n <div>\n <LocaleSelector />\n <p>Hello, world!</p>\n </div>\n );\n}\n\n## RULES\n- The locale selector should be added to a header or footer or some other very obvious place in the app.\n- Scan across files to find the best place to add the locale selector.\n- **DO NOT** create new files. You may only modify existing files.\n- You do not need to mark the component containing the LocaleSelector with 'use client'. The LocaleSelector component is already internally marked with 'use client'.\n\n## Final output\n- When you are done, please return a **brief summary** of the files you modified.\n- **DO NOT** include any other text in your response.\n`;\n return prompt;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"/","sources":["tasks/setup.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSpinner, promptConfirm } from '../logging/console.js';\nimport { getPackageJson, isPackageInstalled } from 'gtx-cli/utils/packageJson';\nimport { getPackageManager } from 'gtx-cli/utils/packageManager';\nimport { installPackage } from 'gtx-cli/utils/installPackage';\nimport chalk from 'chalk';\nimport { logger } from '../logging/logger.js';\nimport { findFilepaths } from '../utils/fs/findConfigs.js';\nimport { wrapContentNext } from 'gtx-cli/next/parse/wrapContent';\nimport { handleInitGT } from 'gtx-cli/next/parse/handleInitGT';\nimport { detectFormatter, formatFiles } from 'gtx-cli/hooks/postProcess';\nimport { createOrUpdateConfig } from 'gtx-cli/fs/config/setupConfig';\nimport { i18nTask } from '../tasks/i18n.js';\nimport { getNextDirectories } from '../utils/fs/getFiles.js';\nimport { LocadexManager } from '../utils/locadexManager.js';\nimport { outro } from '@clack/prompts';\nimport { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { exit } from '../utils/shutdown.js';\nimport {\n addTranslateScript,\n installGlobalPackage,\n} from '../utils/packages/installPackage.js';\nimport { CLAUDE_CODE_VERSION } from '../utils/shared.js';\nimport { getLocadexVersion } from '../utils/getPaths.js';\nimport { getResource } from '../resources/getResource.js';\n\nexport async function setupTask(\n bypassPrompts: boolean,\n specifiedPackageManager?: string\n) {\n if (!bypassPrompts) {\n await promptConfirm({\n message: chalk.yellow(\n `Locadex will modify files! Make sure you have committed or stashed any changes. Do you want to continue?`\n ),\n defaultValue: true,\n cancelMessage: 'Operation cancelled.',\n });\n }\n\n const manager = LocadexManager.getInstance();\n\n const packageManager = await getPackageManager(\n manager.rootDirectory,\n specifiedPackageManager\n );\n let appPackageJson = await getPackageJson(manager.appDirectory);\n\n if (appPackageJson) {\n if (!isPackageInstalled('gt-next', appPackageJson)) {\n const spinner = createSpinner('timer');\n spinner.start(`Installing gt-next with ${packageManager.name}...`);\n await installPackage(\n 'gt-next',\n packageManager,\n false,\n manager.appDirectory\n );\n spinner.stop('Automatically installed gt-next.');\n }\n }\n\n const nextConfigPath = findFilepaths(\n [\n './next.config.js',\n './next.config.ts',\n './next.config.mjs',\n './next.config.mts',\n ],\n manager.appDirectory\n )[0];\n\n if (!nextConfigPath) {\n logger.error('No next.config.[js|ts|mjs|mts] file found.');\n await exit(1);\n }\n\n const errors: string[] = [];\n const warnings: string[] = [];\n let filesUpdated: string[] = [];\n\n const babel = createSpinner();\n\n babel.start('Wrapping <GTProvider> tags...');\n\n // Wrap all JSX elements in the src directory with a <T> tag, with unique ids\n const { filesUpdated: filesUpdatedNext } = await wrapContentNext(\n {\n src: getNextDirectories(manager.appDirectory),\n config: nextConfigPath,\n disableIds: true,\n disableFormatting: true,\n skipTs: true,\n addGTProvider: true,\n },\n 'gt-next',\n errors,\n warnings\n );\n filesUpdated = [...filesUpdated, ...filesUpdatedNext];\n\n babel.stop(`Modified ${filesUpdated.length} files.`);\n\n // Add the withGTConfig() function to the next.config.js file\n await handleInitGT(nextConfigPath, errors, warnings, filesUpdated);\n logger.step(`Added withGTConfig() to your ${nextConfigPath} file.`);\n\n // Create gt.config.json\n await createOrUpdateConfig(\n path.resolve(manager.appDirectory, 'gt.config.json'),\n {\n defaultLocale: 'en',\n locales: ['es', 'fr', 'de', 'ja', 'zh'],\n framework: 'next-app',\n }\n );\n\n logger.success(\n `Feel free to edit ${chalk.cyan(\n 'gt.config.json'\n )} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`\n );\n\n // Add translate to scripts\n // Re-get the package.json to make sure it's updated\n appPackageJson = await getPackageJson(manager.appDirectory);\n if (appPackageJson) {\n await addTranslateScript(manager, appPackageJson, packageManager);\n }\n\n // Install claude-code if not installed\n await installGlobalPackage('@anthropic-ai/claude-code', CLAUDE_CODE_VERSION);\n\n // Install locadex if not installed\n await installGlobalPackage('locadex', getLocadexVersion());\n\n // Set up locale selector\n await setupLocaleSelector();\n\n // Create dictionary.json file if not exists\n setupDictionary(manager);\n\n // Add locadex github action if not exists\n setupGithubAction(manager);\n\n const formatter = await detectFormatter();\n if (formatter && filesUpdated.length > 0) {\n await formatFiles(filesUpdated, formatter);\n }\n\n // Run i18n command\n await i18nTask();\n}\n\nfunction setupDictionary(manager: LocadexManager) {\n const usingSrcDirectory = existsSync(path.join(manager.appDirectory, 'src'));\n const dictionaryPath = usingSrcDirectory\n ? path.join(manager.appDirectory, 'src', 'dictionary.json')\n : path.join(manager.appDirectory, 'dictionary.json');\n if (!existsSync(dictionaryPath)) {\n writeFileSync(dictionaryPath, '{}');\n logger.step(\n `Created ${chalk.cyan(\n 'dictionary.json'\n )} file at ${chalk.cyan(dictionaryPath)}.`\n );\n } else {\n logger.step(\n `Found ${chalk.cyan('dictionary.json')} file at ${chalk.cyan(\n dictionaryPath\n )}. Skipping creation...`\n );\n }\n}\n\nfunction setupGithubAction(manager: LocadexManager) {\n const githubActionPath = path.join(\n manager.rootDirectory,\n '.github',\n 'workflows',\n 'locadex.yml'\n );\n if (!existsSync(githubActionPath)) {\n mkdirSync(path.join(manager.rootDirectory, '.github', 'workflows'), {\n recursive: true,\n });\n const resource = getResource('ghaYaml.yml');\n if (resource.content) {\n writeFileSync(githubActionPath, resource.content);\n logger.step(\n `Created ${chalk.cyan(\n 'locadex.yml'\n )} Github Action at ${chalk.cyan(githubActionPath)}.`\n );\n } else {\n logger.error(`Error reading resource ghaYaml.yml: ${resource.error}`);\n }\n } else {\n logger.step(\n `Found ${chalk.cyan('locadex.yml')} Github Action at ${chalk.cyan(\n githubActionPath\n )}. Skipping creation...`\n );\n }\n}\nasync function setupLocaleSelector() {\n logger.initializeSpinner();\n logger.spinner.start('Creating locale selector...');\n\n // Create agent\n const manager = LocadexManager.getInstance();\n\n const agent = manager.createSingleAgent('claude_setup_agent', {});\n\n // Fix prompt\n const localeSelectorPrompt = getLocaleSelectorPrompt(manager.appDirectory);\n try {\n await agent.run(\n localeSelectorPrompt,\n {\n maxTurns: 50,\n timeoutSec: 120,\n maxRetries: 1,\n },\n {}\n );\n\n // Generate report\n const report = agent.generateReport();\n const reportSummary = `# Summary of locadex setup changes\n${report}`;\n const summaryFilePath = path.join(\n manager.getLogDirectory(),\n 'locadex-report.md'\n );\n appendFileSync(summaryFilePath, reportSummary);\n } catch (error) {\n agent.aggregateStats();\n // Check if this is an abort\n if (manager.getAgentAbortController().signal.aborted) {\n return;\n }\n logger.debugMessage(`[setup] Adding locale selector failed: ${error}`);\n outro(chalk.red('❌ Locadex setup failed!'));\n await exit(1);\n }\n agent.aggregateStats();\n\n logger.spinner.stop('Locale selector setup complete');\n}\n\nfunction getLocaleSelectorPrompt(appDirectory: string) {\n const prompt = `# Task: Add a locale selector to the app\n\n## Instructions\n- The locale selector should be a dropdown that allows the user to select the locale.\n- The app root is: \"${appDirectory}\"\n\n## LOCALE SELECTOR USAGE\n(1) Import the locale selector component from 'gt-next'\n(2) Add the locale selector to the app\n\nFor example:\nimport { LocaleSelector } from 'gt-next';\n\nfunction MyComponent() {\n return (\n <div>\n <LocaleSelector />\n <p>Hello, world!</p>\n </div>\n );\n}\n\n## RULES\n- The locale selector should be added to a header or footer or some other very obvious place in the app.\n- Scan across files to find the best place to add the locale selector.\n- **DO NOT** create new files. You may only modify existing files.\n- You do not need to mark the component containing the LocaleSelector with 'use client'. The LocaleSelector component is already internally marked with 'use client'.\n\n## Final output\n- When you are done, please return a **brief summary** of the files you modified.\n- **DO NOT** include any other text in your response.\n`;\n return prompt;\n}\n"]}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CliOptions, LocadexConfig } from '../types/cli.js';
|
|
2
2
|
export declare function validateConfig(options: CliOptions): Promise<void>;
|
|
3
|
+
export declare function isGTAuthConfigured(): string | undefined;
|
|
3
4
|
export declare function createConfig(directory: string, options: {
|
|
4
5
|
batchSize: number;
|
|
5
6
|
maxConcurrency: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"/","sources":["utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG5D,wBAAsB,cAAc,CAAC,OAAO,EAAE,UAAU,iBA8BvD;AAID,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,QAeF;AAED,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GACnC,aAAa,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"/","sources":["utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG5D,wBAAsB,cAAc,CAAC,OAAO,EAAE,UAAU,iBA8BvD;AAED,wBAAgB,kBAAkB,uBAEjC;AAID,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,QAeF;AAED,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GACnC,aAAa,CA4Bf"}
|
package/dist/utils/config.js
CHANGED
|
@@ -30,6 +30,9 @@ export async function validateConfig(options) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
export function isGTAuthConfigured() {
|
|
34
|
+
return process.env.GT_API_KEY && process.env.GT_PROJECT_ID;
|
|
35
|
+
}
|
|
33
36
|
const CONFIG_FILE_NAME = 'locadex.config.json';
|
|
34
37
|
export function createConfig(directory, options) {
|
|
35
38
|
const configPath = path.resolve(directory, CONFIG_FILE_NAME);
|
|
@@ -48,7 +51,9 @@ export function getConfig(locadexDir, rootDir, appDir, options = {}) {
|
|
|
48
51
|
const DEFAULT_CONFIG = {
|
|
49
52
|
batchSize: 10,
|
|
50
53
|
maxConcurrency: 1,
|
|
51
|
-
matchingFiles: [
|
|
54
|
+
matchingFiles: [
|
|
55
|
+
`${path.relative(rootDir, appDir) || '.'}/**/*.{ts,tsx,js,jsx}`,
|
|
56
|
+
],
|
|
52
57
|
timeout: 60,
|
|
53
58
|
};
|
|
54
59
|
const configPath = path.resolve(locadexDir, CONFIG_FILE_NAME);
|
package/dist/utils/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"/","sources":["utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAmB;IACtD,6BAA6B;IAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CACX,wGAAwG,CACzG,CAAC;QACF,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAC1E,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YACvE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C,MAAM,UAAU,YAAY,CAC1B,SAAiB,EACjB,OAKC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAC7D,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,UAAkB,EAClB,OAAe,EACf,MAAc,EACd,UAAkC,EAAE;IAEpC,MAAM,cAAc,GAAkB;QACpC,SAAS,EAAE,EAAE;QACb,cAAc,EAAE,CAAC;QACjB,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"/","sources":["utils/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { logger } from '../logging/logger.js';\nimport path from 'node:path';\nimport { CliOptions, LocadexConfig } from '../types/cli.js';\nimport { exit } from './shutdown.js';\n\nexport async function validateConfig(options: CliOptions) {\n // Validate ANTHROPIC_API_KEY\n if (!process.env.ANTHROPIC_API_KEY) {\n console.error(\n 'ANTHROPIC_API_KEY is not set! Please set it as an environment variable or in a .env | .env.local file.'\n );\n await exit(1);\n }\n\n if (options.timeout) {\n const timeout = Number(options.timeout);\n if (isNaN(timeout) || timeout <= 0) {\n console.error('Invalid timeout value. Please provide a positive number.');\n await exit(1);\n }\n }\n if (options.batchSize) {\n const batchSize = Number(options.batchSize);\n if (isNaN(batchSize) || batchSize < 1) {\n console.error('Invalid batch size. Please provide a positive number.');\n await exit(1);\n }\n }\n if (options.concurrency) {\n const concurrency = Number(options.concurrency);\n if (isNaN(concurrency) || concurrency < 1) {\n console.error('Invalid concurrency. Please provide a positive number.');\n await exit(1);\n }\n }\n}\n\nexport function isGTAuthConfigured() {\n return process.env.GT_API_KEY && process.env.GT_PROJECT_ID;\n}\n\nconst CONFIG_FILE_NAME = 'locadex.config.json';\n\nexport function createConfig(\n directory: string,\n options: {\n batchSize: number;\n maxConcurrency: number;\n matchingFiles: string[];\n timeout: number;\n }\n) {\n const configPath = path.resolve(directory, CONFIG_FILE_NAME);\n if (existsSync(configPath)) {\n return;\n }\n\n const config = {\n batchSize: options.batchSize,\n maxConcurrency: options.maxConcurrency,\n matchingFiles: options.matchingFiles,\n timeout: options.timeout,\n };\n\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\nexport function getConfig(\n locadexDir: string,\n rootDir: string,\n appDir: string,\n options: Partial<LocadexConfig> = {}\n): LocadexConfig {\n const DEFAULT_CONFIG: LocadexConfig = {\n batchSize: 10,\n maxConcurrency: 1,\n matchingFiles: [\n `${path.relative(rootDir, appDir) || '.'}/**/*.{ts,tsx,js,jsx}`,\n ],\n timeout: 60,\n };\n const configPath = path.resolve(locadexDir, CONFIG_FILE_NAME);\n let fileConfig: Partial<LocadexConfig> = {};\n\n // Load config file if it exists\n if (existsSync(configPath)) {\n try {\n fileConfig = JSON.parse(readFileSync(configPath, 'utf8'));\n } catch (error) {\n logger.error(\n `Error parsing config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`\n );\n // Continue with empty file config on parse error\n }\n }\n\n // Merge configurations: defaults < file config < passed options\n const mergedConfig = { ...DEFAULT_CONFIG, ...fileConfig, ...options };\n\n return mergedConfig;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"/","sources":["utils/exec.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,GAAE,OAAc,EAC1B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAyCf"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { logger } from '../logging/logger.js';
|
|
4
|
+
export async function execFunction(command, args, pipeStdout = true, cwd = process.cwd()) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const childProcess = spawn(command, args, {
|
|
7
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
8
|
+
cwd,
|
|
9
|
+
});
|
|
10
|
+
let errorOutput = '';
|
|
11
|
+
if (childProcess.stderr) {
|
|
12
|
+
childProcess.stderr.on('data', (data) => {
|
|
13
|
+
errorOutput += data.toString();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
childProcess.stdout.on('data', (data) => {
|
|
17
|
+
if (!pipeStdout) {
|
|
18
|
+
logger.debugMessage(data.toString());
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// eslint-disable-next-line no-console
|
|
22
|
+
console.log(data.toString());
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
childProcess.on('error', (error) => {
|
|
26
|
+
logger.error(chalk.red(`${command} error: ${error.message}`));
|
|
27
|
+
reject(error);
|
|
28
|
+
});
|
|
29
|
+
childProcess.on('close', (code) => {
|
|
30
|
+
if (code === 0) {
|
|
31
|
+
resolve();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
logger.error(chalk.red(`${command} failed with exit code ${code}`));
|
|
35
|
+
if (errorOutput) {
|
|
36
|
+
logger.debugMessage(chalk.red(`Error details: ${errorOutput}`));
|
|
37
|
+
}
|
|
38
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"/","sources":["utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,IAAc,EACd,aAAsB,IAAI,EAC1B,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACxC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,EAAE,CAAC;QAErB,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;YACxB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACtC,WAAW,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACtC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,sCAAsC;gBACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,WAAW,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,0BAA0B,IAAI,EAAE,CAAC,CAAC,CAAC;gBACpE,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,WAAW,EAAE,CAAC,CAAC,CAAC;gBAClE,CAAC;gBACD,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import chalk from 'chalk';\nimport { spawn } from 'node:child_process';\nimport { logger } from '../logging/logger.js';\n\nexport async function execFunction(\n command: string,\n args: string[],\n pipeStdout: boolean = true,\n cwd: string = process.cwd()\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const childProcess = spawn(command, args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd,\n });\n\n let errorOutput = '';\n\n if (childProcess.stderr) {\n childProcess.stderr.on('data', (data) => {\n errorOutput += data.toString();\n });\n }\n\n childProcess.stdout.on('data', (data) => {\n if (!pipeStdout) {\n logger.debugMessage(data.toString());\n } else {\n // eslint-disable-next-line no-console\n console.log(data.toString());\n }\n });\n\n childProcess.on('error', (error) => {\n logger.error(chalk.red(`${command} error: ${error.message}`));\n reject(error);\n });\n\n childProcess.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n logger.error(chalk.red(`${command} failed with exit code ${code}`));\n if (errorOutput) {\n logger.debugMessage(chalk.red(`Error details: ${errorOutput}`));\n }\n reject(new Error(`Process exited with code ${code}`));\n }\n });\n });\n}\n"]}
|
package/dist/utils/fs/git.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Deletes any newly created (untracked) files, except those in ignoreDirectories.
|
|
2
|
+
* Deletes any newly created (untracked) files, except those in ignoreDirectories and ignoreFiles.
|
|
3
3
|
* @param ignoreDirectories - Array of directory names to ignore (relative to repo root).
|
|
4
|
+
* @param ignoreFiles - Array of file names to ignore (relative to repo root).
|
|
4
5
|
*/
|
|
5
|
-
export declare function deleteAddedFiles(ignoreDirectories
|
|
6
|
+
export declare function deleteAddedFiles(ignoreDirectories?: string[], ignoreFiles?: string[]): void;
|
|
6
7
|
//# sourceMappingURL=git.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"/","sources":["utils/fs/git.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"/","sources":["utils/fs/git.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,iBAAiB,GAAE,MAAM,EAAO,EAChC,WAAW,GAAE,MAAM,EAAO,QAiC3B"}
|
package/dist/utils/fs/git.js
CHANGED
|
@@ -2,11 +2,12 @@ import { execSync } from 'child_process';
|
|
|
2
2
|
import { unlinkSync } from 'fs';
|
|
3
3
|
import { logger } from '../../logging/logger.js';
|
|
4
4
|
/**
|
|
5
|
-
* Deletes any newly created (untracked) files, except those in ignoreDirectories.
|
|
5
|
+
* Deletes any newly created (untracked) files, except those in ignoreDirectories and ignoreFiles.
|
|
6
6
|
* @param ignoreDirectories - Array of directory names to ignore (relative to repo root).
|
|
7
|
+
* @param ignoreFiles - Array of file names to ignore (relative to repo root).
|
|
7
8
|
*/
|
|
8
|
-
export function deleteAddedFiles(ignoreDirectories) {
|
|
9
|
-
logger.debugMessage(`Deleting untracked files, ignoring directories: ${ignoreDirectories.join(', ')}`);
|
|
9
|
+
export function deleteAddedFiles(ignoreDirectories = [], ignoreFiles = []) {
|
|
10
|
+
logger.debugMessage(`Deleting untracked files, ignoring directories: ${ignoreDirectories.join(', ')}${ignoreFiles.length > 0 ? `, ignoring files: ${ignoreFiles.join(', ')}` : ''}`);
|
|
10
11
|
// Get list of untracked files from git
|
|
11
12
|
const output = execSync('git status --porcelain', { encoding: 'utf-8' });
|
|
12
13
|
const untrackedFiles = output
|
|
@@ -14,9 +15,11 @@ export function deleteAddedFiles(ignoreDirectories) {
|
|
|
14
15
|
.filter((line) => line.startsWith('?? '))
|
|
15
16
|
.map((line) => line.slice(3).trim())
|
|
16
17
|
.filter((file) => file.length > 0);
|
|
17
|
-
// Filter out files in ignored directories
|
|
18
|
+
// Filter out files in ignored directories and specific files
|
|
18
19
|
const filesToDelete = untrackedFiles.filter((file) => {
|
|
19
|
-
|
|
20
|
+
const isInIgnoredDirectory = ignoreDirectories.some((dir) => file === dir || file.startsWith(dir + '/'));
|
|
21
|
+
const isIgnoredFile = ignoreFiles.some((pattern) => file.includes(pattern));
|
|
22
|
+
return !isInIgnoredDirectory && !isIgnoredFile;
|
|
20
23
|
});
|
|
21
24
|
// Delete each file
|
|
22
25
|
for (const file of filesToDelete) {
|
package/dist/utils/fs/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"/","sources":["utils/fs/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"/","sources":["utils/fs/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,oBAA8B,EAAE,EAChC,cAAwB,EAAE;IAE1B,MAAM,CAAC,YAAY,CACjB,mDAAmD,iBAAiB,CAAC,IAAI,CACvE,IAAI,CACL,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,qBAAqB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAClF,CAAC;IACF,uCAAuC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,MAAM,cAAc,GAAG,MAAM;SAC1B,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACnC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAErC,6DAA6D;IAC7D,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACnD,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,IAAI,CACjD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,CACpD,CAAC;QACF,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,oBAAoB,IAAI,CAAC,aAAa,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,mBAAmB;IACnB,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kCAAkC;QACpC,CAAC;IACH,CAAC;IACD,MAAM,CAAC,cAAc,CAAC,WAAW,aAAa,CAAC,MAAM,kBAAkB,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["import { execSync } from 'child_process';\nimport { unlinkSync } from 'fs';\nimport { logger } from '../../logging/logger.js';\n\n/**\n * Deletes any newly created (untracked) files, except those in ignoreDirectories and ignoreFiles.\n * @param ignoreDirectories - Array of directory names to ignore (relative to repo root).\n * @param ignoreFiles - Array of file names to ignore (relative to repo root).\n */\nexport function deleteAddedFiles(\n ignoreDirectories: string[] = [],\n ignoreFiles: string[] = []\n) {\n logger.debugMessage(\n `Deleting untracked files, ignoring directories: ${ignoreDirectories.join(\n ', '\n )}${ignoreFiles.length > 0 ? `, ignoring files: ${ignoreFiles.join(', ')}` : ''}`\n );\n // Get list of untracked files from git\n const output = execSync('git status --porcelain', { encoding: 'utf-8' });\n const untrackedFiles = output\n .split('\\n')\n .filter((line) => line.startsWith('?? '))\n .map((line) => line.slice(3).trim())\n .filter((file) => file.length > 0);\n\n // Filter out files in ignored directories and specific files\n const filesToDelete = untrackedFiles.filter((file) => {\n const isInIgnoredDirectory = ignoreDirectories.some(\n (dir) => file === dir || file.startsWith(dir + '/')\n );\n const isIgnoredFile = ignoreFiles.some((pattern) => file.includes(pattern));\n return !isInIgnoredDirectory && !isIgnoredFile;\n });\n\n // Delete each file\n for (const file of filesToDelete) {\n try {\n unlinkSync(file);\n } catch (err) {\n // Optionally log or handle errors\n }\n }\n logger.verboseMessage(`Deleted ${filesToDelete.length} untracked files`);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "locadex",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "An AI agent for internationalization",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"resources",
|
|
12
13
|
"CHANGELOG.md",
|
|
13
14
|
"guides"
|
|
14
15
|
],
|
|
@@ -22,13 +23,13 @@
|
|
|
22
23
|
"dependency-tree": "^11.1.1",
|
|
23
24
|
"dotenv": "^16.4.5",
|
|
24
25
|
"express": "^5.1.0",
|
|
25
|
-
"gtx-cli": "^1.2.
|
|
26
|
+
"gtx-cli": "^1.2.26",
|
|
26
27
|
"micromatch": "^4.0.8",
|
|
27
28
|
"posthog-node": "^4.18.0"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@anthropic-ai/sdk": "^0.52.0",
|
|
31
|
-
"@modelcontextprotocol/inspector": "^0.
|
|
32
|
+
"@modelcontextprotocol/inspector": "^0.14.2",
|
|
32
33
|
"@types/express": "^5.0.2",
|
|
33
34
|
"@types/jest": "^29.5.14",
|
|
34
35
|
"@types/micromatch": "^4.0.9",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Locadex
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
pull-requests: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
locadex:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
- name: Run Locadex
|
|
19
|
+
uses: generaltranslation/locadex@v0.1.1
|
|
20
|
+
with:
|
|
21
|
+
api_key: \${{ secrets.LOCADEX_API_KEY }}
|