lua-cli 2.2.8-alpha.2 → 2.3.0-alpha.2

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.
Files changed (195) hide show
  1. package/API_REFERENCE.md +1408 -0
  2. package/CLI_REFERENCE.md +818 -0
  3. package/GETTING_STARTED.md +1040 -0
  4. package/README.md +738 -424
  5. package/TEMPLATE_GUIDE.md +1398 -0
  6. package/dist/api/agent.api.service.d.ts +33 -6
  7. package/dist/api/agent.api.service.js +27 -0
  8. package/dist/api/auth.api.service.d.ts +31 -2
  9. package/dist/api/auth.api.service.js +29 -0
  10. package/dist/api/basket.api.service.d.ts +53 -11
  11. package/dist/api/basket.api.service.js +63 -14
  12. package/dist/api/chat.api.service.d.ts +15 -3
  13. package/dist/api/chat.api.service.js +12 -0
  14. package/dist/api/credentials.d.ts +24 -0
  15. package/dist/api/credentials.js +46 -0
  16. package/dist/api/custom.data.api.service.d.ts +45 -9
  17. package/dist/api/custom.data.api.service.js +43 -9
  18. package/dist/api/lazy-instances.d.ts +49 -0
  19. package/dist/api/lazy-instances.js +95 -0
  20. package/dist/api/order.api.service.d.ts +34 -4
  21. package/dist/api/order.api.service.js +41 -3
  22. package/dist/api/products.api.service.d.ts +39 -9
  23. package/dist/api/products.api.service.js +43 -5
  24. package/dist/api/skills.api.service.d.ts +49 -2
  25. package/dist/api/skills.api.service.js +47 -1
  26. package/dist/api/tool.api.service.d.ts +39 -1
  27. package/dist/api/tool.api.service.js +38 -0
  28. package/dist/api/user.data.api.service.d.ts +23 -1
  29. package/dist/api/user.data.api.service.js +22 -0
  30. package/dist/api-exports.d.ts +236 -5
  31. package/dist/api-exports.js +264 -81
  32. package/dist/cli/command-definitions.d.ts +30 -0
  33. package/dist/cli/command-definitions.js +71 -0
  34. package/dist/commands/agents.d.ts +20 -0
  35. package/dist/commands/agents.js +24 -2
  36. package/dist/commands/apiKey.d.ts +23 -0
  37. package/dist/commands/apiKey.js +23 -0
  38. package/dist/commands/compile.d.ts +24 -0
  39. package/dist/commands/compile.js +67 -759
  40. package/dist/commands/configure.d.ts +24 -0
  41. package/dist/commands/configure.js +31 -96
  42. package/dist/commands/deploy.d.ts +31 -19
  43. package/dist/commands/deploy.js +45 -74
  44. package/dist/commands/destroy.d.ts +27 -0
  45. package/dist/commands/destroy.js +27 -1
  46. package/dist/commands/dev.d.ts +25 -62
  47. package/dist/commands/dev.js +58 -878
  48. package/dist/commands/init.d.ts +27 -0
  49. package/dist/commands/init.js +98 -260
  50. package/dist/commands/push.d.ts +24 -21
  51. package/dist/commands/push.js +39 -92
  52. package/dist/commands/test.d.ts +26 -0
  53. package/dist/commands/test.js +41 -188
  54. package/dist/common/basket.instance.d.ts +54 -3
  55. package/dist/common/basket.instance.js +56 -3
  56. package/dist/common/data.entry.instance.d.ts +25 -2
  57. package/dist/common/data.entry.instance.js +24 -0
  58. package/dist/common/http.client.d.ts +51 -1
  59. package/dist/common/http.client.js +50 -0
  60. package/dist/common/order.instance.d.ts +22 -0
  61. package/dist/common/order.instance.js +31 -4
  62. package/dist/common/product.instance.d.ts +22 -1
  63. package/dist/common/product.instance.js +24 -6
  64. package/dist/common/product.pagination.instance.d.ts +22 -2
  65. package/dist/common/product.pagination.instance.js +22 -1
  66. package/dist/common/product.search.instance.d.ts +13 -3
  67. package/dist/common/product.search.instance.js +12 -1
  68. package/dist/common/user.instance.d.ts +27 -3
  69. package/dist/common/user.instance.js +28 -7
  70. package/dist/config/auth.constants.d.ts +11 -0
  71. package/dist/config/auth.constants.js +11 -0
  72. package/dist/config/compile.constants.d.ts +67 -0
  73. package/dist/config/compile.constants.js +99 -0
  74. package/dist/config/constants.d.ts +5 -0
  75. package/dist/config/constants.js +5 -0
  76. package/dist/config/dev.constants.d.ts +65 -0
  77. package/dist/config/dev.constants.js +79 -0
  78. package/dist/config/init.constants.d.ts +23 -0
  79. package/dist/config/init.constants.js +41 -0
  80. package/dist/index.d.ts +19 -3
  81. package/dist/index.js +28 -44
  82. package/dist/interfaces/admin.d.ts +56 -50
  83. package/dist/interfaces/admin.js +4 -0
  84. package/dist/interfaces/agent.d.ts +21 -0
  85. package/dist/interfaces/agent.js +4 -0
  86. package/dist/interfaces/baskets.d.ts +60 -0
  87. package/dist/interfaces/baskets.js +12 -0
  88. package/dist/interfaces/chat.d.ts +48 -4
  89. package/dist/interfaces/chat.js +4 -0
  90. package/dist/interfaces/common.d.ts +62 -0
  91. package/dist/interfaces/common.js +8 -0
  92. package/dist/interfaces/compile.d.ts +11 -0
  93. package/dist/interfaces/compile.js +4 -0
  94. package/dist/interfaces/custom.data.d.ts +49 -19
  95. package/dist/interfaces/custom.data.js +4 -0
  96. package/dist/interfaces/deploy.d.ts +29 -0
  97. package/dist/interfaces/deploy.js +4 -0
  98. package/dist/interfaces/dev.d.ts +53 -0
  99. package/dist/interfaces/dev.js +5 -0
  100. package/dist/interfaces/init.d.ts +60 -0
  101. package/dist/interfaces/init.js +4 -0
  102. package/dist/interfaces/orders.d.ts +37 -0
  103. package/dist/interfaces/orders.js +12 -0
  104. package/dist/interfaces/product.d.ts +38 -10
  105. package/dist/interfaces/product.js +4 -0
  106. package/dist/interfaces/push.d.ts +26 -0
  107. package/dist/interfaces/push.js +4 -0
  108. package/dist/interfaces/test.d.ts +36 -0
  109. package/dist/interfaces/test.js +4 -0
  110. package/dist/services/auth.d.ts +54 -99
  111. package/dist/services/auth.js +76 -12
  112. package/dist/types/api-contracts.d.ts +211 -0
  113. package/dist/types/api-contracts.js +8 -0
  114. package/dist/types/compile.types.d.ts +76 -0
  115. package/dist/types/compile.types.js +4 -0
  116. package/dist/types/index.d.ts +23 -121
  117. package/dist/types/index.js +25 -14
  118. package/dist/types/skill.d.ts +142 -0
  119. package/dist/{skill.js → types/skill.js} +66 -17
  120. package/dist/types/tool-validation.d.ts +34 -0
  121. package/dist/types/tool-validation.js +42 -0
  122. package/dist/utils/auth-flows.d.ts +26 -0
  123. package/dist/utils/auth-flows.js +141 -0
  124. package/dist/utils/bundling.d.ts +36 -0
  125. package/dist/utils/bundling.js +137 -0
  126. package/dist/utils/compile.d.ts +37 -0
  127. package/dist/utils/compile.js +242 -0
  128. package/dist/utils/deploy-api.d.ts +26 -0
  129. package/dist/utils/deploy-api.js +53 -0
  130. package/dist/utils/deploy-helpers.d.ts +46 -0
  131. package/dist/utils/deploy-helpers.js +86 -0
  132. package/dist/utils/deployment.d.ts +25 -0
  133. package/dist/utils/deployment.js +161 -0
  134. package/dist/utils/dev-api.d.ts +61 -0
  135. package/dist/utils/dev-api.js +262 -0
  136. package/dist/utils/dev-helpers.d.ts +46 -0
  137. package/dist/utils/dev-helpers.js +83 -0
  138. package/dist/utils/dev-server.d.ts +24 -0
  139. package/dist/utils/dev-server.js +555 -0
  140. package/dist/utils/dev-watcher.d.ts +31 -0
  141. package/dist/utils/dev-watcher.js +110 -0
  142. package/dist/utils/files.js +0 -5
  143. package/dist/utils/init-agent.d.ts +34 -0
  144. package/dist/utils/init-agent.js +129 -0
  145. package/dist/utils/init-helpers.d.ts +41 -0
  146. package/dist/utils/init-helpers.js +73 -0
  147. package/dist/utils/init-prompts.d.ts +47 -0
  148. package/dist/utils/init-prompts.js +168 -0
  149. package/dist/utils/push-api.d.ts +15 -0
  150. package/dist/utils/push-api.js +48 -0
  151. package/dist/utils/push-helpers.d.ts +38 -0
  152. package/dist/utils/push-helpers.js +84 -0
  153. package/dist/utils/sandbox-storage.d.ts +27 -0
  154. package/dist/utils/sandbox-storage.js +71 -0
  155. package/dist/utils/sandbox.js +78 -114
  156. package/dist/utils/skill-management.d.ts +14 -0
  157. package/dist/utils/skill-management.js +148 -0
  158. package/dist/utils/test-helpers.d.ts +40 -0
  159. package/dist/utils/test-helpers.js +92 -0
  160. package/dist/utils/test-prompts.d.ts +23 -0
  161. package/dist/utils/test-prompts.js +186 -0
  162. package/dist/utils/tool-detection.d.ts +18 -0
  163. package/dist/utils/tool-detection.js +110 -0
  164. package/dist/web/app.css +941 -17
  165. package/dist/web/app.js +174 -22
  166. package/dist/web/index.html +7 -1
  167. package/package.json +13 -4
  168. package/template/QUICKSTART.md +299 -144
  169. package/template/README.md +928 -349
  170. package/template/TOOL_EXAMPLES.md +655 -0
  171. package/template/package-lock.json +5 -5
  172. package/template/package.json +1 -1
  173. package/template/src/index.ts +147 -207
  174. package/template/src/tools/BasketTool.ts +128 -0
  175. package/template/src/tools/CustomDataTool.ts +7 -13
  176. package/template/src/tools/OrderTool.ts +54 -0
  177. package/template/src/tools/PaymentTool.ts +1 -1
  178. package/template/src/tools/ProductsTool.ts +56 -118
  179. package/template/src/tools/UserDataTool.ts +4 -26
  180. package/dist/common/config.d.ts +0 -5
  181. package/dist/common/config.js +0 -5
  182. package/dist/custom-data-api.d.ts +0 -72
  183. package/dist/custom-data-api.js +0 -174
  184. package/dist/product-api.d.ts +0 -189
  185. package/dist/product-api.js +0 -141
  186. package/dist/services/api.d.ts +0 -549
  187. package/dist/services/api.js +0 -596
  188. package/dist/skill.d.ts +0 -50
  189. package/dist/types.d.ts +0 -1
  190. package/dist/types.js +0 -2
  191. package/dist/user-data-api.d.ts +0 -39
  192. package/dist/user-data-api.js +0 -50
  193. package/template/API.md +0 -604
  194. package/template/DEVELOPER.md +0 -771
  195. package/template/lua.skill.yaml +0 -7
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Test Command Helper Utilities
3
+ * Handles tool extraction, decompression, and schema processing
4
+ */
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import { gunzipSync } from "zlib";
8
+ import { Buffer } from "buffer";
9
+ /**
10
+ * Decompresses gzip-compressed base64 encoded code.
11
+ *
12
+ * @param compressedCode - Base64 encoded compressed code
13
+ * @returns Decompressed code string
14
+ */
15
+ export function decompressCode(compressedCode) {
16
+ const buffer = Buffer.from(compressedCode, 'base64');
17
+ return gunzipSync(buffer).toString('utf8');
18
+ }
19
+ /**
20
+ * Reads and parses deploy.json file.
21
+ *
22
+ * @returns Parsed deploy data
23
+ * @throws Error if deploy.json is not found
24
+ */
25
+ export function readDeployJson() {
26
+ const luaDir = path.join(process.cwd(), ".lua");
27
+ if (!fs.existsSync(luaDir)) {
28
+ throw new Error(".lua directory not found. Run 'lua compile' first.");
29
+ }
30
+ const deployJsonPath = path.join(luaDir, "deploy.json");
31
+ if (!fs.existsSync(deployJsonPath)) {
32
+ throw new Error("deploy.json not found. Run 'lua compile' first.");
33
+ }
34
+ return JSON.parse(fs.readFileSync(deployJsonPath, "utf8"));
35
+ }
36
+ /**
37
+ * Extracts all tools from deploy.json (handles both new and legacy formats).
38
+ *
39
+ * @param deployData - Parsed deploy.json data
40
+ * @returns Array of tools with their metadata
41
+ * @throws Error if no tools are found
42
+ */
43
+ export function extractToolsFromDeployData(deployData) {
44
+ let allTools = [];
45
+ if (deployData.skills && Array.isArray(deployData.skills)) {
46
+ // New format: extract tools from skills array
47
+ deployData.skills.forEach((skill) => {
48
+ if (skill.tools && Array.isArray(skill.tools)) {
49
+ skill.tools.forEach((tool) => {
50
+ allTools.push({
51
+ ...tool,
52
+ skillName: skill.name // Add skill context
53
+ });
54
+ });
55
+ }
56
+ });
57
+ }
58
+ else if (deployData.tools) {
59
+ // Legacy format: tools as object or array
60
+ if (Array.isArray(deployData.tools)) {
61
+ allTools = deployData.tools;
62
+ }
63
+ else {
64
+ // Convert tools object to array
65
+ allTools = Object.entries(deployData.tools).map(([name, tool]) => ({
66
+ name,
67
+ ...tool
68
+ }));
69
+ }
70
+ }
71
+ if (allTools.length === 0) {
72
+ throw new Error("No tools found in deploy.json");
73
+ }
74
+ return allTools;
75
+ }
76
+ /**
77
+ * Checks if .env file exists.
78
+ *
79
+ * @returns True if .env file exists
80
+ */
81
+ export function hasEnvFile() {
82
+ return fs.existsSync(path.join(process.cwd(), '.env'));
83
+ }
84
+ /**
85
+ * Checks if config has environment variables defined.
86
+ *
87
+ * @param config - Skill configuration
88
+ * @returns True if config has environment variables
89
+ */
90
+ export function hasConfigEnvVars(config) {
91
+ return config?.skill?.env && Object.keys(config.skill.env).length > 0;
92
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Test Command Prompt Utilities
3
+ * Handles interactive prompts for tool selection and input collection
4
+ */
5
+ import { ToolData, InputSchema } from '../interfaces/test.js';
6
+ /**
7
+ * Prompts user to select a tool from the list.
8
+ *
9
+ * @param tools - Array of available tools
10
+ * @returns Selected tool data
11
+ */
12
+ export declare function promptToolSelection(tools: ToolData[]): Promise<ToolData>;
13
+ /**
14
+ * Recursively generates prompts for schema properties and collects input values.
15
+ * Handles nested objects and various property types.
16
+ *
17
+ * @param schema - Input schema to generate prompts from
18
+ * @param prefix - Prefix for nested property names
19
+ * @param required - Array of required property names
20
+ * @param rootSchema - Root schema for nested property lookups
21
+ * @returns Object containing collected input values
22
+ */
23
+ export declare function generatePromptsForObject(schema: InputSchema, prefix?: string, required?: string[], rootSchema?: InputSchema): Promise<any>;
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Test Command Prompt Utilities
3
+ * Handles interactive prompts for tool selection and input collection
4
+ */
5
+ import inquirer from "inquirer";
6
+ import { writeProgress } from './cli.js';
7
+ /**
8
+ * Prompts user to select a tool from the list.
9
+ *
10
+ * @param tools - Array of available tools
11
+ * @returns Selected tool data
12
+ */
13
+ export async function promptToolSelection(tools) {
14
+ const toolChoices = tools.map((tool) => ({
15
+ name: tool.skillName
16
+ ? `${tool.name} (${tool.skillName}) - ${tool.description}`
17
+ : `${tool.name} - ${tool.description}`,
18
+ value: tool
19
+ }));
20
+ const { selectedTool } = await inquirer.prompt([
21
+ {
22
+ type: 'list',
23
+ name: 'selectedTool',
24
+ message: '🔧 Select a tool to test:',
25
+ choices: toolChoices,
26
+ pageSize: 10
27
+ }
28
+ ]);
29
+ return selectedTool;
30
+ }
31
+ /**
32
+ * Recursively generates prompts for schema properties and collects input values.
33
+ * Handles nested objects and various property types.
34
+ *
35
+ * @param schema - Input schema to generate prompts from
36
+ * @param prefix - Prefix for nested property names
37
+ * @param required - Array of required property names
38
+ * @param rootSchema - Root schema for nested property lookups
39
+ * @returns Object containing collected input values
40
+ */
41
+ export async function generatePromptsForObject(schema, prefix = '', required = [], rootSchema) {
42
+ const prompts = [];
43
+ const result = {};
44
+ const inputSchema = rootSchema || schema;
45
+ for (const [key, value] of Object.entries(schema.properties || {})) {
46
+ const property = value;
47
+ const fullKey = prefix ? `${prefix}.${key}` : key;
48
+ const isRequired = required.includes(key);
49
+ if (property.type === "object" && property.properties) {
50
+ // Handle nested object
51
+ writeProgress(`\n📋 Entering values for ${key}:`);
52
+ const nestedResult = await generatePromptsForObject(property, fullKey, property.required || [], inputSchema);
53
+ result[key] = nestedResult[key] || nestedResult;
54
+ }
55
+ else {
56
+ // Handle primitive types
57
+ const prompt = createPromptForProperty(key, property, fullKey, isRequired);
58
+ prompts.push(prompt);
59
+ }
60
+ }
61
+ if (prompts.length > 0) {
62
+ const answers = await inquirer.prompt(prompts);
63
+ processAnswers(answers, result, inputSchema, schema, required);
64
+ }
65
+ return result;
66
+ }
67
+ /**
68
+ * Creates an inquirer prompt for a schema property.
69
+ *
70
+ * @param key - Property name
71
+ * @param property - Property schema
72
+ * @param fullKey - Full property key including nested path
73
+ * @param isRequired - Whether the property is required
74
+ * @returns Inquirer prompt configuration
75
+ */
76
+ function createPromptForProperty(key, property, fullKey, isRequired) {
77
+ let promptType = 'input';
78
+ let validate = undefined;
79
+ switch (property.type) {
80
+ case "string":
81
+ if (isRequired) {
82
+ validate = (input) => input.trim() !== "" || `${key} is required`;
83
+ }
84
+ break;
85
+ case "number":
86
+ promptType = 'number';
87
+ if (isRequired) {
88
+ validate = (input) => !isNaN(input) || `${key} must be a valid number`;
89
+ }
90
+ break;
91
+ case "boolean":
92
+ promptType = 'confirm';
93
+ break;
94
+ default:
95
+ if (isRequired) {
96
+ validate = (input) => input.trim() !== "" || `${key} is required`;
97
+ }
98
+ }
99
+ return {
100
+ type: promptType,
101
+ name: fullKey,
102
+ message: `${key}${isRequired ? " (required)" : " (optional)"}:`,
103
+ validate: validate,
104
+ };
105
+ }
106
+ /**
107
+ * Processes prompt answers and converts them to proper types.
108
+ * Handles nested structures and optional fields.
109
+ *
110
+ * @param answers - Raw answers from inquirer
111
+ * @param result - Result object to populate
112
+ * @param inputSchema - Root input schema
113
+ * @param schema - Current schema level
114
+ * @param required - Required property names at current level
115
+ */
116
+ function processAnswers(answers, result, inputSchema, schema, required) {
117
+ for (const [key, value] of Object.entries(answers)) {
118
+ const keyParts = key.split('.');
119
+ const propertyKey = keyParts[keyParts.length - 1];
120
+ // Navigate through nested schemas to find the property
121
+ let currentSchema = inputSchema;
122
+ let currentProperty = null;
123
+ for (let i = 0; i < keyParts.length; i++) {
124
+ const part = keyParts[i];
125
+ if (currentSchema.properties && currentSchema.properties[part]) {
126
+ currentProperty = currentSchema.properties[part];
127
+ if (i < keyParts.length - 1) {
128
+ currentSchema = currentProperty;
129
+ }
130
+ }
131
+ }
132
+ if (currentProperty) {
133
+ const convertedValue = convertValueByType(value, currentProperty);
134
+ // Check if field is optional and value is empty - skip if so
135
+ const parentSchema = keyParts.length > 1 ? currentSchema : schema;
136
+ const isOptional = !parentSchema.required || !parentSchema.required.includes(propertyKey);
137
+ const isEmpty = convertedValue === '' || convertedValue === null || convertedValue === undefined;
138
+ if (isOptional && isEmpty) {
139
+ continue; // Skip optional empty fields
140
+ }
141
+ // Build nested structure
142
+ if (keyParts.length === 1) {
143
+ result[propertyKey] = convertedValue;
144
+ }
145
+ else {
146
+ buildNestedStructure(result, keyParts, propertyKey, convertedValue);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ /**
152
+ * Converts a value to the appropriate type based on schema property.
153
+ *
154
+ * @param value - Raw value from prompt
155
+ * @param property - Schema property definition
156
+ * @returns Converted value
157
+ */
158
+ function convertValueByType(value, property) {
159
+ switch (property.type) {
160
+ case "number":
161
+ return parseFloat(value);
162
+ case "boolean":
163
+ return value;
164
+ default:
165
+ return value;
166
+ }
167
+ }
168
+ /**
169
+ * Builds nested object structure from key parts and value.
170
+ *
171
+ * @param result - Result object to populate
172
+ * @param keyParts - Array of nested key parts
173
+ * @param propertyKey - Final property key
174
+ * @param value - Value to set
175
+ */
176
+ function buildNestedStructure(result, keyParts, propertyKey, value) {
177
+ let current = result;
178
+ for (let i = 0; i < keyParts.length - 1; i++) {
179
+ const part = keyParts[i];
180
+ if (!current[part]) {
181
+ current[part] = {};
182
+ }
183
+ current = current[part];
184
+ }
185
+ current[propertyKey] = value;
186
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Tool Detection Utilities
3
+ * Handles detection and extraction of tools from TypeScript source code
4
+ */
5
+ import { Project } from "ts-morph";
6
+ import { ToolInfo } from '../interfaces/compile.js';
7
+ import { TypeScriptSourceFile } from '../types/compile.types.js';
8
+ /**
9
+ * Detects all tools in the project by analyzing the index file.
10
+ * Searches for tools in two places:
11
+ * 1. LuaSkill constructor's tools array
12
+ * 2. skill.addTools() or skill.addTool() method calls
13
+ *
14
+ * @param indexFile - The main index TypeScript source file
15
+ * @param project - The ts-morph Project instance
16
+ * @returns Promise resolving to array of detected tool information
17
+ */
18
+ export declare function detectTools(indexFile: TypeScriptSourceFile, project: Project): Promise<ToolInfo[]>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Tool Detection Utilities
3
+ * Handles detection and extraction of tools from TypeScript source code
4
+ */
5
+ import { Node } from "ts-morph";
6
+ import { extractToolFromNewExpressionSync, } from './compile.js';
7
+ /**
8
+ * Detects all tools in the project by analyzing the index file.
9
+ * Searches for tools in two places:
10
+ * 1. LuaSkill constructor's tools array
11
+ * 2. skill.addTools() or skill.addTool() method calls
12
+ *
13
+ * @param indexFile - The main index TypeScript source file
14
+ * @param project - The ts-morph Project instance
15
+ * @returns Promise resolving to array of detected tool information
16
+ */
17
+ export async function detectTools(indexFile, project) {
18
+ const tools = [];
19
+ // Search strategy 1: Find tools in LuaSkill constructor's tools array
20
+ detectToolsFromConstructor(indexFile, project, tools);
21
+ // Search strategy 2: Find tools from skill.addTools() or skill.addTool() method calls
22
+ detectToolsFromMethodCalls(indexFile, project, tools);
23
+ return tools;
24
+ }
25
+ /**
26
+ * Detects tools from LuaSkill constructor configuration.
27
+ * Example: new LuaSkill({ tools: [new MyTool(), ...] })
28
+ *
29
+ * @param indexFile - The TypeScript source file to analyze
30
+ * @param project - The ts-morph Project instance
31
+ * @param tools - Array to push detected tools into (mutated)
32
+ */
33
+ function detectToolsFromConstructor(indexFile, project, tools) {
34
+ indexFile.forEachDescendant((node) => {
35
+ if (Node.isNewExpression(node)) {
36
+ const expression = node.getExpression();
37
+ if (expression.getText() === 'LuaSkill') {
38
+ const args = node.getArguments();
39
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
40
+ const configObj = args[0];
41
+ // Look for tools property in constructor config
42
+ configObj.getProperties().forEach((prop) => {
43
+ if (Node.isPropertyAssignment(prop) && prop.getName() === 'tools') {
44
+ const value = prop.getInitializer();
45
+ if (value && Node.isArrayLiteralExpression(value)) {
46
+ const toolsArray = value;
47
+ toolsArray.getElements().forEach((element) => {
48
+ if (Node.isNewExpression(element)) {
49
+ const toolInfo = extractToolFromNewExpressionSync(element, project);
50
+ if (toolInfo) {
51
+ tools.push(toolInfo);
52
+ }
53
+ }
54
+ });
55
+ }
56
+ }
57
+ });
58
+ }
59
+ }
60
+ }
61
+ });
62
+ }
63
+ /**
64
+ * Detects tools from skill.addTools() or skill.addTool() method calls.
65
+ * Examples:
66
+ * - skill.addTools([new Tool1(), new Tool2()])
67
+ * - skill.addTool(new MyTool())
68
+ *
69
+ * @param indexFile - The TypeScript source file to analyze
70
+ * @param project - The ts-morph Project instance
71
+ * @param tools - Array to push detected tools into (mutated)
72
+ */
73
+ function detectToolsFromMethodCalls(indexFile, project, tools) {
74
+ indexFile.forEachDescendant((node) => {
75
+ if (Node.isCallExpression(node)) {
76
+ const expression = node.getExpression();
77
+ if (Node.isPropertyAccessExpression(expression)) {
78
+ const property = expression.getName();
79
+ if (property === 'addTools' || property === 'addTool') {
80
+ const args = node.getArguments();
81
+ if (property === 'addTools' && args.length > 0) {
82
+ // Handle skill.addTools([...]) - array of tools
83
+ const arrayArg = args[0];
84
+ if (Node.isArrayLiteralExpression(arrayArg)) {
85
+ const elements = arrayArg.getElements();
86
+ for (const element of elements) {
87
+ if (Node.isNewExpression(element)) {
88
+ const toolInfo = extractToolFromNewExpressionSync(element, project);
89
+ if (toolInfo) {
90
+ tools.push(toolInfo);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ else if (property === 'addTool' && args.length > 0) {
97
+ // Handle skill.addTool(new ToolClass()) - single tool
98
+ const arg = args[0];
99
+ if (Node.isNewExpression(arg)) {
100
+ const toolInfo = extractToolFromNewExpressionSync(arg, project);
101
+ if (toolInfo) {
102
+ tools.push(toolInfo);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ });
110
+ }