@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 +1 -1
- package/scripts/arcten-cli.cjs +132 -132
- package/scripts/cli-extract-types-auto.ts +153 -37
- package/scripts/update-core.cjs +125 -125
package/package.json
CHANGED
package/scripts/arcten-cli.cjs
CHANGED
|
@@ -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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
497
|
-
if (
|
|
498
|
-
|
|
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
|
}
|
package/scripts/update-core.cjs
CHANGED
|
@@ -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
|
+
|