@arcteninc/core 0.0.61 → 0.0.63

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.63",
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
@@ -101,6 +102,12 @@ function extractToolNamesFromExpression(
101
102
  function extractFromExpr(node: ts.Node): void {
102
103
  if (visited.has(node)) return;
103
104
  visited.add(node);
105
+
106
+ // Handle type assertions: (expr as any)
107
+ if (ts.isAsExpression(node)) {
108
+ extractFromExpr(node.expression);
109
+ return;
110
+ }
104
111
 
105
112
  // Direct array literal: [tool1, tool2]
106
113
  if (ts.isArrayLiteralExpression(node)) {
@@ -128,9 +135,15 @@ function extractToolNamesFromExpression(
128
135
  // Property access: tools.getOrders -> extract "getOrders"
129
136
  const propName = element.name.text;
130
137
  if (propName) {
131
- if (!toolNames.has(propName)) {
132
- toolNames.add(propName);
133
- toolOrder.push(propName); // Preserve order
138
+ // Try to resolve the module to find the actual function name
139
+ const resolvedName = resolvePropertyAccess(element, sourceFile, program);
140
+ const finalName = resolvedName || propName;
141
+ // Only add if it's a valid identifier name
142
+ if (finalName && finalName !== 'undefined' && finalName !== 'null' && finalName !== 'any') {
143
+ if (!toolNames.has(finalName)) {
144
+ toolNames.add(finalName);
145
+ toolOrder.push(finalName); // Preserve order
146
+ }
134
147
  }
135
148
  }
136
149
  } else if (ts.isElementAccessExpression(element)) {
@@ -139,9 +152,12 @@ function extractToolNamesFromExpression(
139
152
  if (ts.isStringLiteral(indexExpr) || ts.isNumericLiteral(indexExpr)) {
140
153
  const name = indexExpr.text;
141
154
  if (name && name !== 'undefined' && name !== 'null') {
142
- if (!toolNames.has(name)) {
143
- toolNames.add(name);
144
- toolOrder.push(name); // Preserve order
155
+ // Try to resolve the module
156
+ const resolvedName = resolveElementAccess(element, sourceFile, program);
157
+ const finalName = resolvedName || name;
158
+ if (!toolNames.has(finalName)) {
159
+ toolNames.add(finalName);
160
+ toolOrder.push(finalName); // Preserve order
145
161
  }
146
162
  }
147
163
  } else {
@@ -176,12 +192,18 @@ function extractToolNamesFromExpression(
176
192
  return;
177
193
  }
178
194
 
179
- // Property access: wrappedTools.getRAGInfo
195
+ // Property access: wrappedTools.getRAGInfo or tools.getLocation
180
196
  if (ts.isPropertyAccessExpression(node)) {
181
197
  const propName = node.name.text;
182
- if (!toolNames.has(propName)) {
183
- toolNames.add(propName);
184
- toolOrder.push(propName);
198
+ // Try to resolve the module to find the actual function name
199
+ const resolvedName = resolvePropertyAccess(node, sourceFile, program);
200
+ const finalName = resolvedName || propName;
201
+ // Only add if it's a valid identifier name (not empty, not a keyword)
202
+ if (finalName && finalName !== 'undefined' && finalName !== 'null' && finalName !== 'any') {
203
+ if (!toolNames.has(finalName)) {
204
+ toolNames.add(finalName);
205
+ toolOrder.push(finalName);
206
+ }
185
207
  }
186
208
  return;
187
209
  }
@@ -198,6 +220,15 @@ function extractToolNamesFromExpression(
198
220
  }
199
221
  }
200
222
  }
223
+ // Also handle other function calls that might return arrays
224
+ // For example: someFunction() that returns an array of tools
225
+ if (node.arguments.length === 0) {
226
+ // Check if this call might be a variable reference
227
+ const varExpr = variableMap.get(callExpr.getText(sourceFile));
228
+ if (varExpr) {
229
+ extractFromExpr(varExpr);
230
+ }
231
+ }
201
232
  return;
202
233
  }
203
234
 
@@ -212,6 +243,57 @@ function extractToolNamesFromExpression(
212
243
  return { names: toolNames, order: toolOrder };
213
244
  }
214
245
 
246
+ /**
247
+ * Resolve property access like tools.getLocation to find the actual function name
248
+ * Returns the resolved name if found, or null if couldn't resolve
249
+ */
250
+ function resolvePropertyAccess(
251
+ expr: ts.PropertyAccessExpression,
252
+ sourceFile: ts.SourceFile,
253
+ program?: ts.Program
254
+ ): string | null {
255
+ if (!program) return null;
256
+
257
+ const checker = program.getTypeChecker();
258
+ const symbol = checker.getSymbolAtLocation(expr);
259
+
260
+ if (symbol) {
261
+ // Get the name of the property (e.g., "getLocation")
262
+ return symbol.getName();
263
+ }
264
+
265
+ // Fallback: try to resolve the object (e.g., "tools")
266
+ const objectExpr = expr.expression;
267
+ if (ts.isIdentifier(objectExpr)) {
268
+ const objectName = objectExpr.text;
269
+ // Check if this is an imported module (e.g., import * as tools from "./tools")
270
+ // We'll handle this in the import resolution
271
+ return null;
272
+ }
273
+
274
+ return null;
275
+ }
276
+
277
+ /**
278
+ * Resolve element access like tools['getLocation'] to find the actual function name
279
+ */
280
+ function resolveElementAccess(
281
+ expr: ts.ElementAccessExpression,
282
+ sourceFile: ts.SourceFile,
283
+ program?: ts.Program
284
+ ): string | null {
285
+ if (!program) return null;
286
+
287
+ const checker = program.getTypeChecker();
288
+ const symbol = checker.getSymbolAtLocation(expr);
289
+
290
+ if (symbol) {
291
+ return symbol.getName();
292
+ }
293
+
294
+ return null;
295
+ }
296
+
215
297
  /**
216
298
  * Build a map of variable declarations in the file
217
299
  * Handles: const x = [...], const x = useMemo(...), etc.
@@ -245,6 +327,7 @@ function buildVariableMap(sourceFile: ts.SourceFile): Map<string, ts.Expression>
245
327
 
246
328
  /**
247
329
  * Extract tools from useMemo callback, handling both arrow functions and regular functions
330
+ * Also handles type assertions like `as any`
248
331
  */
249
332
  function extractToolsFromUseMemo(
250
333
  useMemoCall: ts.CallExpression,
@@ -255,34 +338,45 @@ function extractToolsFromUseMemo(
255
338
 
256
339
  const firstArg = useMemoCall.arguments[0];
257
340
 
341
+ function extractFromBody(body: ts.Expression | ts.Block): ts.Expression | null {
342
+ if (ts.isBlock(body)) {
343
+ // Block body: () => { return [...] }
344
+ for (const stmt of body.statements) {
345
+ if (ts.isReturnStatement(stmt) && stmt.expression) {
346
+ return unwrapTypeAssertion(stmt.expression);
347
+ }
348
+ }
349
+ } else {
350
+ // Expression body: () => [...]
351
+ return unwrapTypeAssertion(body);
352
+ }
353
+ return null;
354
+ }
355
+
258
356
  // Arrow function: () => [...]
259
357
  if (ts.isArrowFunction(firstArg)) {
260
358
  if (firstArg.body) {
261
- if (ts.isBlock(firstArg.body)) {
262
- // Block body: () => { return [...] }
263
- for (const stmt of firstArg.body.statements) {
264
- if (ts.isReturnStatement(stmt) && stmt.expression) {
265
- return stmt.expression;
266
- }
267
- }
268
- } else {
269
- // Expression body: () => [...]
270
- return firstArg.body;
271
- }
359
+ return extractFromBody(firstArg.body);
272
360
  }
273
361
  }
274
362
  // Regular function: function() { return [...] }
275
363
  else if (ts.isFunctionExpression(firstArg) && firstArg.body) {
276
- for (const stmt of firstArg.body.statements) {
277
- if (ts.isReturnStatement(stmt) && stmt.expression) {
278
- return stmt.expression;
279
- }
280
- }
364
+ return extractFromBody(firstArg.body);
281
365
  }
282
366
 
283
367
  return null;
284
368
  }
285
369
 
370
+ /**
371
+ * Unwrap type assertions like `as any`, `as ToolFunction[]`, etc.
372
+ */
373
+ function unwrapTypeAssertion(expr: ts.Expression): ts.Expression {
374
+ if (ts.isAsExpression(expr)) {
375
+ return expr.expression;
376
+ }
377
+ return expr;
378
+ }
379
+
286
380
  /**
287
381
  * Extract tool names from ArctenAgent or useAgent usage
288
382
  */
@@ -313,7 +407,7 @@ function extractToolNamesFromFile(
313
407
  if (attr.initializer && ts.isJsxExpression(attr.initializer)) {
314
408
  const expr = attr.initializer.expression;
315
409
  if (expr) {
316
- const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap);
410
+ const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap, program);
317
411
  extracted.names.forEach(name => toolNames.add(name));
318
412
  }
319
413
  }
@@ -331,7 +425,7 @@ function extractToolNamesFromFile(
331
425
  if (attr.initializer && ts.isJsxExpression(attr.initializer)) {
332
426
  const expr = attr.initializer.expression;
333
427
  if (expr) {
334
- const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap);
428
+ const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap, program);
335
429
  allToolOrder.push(...extracted.order);
336
430
  }
337
431
  }
@@ -365,7 +459,8 @@ function extractToolNamesFromFile(
365
459
  const extracted = extractToolNamesFromExpression(
366
460
  prop.initializer,
367
461
  sourceFile,
368
- variableMap
462
+ variableMap,
463
+ program
369
464
  );
370
465
  extracted.names.forEach(name => toolNames.add(name));
371
466
  }
@@ -387,7 +482,8 @@ function extractToolNamesFromFile(
387
482
  const extracted = extractToolNamesFromExpression(
388
483
  prop.initializer,
389
484
  sourceFile,
390
- variableMap
485
+ variableMap,
486
+ program
391
487
  );
392
488
  allToolOrder.push(...extracted.order);
393
489
  }
@@ -464,18 +560,28 @@ function findFunctionDefinition(
464
560
  }
465
561
 
466
562
  // If not found, check imports
467
- const imports: { name: string; from: string }[] = [];
563
+ const imports: { name: string; from: string; isNamespace?: boolean }[] = [];
468
564
 
469
565
  function visitForImports(node: ts.Node) {
470
566
  if (ts.isImportDeclaration(node)) {
471
567
  const importClause = node.importClause;
568
+ const modulePath = (node.moduleSpecifier as ts.StringLiteral).text;
569
+
472
570
  if (importClause) {
473
571
  const namedBindings = importClause.namedBindings;
474
- if (namedBindings && ts.isNamedImports(namedBindings)) {
572
+
573
+ // Handle namespace imports: import * as tools from "./tools"
574
+ if (namedBindings && ts.isNamespaceImport(namedBindings)) {
575
+ const namespaceName = namedBindings.name.getText(sourceFile);
576
+ // Check if functionName matches the namespace (e.g., "tools" in tools.getLocation)
577
+ // We'll handle property access separately
578
+ imports.push({ name: namespaceName, from: modulePath, isNamespace: true });
579
+ }
580
+ // Handle named imports: import { getLocation } from "./tools"
581
+ else if (namedBindings && ts.isNamedImports(namedBindings)) {
475
582
  for (const element of namedBindings.elements) {
476
583
  const importedName = element.name.getText(sourceFile);
477
584
  if (importedName === functionName) {
478
- const modulePath = (node.moduleSpecifier as ts.StringLiteral).text;
479
585
  imports.push({ name: importedName, from: modulePath });
480
586
  }
481
587
  }
@@ -493,9 +599,19 @@ function findFunctionDefinition(
493
599
  if (resolvedPath) {
494
600
  const importedSourceFile = program.getSourceFile(resolvedPath);
495
601
  if (importedSourceFile) {
496
- const result = findFunctionDefinition(functionName, importedSourceFile, program);
497
- if (result) {
498
- return result;
602
+ // For namespace imports, search for the function name in the imported module
603
+ if (imp.isNamespace) {
604
+ // The functionName should be found directly in the imported module
605
+ const result = findFunctionDefinition(functionName, importedSourceFile, program);
606
+ if (result) {
607
+ return result;
608
+ }
609
+ } else {
610
+ // For named imports, the name matches
611
+ const result = findFunctionDefinition(functionName, importedSourceFile, program);
612
+ if (result) {
613
+ return result;
614
+ }
499
615
  }
500
616
  }
501
617
  }
@@ -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
+