@arcteninc/core 0.0.61 → 0.0.62

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcteninc/core",
3
- "version": "0.0.61",
3
+ "version": "0.0.62",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -1,132 +1,132 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Arcten CLI - Unified command interface
4
- * Usage: arcten <command> [options]
5
- *
6
- * Commands:
7
- * extract-types, tools Extract tool metadata from your project
8
- * update Update @arcteninc/core to latest version
9
- * help Show help message
10
- */
11
-
12
- const { spawn } = require('child_process');
13
- const path = require('path');
14
- const fs = require('fs');
15
-
16
- const commands = {
17
- 'extract-types': () => require('./cli-extract-types-auto.js'),
18
- 'tools': () => require('./cli-extract-types-auto.js'), // Alias
19
- 'update': () => require('./update-core.js'),
20
- 'help': showHelp,
21
- '--help': showHelp,
22
- '-h': showHelp,
23
- };
24
-
25
- function showHelp() {
26
- console.log(`
27
- šŸ“¦ Arcten CLI
28
-
29
- Usage: arcten <command> [options]
30
-
31
- Commands:
32
- extract-types, tools Extract tool metadata from your project
33
- Alias: arcten tools
34
-
35
- update Update @arcteninc/core to latest version
36
- Updates package.json and shows next steps
37
-
38
- help Show this help message
39
-
40
- Examples:
41
- arcten tools Extract tool types (same as arcten extract-types)
42
- arcten update Update @arcteninc/core to latest version
43
- arcten help Show help
44
-
45
- For more information, visit https://github.com/arcteninc/core
46
- `);
47
- process.exit(0);
48
- }
49
-
50
- function main() {
51
- const args = process.argv.slice(2);
52
-
53
- if (args.length === 0) {
54
- showHelp();
55
- return;
56
- }
57
-
58
- const command = args[0];
59
- const commandArgs = args.slice(1);
60
-
61
- if (!commands[command]) {
62
- console.error(`āŒ Unknown command: ${command}`);
63
- console.error(`\nRun 'arcten help' for available commands`);
64
- process.exit(1);
65
- }
66
-
67
- try {
68
- const commandHandler = commands[command];
69
- if (typeof commandHandler === 'function' && commandHandler !== showHelp) {
70
- // For commands that are modules, we need to handle them differently
71
- // Since they're designed to run as standalone scripts, we'll spawn them
72
- let scriptPath;
73
- let runner = 'node';
74
-
75
- if (command === 'update') {
76
- scriptPath = path.join(__dirname, 'update-core.cjs');
77
- } else {
78
- // For extract-types/tools, try .js first, fallback to .ts with bun
79
- const jsPath = path.join(__dirname, 'cli-extract-types-auto.js');
80
- const tsPath = path.join(__dirname, 'cli-extract-types-auto.ts');
81
-
82
- if (fs.existsSync(jsPath)) {
83
- scriptPath = jsPath;
84
- } else if (fs.existsSync(tsPath)) {
85
- scriptPath = tsPath;
86
- runner = 'bun'; // Use bun for TypeScript files
87
- } else {
88
- console.error(`āŒ Script not found: ${jsPath} or ${tsPath}`);
89
- process.exit(1);
90
- }
91
- }
92
-
93
- if (!fs.existsSync(scriptPath)) {
94
- console.error(`āŒ Script not found: ${scriptPath}`);
95
- process.exit(1);
96
- }
97
-
98
- // Spawn the script with remaining args
99
- const child = spawn(runner, [scriptPath, ...commandArgs], {
100
- stdio: 'inherit',
101
- cwd: process.cwd(),
102
- shell: true // Use shell to find bun/node in PATH
103
- });
104
-
105
- child.on('error', (error) => {
106
- console.error(`āŒ Failed to run command:`, error.message);
107
- if (runner === 'bun' && error.code === 'ENOENT') {
108
- console.error(`\nšŸ’” Bun not found. Install it: https://bun.sh`);
109
- console.error(` Or ensure cli-extract-types-auto.js is compiled`);
110
- }
111
- process.exit(1);
112
- });
113
-
114
- child.on('exit', (code) => {
115
- process.exit(code || 0);
116
- });
117
- } else {
118
- // For help command
119
- commandHandler();
120
- }
121
- } catch (error) {
122
- console.error(`āŒ Error running command:`, error.message);
123
- process.exit(1);
124
- }
125
- }
126
-
127
- if (require.main === module) {
128
- main();
129
- }
130
-
131
- module.exports = { main };
132
-
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Arcten CLI - Unified command interface
4
+ * Usage: arcten <command> [options]
5
+ *
6
+ * Commands:
7
+ * extract-types, tools Extract tool metadata from your project
8
+ * update Update @arcteninc/core to latest version
9
+ * help Show help message
10
+ */
11
+
12
+ const { spawn } = require('child_process');
13
+ const path = require('path');
14
+ const fs = require('fs');
15
+
16
+ const commands = {
17
+ 'extract-types': () => require('./cli-extract-types-auto.js'),
18
+ 'tools': () => require('./cli-extract-types-auto.js'), // Alias
19
+ 'update': () => require('./update-core.js'),
20
+ 'help': showHelp,
21
+ '--help': showHelp,
22
+ '-h': showHelp,
23
+ };
24
+
25
+ function showHelp() {
26
+ console.log(`
27
+ šŸ“¦ Arcten CLI
28
+
29
+ Usage: arcten <command> [options]
30
+
31
+ Commands:
32
+ extract-types, tools Extract tool metadata from your project
33
+ Alias: arcten tools
34
+
35
+ update Update @arcteninc/core to latest version
36
+ Updates package.json and shows next steps
37
+
38
+ help Show this help message
39
+
40
+ Examples:
41
+ arcten tools Extract tool types (same as arcten extract-types)
42
+ arcten update Update @arcteninc/core to latest version
43
+ arcten help Show help
44
+
45
+ For more information, visit https://github.com/arcteninc/core
46
+ `);
47
+ process.exit(0);
48
+ }
49
+
50
+ function main() {
51
+ const args = process.argv.slice(2);
52
+
53
+ if (args.length === 0) {
54
+ showHelp();
55
+ return;
56
+ }
57
+
58
+ const command = args[0];
59
+ const commandArgs = args.slice(1);
60
+
61
+ if (!commands[command]) {
62
+ console.error(`āŒ Unknown command: ${command}`);
63
+ console.error(`\nRun 'arcten help' for available commands`);
64
+ process.exit(1);
65
+ }
66
+
67
+ try {
68
+ const commandHandler = commands[command];
69
+ if (typeof commandHandler === 'function' && commandHandler !== showHelp) {
70
+ // For commands that are modules, we need to handle them differently
71
+ // Since they're designed to run as standalone scripts, we'll spawn them
72
+ let scriptPath;
73
+ let runner = 'node';
74
+
75
+ if (command === 'update') {
76
+ scriptPath = path.join(__dirname, 'update-core.cjs');
77
+ } else {
78
+ // For extract-types/tools, try .js first, fallback to .ts with bun
79
+ const jsPath = path.join(__dirname, 'cli-extract-types-auto.js');
80
+ const tsPath = path.join(__dirname, 'cli-extract-types-auto.ts');
81
+
82
+ if (fs.existsSync(jsPath)) {
83
+ scriptPath = jsPath;
84
+ } else if (fs.existsSync(tsPath)) {
85
+ scriptPath = tsPath;
86
+ runner = 'bun'; // Use bun for TypeScript files
87
+ } else {
88
+ console.error(`āŒ Script not found: ${jsPath} or ${tsPath}`);
89
+ process.exit(1);
90
+ }
91
+ }
92
+
93
+ if (!fs.existsSync(scriptPath)) {
94
+ console.error(`āŒ Script not found: ${scriptPath}`);
95
+ process.exit(1);
96
+ }
97
+
98
+ // Spawn the script with remaining args
99
+ const child = spawn(runner, [scriptPath, ...commandArgs], {
100
+ stdio: 'inherit',
101
+ cwd: process.cwd(),
102
+ shell: true // Use shell to find bun/node in PATH
103
+ });
104
+
105
+ child.on('error', (error) => {
106
+ console.error(`āŒ Failed to run command:`, error.message);
107
+ if (runner === 'bun' && error.code === 'ENOENT') {
108
+ console.error(`\nšŸ’” Bun not found. Install it: https://bun.sh`);
109
+ console.error(` Or ensure cli-extract-types-auto.js is compiled`);
110
+ }
111
+ process.exit(1);
112
+ });
113
+
114
+ child.on('exit', (code) => {
115
+ process.exit(code || 0);
116
+ });
117
+ } else {
118
+ // For help command
119
+ commandHandler();
120
+ }
121
+ } catch (error) {
122
+ console.error(`āŒ Error running command:`, error.message);
123
+ process.exit(1);
124
+ }
125
+ }
126
+
127
+ if (require.main === module) {
128
+ main();
129
+ }
130
+
131
+ module.exports = { main };
132
+
@@ -92,7 +92,8 @@ async function findToolUsageFiles(projectRoot: string): Promise<string[]> {
92
92
  function extractToolNamesFromExpression(
93
93
  expr: ts.Expression,
94
94
  sourceFile: ts.SourceFile,
95
- variableMap: Map<string, ts.Expression>
95
+ variableMap: Map<string, ts.Expression>,
96
+ program?: ts.Program
96
97
  ): { names: Set<string>; order: string[] } {
97
98
  const toolNames = new Set<string>();
98
99
  const toolOrder: string[] = []; // Preserve order
@@ -128,9 +129,12 @@ function extractToolNamesFromExpression(
128
129
  // Property access: tools.getOrders -> extract "getOrders"
129
130
  const propName = element.name.text;
130
131
  if (propName) {
131
- if (!toolNames.has(propName)) {
132
- toolNames.add(propName);
133
- toolOrder.push(propName); // Preserve order
132
+ // Try to resolve the module to find the actual function name
133
+ const resolvedName = resolvePropertyAccess(element, sourceFile, program);
134
+ const finalName = resolvedName || propName;
135
+ if (!toolNames.has(finalName)) {
136
+ toolNames.add(finalName);
137
+ toolOrder.push(finalName); // Preserve order
134
138
  }
135
139
  }
136
140
  } else if (ts.isElementAccessExpression(element)) {
@@ -139,9 +143,12 @@ function extractToolNamesFromExpression(
139
143
  if (ts.isStringLiteral(indexExpr) || ts.isNumericLiteral(indexExpr)) {
140
144
  const name = indexExpr.text;
141
145
  if (name && name !== 'undefined' && name !== 'null') {
142
- if (!toolNames.has(name)) {
143
- toolNames.add(name);
144
- toolOrder.push(name); // Preserve order
146
+ // Try to resolve the module
147
+ const resolvedName = resolveElementAccess(element, sourceFile, program);
148
+ const finalName = resolvedName || name;
149
+ if (!toolNames.has(finalName)) {
150
+ toolNames.add(finalName);
151
+ toolOrder.push(finalName); // Preserve order
145
152
  }
146
153
  }
147
154
  } else {
@@ -176,12 +183,15 @@ function extractToolNamesFromExpression(
176
183
  return;
177
184
  }
178
185
 
179
- // Property access: wrappedTools.getRAGInfo
186
+ // Property access: wrappedTools.getRAGInfo or tools.getLocation
180
187
  if (ts.isPropertyAccessExpression(node)) {
181
188
  const propName = node.name.text;
182
- if (!toolNames.has(propName)) {
183
- toolNames.add(propName);
184
- toolOrder.push(propName);
189
+ // Try to resolve the module to find the actual function name
190
+ const resolvedName = resolvePropertyAccess(node, sourceFile, program);
191
+ const finalName = resolvedName || propName;
192
+ if (!toolNames.has(finalName)) {
193
+ toolNames.add(finalName);
194
+ toolOrder.push(finalName);
185
195
  }
186
196
  return;
187
197
  }
@@ -198,6 +208,15 @@ function extractToolNamesFromExpression(
198
208
  }
199
209
  }
200
210
  }
211
+ // Also handle other function calls that might return arrays
212
+ // For example: someFunction() that returns an array of tools
213
+ if (node.arguments.length === 0) {
214
+ // Check if this call might be a variable reference
215
+ const varExpr = variableMap.get(callExpr.getText(sourceFile));
216
+ if (varExpr) {
217
+ extractFromExpr(varExpr);
218
+ }
219
+ }
201
220
  return;
202
221
  }
203
222
 
@@ -212,6 +231,57 @@ function extractToolNamesFromExpression(
212
231
  return { names: toolNames, order: toolOrder };
213
232
  }
214
233
 
234
+ /**
235
+ * Resolve property access like tools.getLocation to find the actual function name
236
+ * Returns the resolved name if found, or null if couldn't resolve
237
+ */
238
+ function resolvePropertyAccess(
239
+ expr: ts.PropertyAccessExpression,
240
+ sourceFile: ts.SourceFile,
241
+ program?: ts.Program
242
+ ): string | null {
243
+ if (!program) return null;
244
+
245
+ const checker = program.getTypeChecker();
246
+ const symbol = checker.getSymbolAtLocation(expr);
247
+
248
+ if (symbol) {
249
+ // Get the name of the property (e.g., "getLocation")
250
+ return symbol.getName();
251
+ }
252
+
253
+ // Fallback: try to resolve the object (e.g., "tools")
254
+ const objectExpr = expr.expression;
255
+ if (ts.isIdentifier(objectExpr)) {
256
+ const objectName = objectExpr.text;
257
+ // Check if this is an imported module (e.g., import * as tools from "./tools")
258
+ // We'll handle this in the import resolution
259
+ return null;
260
+ }
261
+
262
+ return null;
263
+ }
264
+
265
+ /**
266
+ * Resolve element access like tools['getLocation'] to find the actual function name
267
+ */
268
+ function resolveElementAccess(
269
+ expr: ts.ElementAccessExpression,
270
+ sourceFile: ts.SourceFile,
271
+ program?: ts.Program
272
+ ): string | null {
273
+ if (!program) return null;
274
+
275
+ const checker = program.getTypeChecker();
276
+ const symbol = checker.getSymbolAtLocation(expr);
277
+
278
+ if (symbol) {
279
+ return symbol.getName();
280
+ }
281
+
282
+ return null;
283
+ }
284
+
215
285
  /**
216
286
  * Build a map of variable declarations in the file
217
287
  * Handles: const x = [...], const x = useMemo(...), etc.
@@ -313,7 +383,7 @@ function extractToolNamesFromFile(
313
383
  if (attr.initializer && ts.isJsxExpression(attr.initializer)) {
314
384
  const expr = attr.initializer.expression;
315
385
  if (expr) {
316
- const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap);
386
+ const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap, program);
317
387
  extracted.names.forEach(name => toolNames.add(name));
318
388
  }
319
389
  }
@@ -331,7 +401,7 @@ function extractToolNamesFromFile(
331
401
  if (attr.initializer && ts.isJsxExpression(attr.initializer)) {
332
402
  const expr = attr.initializer.expression;
333
403
  if (expr) {
334
- const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap);
404
+ const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap, program);
335
405
  allToolOrder.push(...extracted.order);
336
406
  }
337
407
  }
@@ -365,7 +435,8 @@ function extractToolNamesFromFile(
365
435
  const extracted = extractToolNamesFromExpression(
366
436
  prop.initializer,
367
437
  sourceFile,
368
- variableMap
438
+ variableMap,
439
+ program
369
440
  );
370
441
  extracted.names.forEach(name => toolNames.add(name));
371
442
  }
@@ -387,7 +458,8 @@ function extractToolNamesFromFile(
387
458
  const extracted = extractToolNamesFromExpression(
388
459
  prop.initializer,
389
460
  sourceFile,
390
- variableMap
461
+ variableMap,
462
+ program
391
463
  );
392
464
  allToolOrder.push(...extracted.order);
393
465
  }
@@ -464,18 +536,28 @@ function findFunctionDefinition(
464
536
  }
465
537
 
466
538
  // If not found, check imports
467
- const imports: { name: string; from: string }[] = [];
539
+ const imports: { name: string; from: string; isNamespace?: boolean }[] = [];
468
540
 
469
541
  function visitForImports(node: ts.Node) {
470
542
  if (ts.isImportDeclaration(node)) {
471
543
  const importClause = node.importClause;
544
+ const modulePath = (node.moduleSpecifier as ts.StringLiteral).text;
545
+
472
546
  if (importClause) {
473
547
  const namedBindings = importClause.namedBindings;
474
- if (namedBindings && ts.isNamedImports(namedBindings)) {
548
+
549
+ // Handle namespace imports: import * as tools from "./tools"
550
+ if (namedBindings && ts.isNamespaceImport(namedBindings)) {
551
+ const namespaceName = namedBindings.name.getText(sourceFile);
552
+ // Check if functionName matches the namespace (e.g., "tools" in tools.getLocation)
553
+ // We'll handle property access separately
554
+ imports.push({ name: namespaceName, from: modulePath, isNamespace: true });
555
+ }
556
+ // Handle named imports: import { getLocation } from "./tools"
557
+ else if (namedBindings && ts.isNamedImports(namedBindings)) {
475
558
  for (const element of namedBindings.elements) {
476
559
  const importedName = element.name.getText(sourceFile);
477
560
  if (importedName === functionName) {
478
- const modulePath = (node.moduleSpecifier as ts.StringLiteral).text;
479
561
  imports.push({ name: importedName, from: modulePath });
480
562
  }
481
563
  }
@@ -493,9 +575,19 @@ function findFunctionDefinition(
493
575
  if (resolvedPath) {
494
576
  const importedSourceFile = program.getSourceFile(resolvedPath);
495
577
  if (importedSourceFile) {
496
- const result = findFunctionDefinition(functionName, importedSourceFile, program);
497
- if (result) {
498
- return result;
578
+ // For namespace imports, search for the function name in the imported module
579
+ if (imp.isNamespace) {
580
+ // The functionName should be found directly in the imported module
581
+ const result = findFunctionDefinition(functionName, importedSourceFile, program);
582
+ if (result) {
583
+ return result;
584
+ }
585
+ } else {
586
+ // For named imports, the name matches
587
+ const result = findFunctionDefinition(functionName, importedSourceFile, program);
588
+ if (result) {
589
+ return result;
590
+ }
499
591
  }
500
592
  }
501
593
  }
@@ -1,125 +1,125 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Manual update command for @arcteninc/core
4
- * Usage: arcten update
5
- *
6
- * This allows users to explicitly update their package.json
7
- */
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
- const { execSync } = require('child_process');
12
- const { findPackageJson } = require('./postinstall-check-version.cjs');
13
-
14
- function findPackageJsonLocal(startPath = process.cwd()) {
15
- let currentPath = startPath;
16
-
17
- while (currentPath !== path.dirname(currentPath)) {
18
- if (currentPath.includes('node_modules')) {
19
- currentPath = path.dirname(currentPath);
20
- continue;
21
- }
22
-
23
- const packageJsonPath = path.join(currentPath, 'package.json');
24
- if (fs.existsSync(packageJsonPath)) {
25
- try {
26
- const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
27
- if (pkg.name === '@arcteninc/core') {
28
- currentPath = path.dirname(currentPath);
29
- continue;
30
- }
31
- } catch (e) {
32
- currentPath = path.dirname(currentPath);
33
- continue;
34
- }
35
-
36
- return packageJsonPath;
37
- }
38
- currentPath = path.dirname(currentPath);
39
- }
40
-
41
- return null;
42
- }
43
-
44
- function getLatestVersion() {
45
- try {
46
- const output = execSync('npm view @arcteninc/core version', { encoding: 'utf-8', stdio: 'pipe' });
47
- return output.trim();
48
- } catch (error) {
49
- console.error('āŒ Could not check latest version:', error.message);
50
- return null;
51
- }
52
- }
53
-
54
- function updateVersion(packageJsonPath, packageJson, latestVersion) {
55
- let updated = false;
56
-
57
- if (packageJson.dependencies && packageJson.dependencies['@arcteninc/core']) {
58
- packageJson.dependencies['@arcteninc/core'] = `^${latestVersion}`;
59
- updated = true;
60
- }
61
- if (packageJson.devDependencies && packageJson.devDependencies['@arcteninc/core']) {
62
- packageJson.devDependencies['@arcteninc/core'] = `^${latestVersion}`;
63
- updated = true;
64
- }
65
-
66
- if (updated) {
67
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
68
- console.log(`āœ… Updated to \x1b[32m^${latestVersion}\x1b[0m in package.json\n`);
69
- return true;
70
- }
71
-
72
- return false;
73
- }
74
-
75
- function main() {
76
- const packageJsonPath = findPackageJson();
77
- if (!packageJsonPath) {
78
- console.error('āŒ Could not find package.json');
79
- process.exit(1);
80
- }
81
-
82
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
83
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
84
- const currentVersion = deps['@arcteninc/core'];
85
-
86
- if (!currentVersion) {
87
- console.error('āŒ @arcteninc/core not found in dependencies');
88
- process.exit(1);
89
- }
90
-
91
- const latestVersion = getLatestVersion();
92
- if (!latestVersion) {
93
- process.exit(1);
94
- }
95
-
96
- const currentVersionMatch = currentVersion.match(/(\d+\.\d+\.\d+)/);
97
- if (!currentVersionMatch) {
98
- console.error('āŒ Invalid version format:', currentVersion);
99
- process.exit(1);
100
- }
101
-
102
- const current = currentVersionMatch[1];
103
-
104
- if (current === latestVersion) {
105
- console.log(`\nāœ… Already on latest version: \x1b[32m${latestVersion}\x1b[0m\n`);
106
- return;
107
- }
108
-
109
- console.log(`\nšŸ“¦ Updating @arcteninc/core\n`);
110
- console.log(` Current: \x1b[33m${current}\x1b[0m`);
111
- console.log(` Latest: \x1b[32m${latestVersion}\x1b[0m\n`);
112
-
113
- if (updateVersion(packageJsonPath, packageJson, latestVersion)) {
114
- console.log(`šŸ’” Next steps:`);
115
- console.log(` 1. Review the changes in package.json`);
116
- console.log(` 2. Run \x1b[36mnpm install\x1b[0m to install the update\n`);
117
- }
118
- }
119
-
120
- if (require.main === module) {
121
- main();
122
- }
123
-
124
- module.exports = { main };
125
-
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Manual update command for @arcteninc/core
4
+ * Usage: arcten update
5
+ *
6
+ * This allows users to explicitly update their package.json
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { execSync } = require('child_process');
12
+ const { findPackageJson } = require('./postinstall-check-version.cjs');
13
+
14
+ function findPackageJsonLocal(startPath = process.cwd()) {
15
+ let currentPath = startPath;
16
+
17
+ while (currentPath !== path.dirname(currentPath)) {
18
+ if (currentPath.includes('node_modules')) {
19
+ currentPath = path.dirname(currentPath);
20
+ continue;
21
+ }
22
+
23
+ const packageJsonPath = path.join(currentPath, 'package.json');
24
+ if (fs.existsSync(packageJsonPath)) {
25
+ try {
26
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
27
+ if (pkg.name === '@arcteninc/core') {
28
+ currentPath = path.dirname(currentPath);
29
+ continue;
30
+ }
31
+ } catch (e) {
32
+ currentPath = path.dirname(currentPath);
33
+ continue;
34
+ }
35
+
36
+ return packageJsonPath;
37
+ }
38
+ currentPath = path.dirname(currentPath);
39
+ }
40
+
41
+ return null;
42
+ }
43
+
44
+ function getLatestVersion() {
45
+ try {
46
+ const output = execSync('npm view @arcteninc/core version', { encoding: 'utf-8', stdio: 'pipe' });
47
+ return output.trim();
48
+ } catch (error) {
49
+ console.error('āŒ Could not check latest version:', error.message);
50
+ return null;
51
+ }
52
+ }
53
+
54
+ function updateVersion(packageJsonPath, packageJson, latestVersion) {
55
+ let updated = false;
56
+
57
+ if (packageJson.dependencies && packageJson.dependencies['@arcteninc/core']) {
58
+ packageJson.dependencies['@arcteninc/core'] = `^${latestVersion}`;
59
+ updated = true;
60
+ }
61
+ if (packageJson.devDependencies && packageJson.devDependencies['@arcteninc/core']) {
62
+ packageJson.devDependencies['@arcteninc/core'] = `^${latestVersion}`;
63
+ updated = true;
64
+ }
65
+
66
+ if (updated) {
67
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
68
+ console.log(`āœ… Updated to \x1b[32m^${latestVersion}\x1b[0m in package.json\n`);
69
+ return true;
70
+ }
71
+
72
+ return false;
73
+ }
74
+
75
+ function main() {
76
+ const packageJsonPath = findPackageJson();
77
+ if (!packageJsonPath) {
78
+ console.error('āŒ Could not find package.json');
79
+ process.exit(1);
80
+ }
81
+
82
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
83
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
84
+ const currentVersion = deps['@arcteninc/core'];
85
+
86
+ if (!currentVersion) {
87
+ console.error('āŒ @arcteninc/core not found in dependencies');
88
+ process.exit(1);
89
+ }
90
+
91
+ const latestVersion = getLatestVersion();
92
+ if (!latestVersion) {
93
+ process.exit(1);
94
+ }
95
+
96
+ const currentVersionMatch = currentVersion.match(/(\d+\.\d+\.\d+)/);
97
+ if (!currentVersionMatch) {
98
+ console.error('āŒ Invalid version format:', currentVersion);
99
+ process.exit(1);
100
+ }
101
+
102
+ const current = currentVersionMatch[1];
103
+
104
+ if (current === latestVersion) {
105
+ console.log(`\nāœ… Already on latest version: \x1b[32m${latestVersion}\x1b[0m\n`);
106
+ return;
107
+ }
108
+
109
+ console.log(`\nšŸ“¦ Updating @arcteninc/core\n`);
110
+ console.log(` Current: \x1b[33m${current}\x1b[0m`);
111
+ console.log(` Latest: \x1b[32m${latestVersion}\x1b[0m\n`);
112
+
113
+ if (updateVersion(packageJsonPath, packageJson, latestVersion)) {
114
+ console.log(`šŸ’” Next steps:`);
115
+ console.log(` 1. Review the changes in package.json`);
116
+ console.log(` 2. Run \x1b[36mnpm install\x1b[0m to install the update\n`);
117
+ }
118
+ }
119
+
120
+ if (require.main === module) {
121
+ main();
122
+ }
123
+
124
+ module.exports = { main };
125
+