lua-cli 3.2.0-alpha.2 → 3.3.0

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 (328) hide show
  1. package/dist/api/agent.api.service.js +1 -0
  2. package/dist/api/agent.api.service.js.map +1 -0
  3. package/dist/api/auth.api.service.js +1 -0
  4. package/dist/api/auth.api.service.js.map +1 -0
  5. package/dist/api/basket.api.service.js +1 -0
  6. package/dist/api/basket.api.service.js.map +1 -0
  7. package/dist/api/cdn.api.service.js +1 -0
  8. package/dist/api/cdn.api.service.js.map +1 -0
  9. package/dist/api/chat.api.service.js +1 -0
  10. package/dist/api/chat.api.service.js.map +1 -0
  11. package/dist/api/credentials.js +1 -0
  12. package/dist/api/credentials.js.map +1 -0
  13. package/dist/api/custom.data.api.service.js +1 -0
  14. package/dist/api/custom.data.api.service.js.map +1 -0
  15. package/dist/api/developer.api.service.js +1 -0
  16. package/dist/api/developer.api.service.js.map +1 -0
  17. package/dist/api/job.api.service.js +1 -0
  18. package/dist/api/job.api.service.js.map +1 -0
  19. package/dist/api/lazy-instances.js +1 -0
  20. package/dist/api/lazy-instances.js.map +1 -0
  21. package/dist/api/logs.api.service.d.ts +1 -1
  22. package/dist/api/logs.api.service.js +1 -0
  23. package/dist/api/logs.api.service.js.map +1 -0
  24. package/dist/api/marketplace.api.service.js +1 -0
  25. package/dist/api/marketplace.api.service.js.map +1 -0
  26. package/dist/api/order.api.service.js +1 -0
  27. package/dist/api/order.api.service.js.map +1 -0
  28. package/dist/api/persona.api.service.js +1 -0
  29. package/dist/api/persona.api.service.js.map +1 -0
  30. package/dist/api/postprocessor.api.service.js +1 -0
  31. package/dist/api/postprocessor.api.service.js.map +1 -0
  32. package/dist/api/preprocessor.api.service.js +1 -0
  33. package/dist/api/preprocessor.api.service.js.map +1 -0
  34. package/dist/api/products.api.service.d.ts +17 -5
  35. package/dist/api/products.api.service.js +22 -9
  36. package/dist/api/products.api.service.js.map +1 -0
  37. package/dist/api/skills.api.service.js +1 -0
  38. package/dist/api/skills.api.service.js.map +1 -0
  39. package/dist/api/tool.api.service.js +1 -0
  40. package/dist/api/tool.api.service.js.map +1 -0
  41. package/dist/api/user.data.api.service.js +1 -0
  42. package/dist/api/user.data.api.service.js.map +1 -0
  43. package/dist/api/webhook.api.service.js +1 -0
  44. package/dist/api/webhook.api.service.js.map +1 -0
  45. package/dist/api/whatsapp-templates.api.service.js +1 -0
  46. package/dist/api/whatsapp-templates.api.service.js.map +1 -0
  47. package/dist/api-exports.d.ts +23 -6
  48. package/dist/api-exports.js +27 -5
  49. package/dist/api-exports.js.map +1 -0
  50. package/dist/cli/command-definitions.js +321 -88
  51. package/dist/cli/command-definitions.js.map +1 -0
  52. package/dist/commands/admin.js +1 -0
  53. package/dist/commands/admin.js.map +1 -0
  54. package/dist/commands/agents.js +1 -0
  55. package/dist/commands/agents.js.map +1 -0
  56. package/dist/commands/apiKey.d.ts +5 -2
  57. package/dist/commands/apiKey.js +9 -2
  58. package/dist/commands/apiKey.js.map +1 -0
  59. package/dist/commands/channels.d.ts +4 -9
  60. package/dist/commands/channels.js +141 -84
  61. package/dist/commands/channels.js.map +1 -0
  62. package/dist/commands/chat.d.ts +4 -2
  63. package/dist/commands/chat.js +127 -32
  64. package/dist/commands/chat.js.map +1 -0
  65. package/dist/commands/chatClear.d.ts +3 -2
  66. package/dist/commands/chatClear.js +17 -15
  67. package/dist/commands/chatClear.js.map +1 -0
  68. package/dist/commands/compile.js +68 -4
  69. package/dist/commands/compile.js.map +1 -0
  70. package/dist/commands/completion.js +1 -0
  71. package/dist/commands/completion.js.map +1 -0
  72. package/dist/commands/configure.js +1 -0
  73. package/dist/commands/configure.js.map +1 -0
  74. package/dist/commands/deploy.d.ts +5 -24
  75. package/dist/commands/deploy.js +76 -48
  76. package/dist/commands/deploy.js.map +1 -0
  77. package/dist/commands/destroy.d.ts +5 -2
  78. package/dist/commands/destroy.js +15 -2
  79. package/dist/commands/destroy.js.map +1 -0
  80. package/dist/commands/dev.js +1 -0
  81. package/dist/commands/dev.js.map +1 -0
  82. package/dist/commands/docs.js +1 -0
  83. package/dist/commands/docs.js.map +1 -0
  84. package/dist/commands/env.d.ts +3 -1
  85. package/dist/commands/env.js +323 -122
  86. package/dist/commands/env.js.map +1 -0
  87. package/dist/commands/evals.js +1 -0
  88. package/dist/commands/evals.js.map +1 -0
  89. package/dist/commands/features.d.ts +5 -9
  90. package/dist/commands/features.js +250 -129
  91. package/dist/commands/features.js.map +1 -0
  92. package/dist/commands/index.js +1 -0
  93. package/dist/commands/index.js.map +1 -0
  94. package/dist/commands/init.d.ts +7 -1
  95. package/dist/commands/init.js +252 -65
  96. package/dist/commands/init.js.map +1 -0
  97. package/dist/commands/jobs.d.ts +5 -13
  98. package/dist/commands/jobs.js +450 -364
  99. package/dist/commands/jobs.js.map +1 -0
  100. package/dist/commands/logs.d.ts +5 -10
  101. package/dist/commands/logs.js +260 -103
  102. package/dist/commands/logs.js.map +1 -0
  103. package/dist/commands/marketplace.d.ts +23 -2
  104. package/dist/commands/marketplace.js +531 -7
  105. package/dist/commands/marketplace.js.map +1 -0
  106. package/dist/commands/mcp.d.ts +5 -11
  107. package/dist/commands/mcp.js +304 -288
  108. package/dist/commands/mcp.js.map +1 -0
  109. package/dist/commands/persona.d.ts +5 -9
  110. package/dist/commands/persona.js +350 -232
  111. package/dist/commands/persona.js.map +1 -0
  112. package/dist/commands/postprocessors.d.ts +6 -2
  113. package/dist/commands/postprocessors.js +388 -280
  114. package/dist/commands/postprocessors.js.map +1 -0
  115. package/dist/commands/preprocessors.d.ts +6 -2
  116. package/dist/commands/preprocessors.js +388 -280
  117. package/dist/commands/preprocessors.js.map +1 -0
  118. package/dist/commands/production.d.ts +5 -8
  119. package/dist/commands/production.js +318 -228
  120. package/dist/commands/production.js.map +1 -0
  121. package/dist/commands/push.js +386 -427
  122. package/dist/commands/push.js.map +1 -0
  123. package/dist/commands/resources.d.ts +5 -10
  124. package/dist/commands/resources.js +220 -154
  125. package/dist/commands/resources.js.map +1 -0
  126. package/dist/commands/skills.d.ts +5 -9
  127. package/dist/commands/skills.js +355 -278
  128. package/dist/commands/skills.js.map +1 -0
  129. package/dist/commands/sync.d.ts +10 -8
  130. package/dist/commands/sync.js +111 -19
  131. package/dist/commands/sync.js.map +1 -0
  132. package/dist/commands/test.d.ts +1 -11
  133. package/dist/commands/test.js +396 -438
  134. package/dist/commands/test.js.map +1 -0
  135. package/dist/commands/webhooks.d.ts +5 -11
  136. package/dist/commands/webhooks.js +357 -290
  137. package/dist/commands/webhooks.js.map +1 -0
  138. package/dist/common/basket.instance.js +1 -0
  139. package/dist/common/basket.instance.js.map +1 -0
  140. package/dist/common/data.entry.instance.js +1 -0
  141. package/dist/common/data.entry.instance.js.map +1 -0
  142. package/dist/common/http.client.js +1 -0
  143. package/dist/common/http.client.js.map +1 -0
  144. package/dist/common/job.instance.js +1 -0
  145. package/dist/common/job.instance.js.map +1 -0
  146. package/dist/common/order.instance.js +1 -0
  147. package/dist/common/order.instance.js.map +1 -0
  148. package/dist/common/product.instance.js +1 -0
  149. package/dist/common/product.instance.js.map +1 -0
  150. package/dist/common/product.pagination.instance.js +1 -0
  151. package/dist/common/product.pagination.instance.js.map +1 -0
  152. package/dist/common/product.search.instance.js +1 -0
  153. package/dist/common/product.search.instance.js.map +1 -0
  154. package/dist/common/user.instance.js +1 -0
  155. package/dist/common/user.instance.js.map +1 -0
  156. package/dist/config/auth.constants.js +1 -0
  157. package/dist/config/auth.constants.js.map +1 -0
  158. package/dist/config/compile.constants.js +1 -0
  159. package/dist/config/compile.constants.js.map +1 -0
  160. package/dist/config/constants.js +1 -0
  161. package/dist/config/constants.js.map +1 -0
  162. package/dist/config/dev.constants.js +1 -0
  163. package/dist/config/dev.constants.js.map +1 -0
  164. package/dist/config/init.constants.d.ts +0 -8
  165. package/dist/config/init.constants.js +1 -24
  166. package/dist/config/init.constants.js.map +1 -0
  167. package/dist/errors/auth.error.js +1 -0
  168. package/dist/errors/auth.error.js.map +1 -0
  169. package/dist/errors/index.js +1 -0
  170. package/dist/errors/index.js.map +1 -0
  171. package/dist/index.js +1 -0
  172. package/dist/index.js.map +1 -0
  173. package/dist/interfaces/admin.js +1 -0
  174. package/dist/interfaces/admin.js.map +1 -0
  175. package/dist/interfaces/agent.d.ts +2 -27
  176. package/dist/interfaces/agent.js +1 -0
  177. package/dist/interfaces/agent.js.map +1 -0
  178. package/dist/interfaces/baskets.js +1 -0
  179. package/dist/interfaces/baskets.js.map +1 -0
  180. package/dist/interfaces/cdn.js +1 -0
  181. package/dist/interfaces/cdn.js.map +1 -0
  182. package/dist/interfaces/chat.js +1 -0
  183. package/dist/interfaces/chat.js.map +1 -0
  184. package/dist/interfaces/common.js +1 -0
  185. package/dist/interfaces/common.js.map +1 -0
  186. package/dist/interfaces/compile.js +1 -0
  187. package/dist/interfaces/compile.js.map +1 -0
  188. package/dist/interfaces/custom.data.js +1 -0
  189. package/dist/interfaces/custom.data.js.map +1 -0
  190. package/dist/interfaces/deploy.js +1 -0
  191. package/dist/interfaces/deploy.js.map +1 -0
  192. package/dist/interfaces/dev.js +1 -0
  193. package/dist/interfaces/dev.js.map +1 -0
  194. package/dist/interfaces/index.js +1 -0
  195. package/dist/interfaces/index.js.map +1 -0
  196. package/dist/interfaces/init.d.ts +0 -19
  197. package/dist/interfaces/init.js +1 -0
  198. package/dist/interfaces/init.js.map +1 -0
  199. package/dist/interfaces/jobs.js +1 -0
  200. package/dist/interfaces/jobs.js.map +1 -0
  201. package/dist/interfaces/logs.js +1 -0
  202. package/dist/interfaces/logs.js.map +1 -0
  203. package/dist/interfaces/lua.d.ts +11 -1
  204. package/dist/interfaces/lua.js +1 -0
  205. package/dist/interfaces/lua.js.map +1 -0
  206. package/dist/interfaces/marketplace.js +1 -0
  207. package/dist/interfaces/marketplace.js.map +1 -0
  208. package/dist/interfaces/mcp.d.ts +28 -1
  209. package/dist/interfaces/mcp.js +1 -0
  210. package/dist/interfaces/mcp.js.map +1 -0
  211. package/dist/interfaces/message.js +1 -0
  212. package/dist/interfaces/message.js.map +1 -0
  213. package/dist/interfaces/orders.js +1 -0
  214. package/dist/interfaces/orders.js.map +1 -0
  215. package/dist/interfaces/persona.js +1 -0
  216. package/dist/interfaces/persona.js.map +1 -0
  217. package/dist/interfaces/postprocessors.js +1 -0
  218. package/dist/interfaces/postprocessors.js.map +1 -0
  219. package/dist/interfaces/preprocessors.js +1 -0
  220. package/dist/interfaces/preprocessors.js.map +1 -0
  221. package/dist/interfaces/product.d.ts +26 -0
  222. package/dist/interfaces/product.js +1 -0
  223. package/dist/interfaces/product.js.map +1 -0
  224. package/dist/interfaces/push.js +1 -0
  225. package/dist/interfaces/push.js.map +1 -0
  226. package/dist/interfaces/skills.js +1 -0
  227. package/dist/interfaces/skills.js.map +1 -0
  228. package/dist/interfaces/test.js +1 -0
  229. package/dist/interfaces/test.js.map +1 -0
  230. package/dist/interfaces/user.js +1 -0
  231. package/dist/interfaces/user.js.map +1 -0
  232. package/dist/interfaces/webhooks.js +1 -0
  233. package/dist/interfaces/webhooks.js.map +1 -0
  234. package/dist/interfaces/whatsapp-templates.js +1 -0
  235. package/dist/interfaces/whatsapp-templates.js.map +1 -0
  236. package/dist/services/auth.js +1 -0
  237. package/dist/services/auth.js.map +1 -0
  238. package/dist/types/api-contracts.d.ts +8 -4
  239. package/dist/types/api-contracts.js +1 -0
  240. package/dist/types/api-contracts.js.map +1 -0
  241. package/dist/types/compile.types.js +1 -0
  242. package/dist/types/compile.types.js.map +1 -0
  243. package/dist/types/index.d.ts +3 -3
  244. package/dist/types/index.js +1 -0
  245. package/dist/types/index.js.map +1 -0
  246. package/dist/types/skill.d.ts +92 -17
  247. package/dist/types/skill.js +16 -11
  248. package/dist/types/skill.js.map +1 -0
  249. package/dist/types/tool-validation.js +1 -0
  250. package/dist/types/tool-validation.js.map +1 -0
  251. package/dist/utils/agent-code-utils.d.ts +2 -1
  252. package/dist/utils/agent-code-utils.js +14 -3
  253. package/dist/utils/agent-code-utils.js.map +1 -0
  254. package/dist/utils/auth-flows.js +1 -0
  255. package/dist/utils/auth-flows.js.map +1 -0
  256. package/dist/utils/bundling.d.ts +17 -0
  257. package/dist/utils/bundling.js +146 -12
  258. package/dist/utils/bundling.js.map +1 -0
  259. package/dist/utils/cli.js +1 -0
  260. package/dist/utils/cli.js.map +1 -0
  261. package/dist/utils/compile.d.ts +5 -0
  262. package/dist/utils/compile.js +154 -15
  263. package/dist/utils/compile.js.map +1 -0
  264. package/dist/utils/deploy-api.js +1 -0
  265. package/dist/utils/deploy-api.js.map +1 -0
  266. package/dist/utils/deploy-helpers.js +1 -0
  267. package/dist/utils/deploy-helpers.js.map +1 -0
  268. package/dist/utils/deployment.js +1 -0
  269. package/dist/utils/deployment.js.map +1 -0
  270. package/dist/utils/dev-api.js +1 -0
  271. package/dist/utils/dev-api.js.map +1 -0
  272. package/dist/utils/dev-helpers.d.ts +3 -2
  273. package/dist/utils/dev-helpers.js +4 -5
  274. package/dist/utils/dev-helpers.js.map +1 -0
  275. package/dist/utils/dev-server.js +1 -0
  276. package/dist/utils/dev-server.js.map +1 -0
  277. package/dist/utils/dev-watcher.js +1 -0
  278. package/dist/utils/dev-watcher.js.map +1 -0
  279. package/dist/utils/env-loader.utils.js +1 -0
  280. package/dist/utils/env-loader.utils.js.map +1 -0
  281. package/dist/utils/files.js +1 -0
  282. package/dist/utils/files.js.map +1 -0
  283. package/dist/utils/init-agent.d.ts +4 -4
  284. package/dist/utils/init-agent.js +12 -14
  285. package/dist/utils/init-agent.js.map +1 -0
  286. package/dist/utils/init-helpers.js +1 -0
  287. package/dist/utils/init-helpers.js.map +1 -0
  288. package/dist/utils/init-prompts.d.ts +10 -6
  289. package/dist/utils/init-prompts.js +41 -75
  290. package/dist/utils/init-prompts.js.map +1 -0
  291. package/dist/utils/job-management.js +1 -0
  292. package/dist/utils/job-management.js.map +1 -0
  293. package/dist/utils/mcp-server-management.d.ts +1 -1
  294. package/dist/utils/mcp-server-management.js +14 -14
  295. package/dist/utils/mcp-server-management.js.map +1 -0
  296. package/dist/utils/postprocessor-management.js +1 -0
  297. package/dist/utils/postprocessor-management.js.map +1 -0
  298. package/dist/utils/pre-bundle-jobs.js +1 -0
  299. package/dist/utils/pre-bundle-jobs.js.map +1 -0
  300. package/dist/utils/preprocessor-management.js +1 -0
  301. package/dist/utils/preprocessor-management.js.map +1 -0
  302. package/dist/utils/prompt-handler.js +1 -0
  303. package/dist/utils/prompt-handler.js.map +1 -0
  304. package/dist/utils/push-api.js +1 -0
  305. package/dist/utils/push-api.js.map +1 -0
  306. package/dist/utils/push-helpers.js +1 -0
  307. package/dist/utils/push-helpers.js.map +1 -0
  308. package/dist/utils/sandbox-storage.js +1 -0
  309. package/dist/utils/sandbox-storage.js.map +1 -0
  310. package/dist/utils/sandbox.d.ts +1 -0
  311. package/dist/utils/sandbox.js +2 -0
  312. package/dist/utils/sandbox.js.map +1 -0
  313. package/dist/utils/semver.js +1 -0
  314. package/dist/utils/semver.js.map +1 -0
  315. package/dist/utils/skill-management.js +1 -0
  316. package/dist/utils/skill-management.js.map +1 -0
  317. package/dist/utils/sync-helpers.js +23 -4
  318. package/dist/utils/sync-helpers.js.map +1 -0
  319. package/dist/utils/test-helpers.js +1 -0
  320. package/dist/utils/test-helpers.js.map +1 -0
  321. package/dist/utils/test-prompts.js +1 -0
  322. package/dist/utils/test-prompts.js.map +1 -0
  323. package/dist/utils/tool-detection.js +1 -0
  324. package/dist/utils/tool-detection.js.map +1 -0
  325. package/dist/utils/webhook-management.js +1 -0
  326. package/dist/utils/webhook-management.js.map +1 -0
  327. package/package.json +2 -1
  328. package/template/package.json +1 -1
@@ -12,26 +12,121 @@ import { readSkillConfig } from "../utils/files.js";
12
12
  import { safePrompt } from "../utils/prompt-handler.js";
13
13
  import { decompressCode, readDeployJson, extractToolsFromDeployData, hasEnvFile, } from "../utils/test-helpers.js";
14
14
  import { promptToolSelection, generatePromptsForObject } from "../utils/test-prompts.js";
15
+ // ─────────────────────────────────────────────────────────────────────────────
16
+ // Shared Helpers
17
+ // ─────────────────────────────────────────────────────────────────────────────
18
+ /**
19
+ * Loads API key and agent ID, failing with clear error if not configured.
20
+ */
21
+ async function loadAuthOrFail() {
22
+ const apiKey = await loadApiKey();
23
+ if (!apiKey) {
24
+ throw new Error("No API key found. Please run 'lua auth configure' first.");
25
+ }
26
+ const config = readSkillConfig();
27
+ const agentId = config?.agent?.agentId;
28
+ if (!agentId) {
29
+ throw new Error("No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
30
+ }
31
+ return { apiKey, agentId, config };
32
+ }
33
+ /**
34
+ * Wraps execution with sandbox environment (env vars setup/teardown).
35
+ */
36
+ async function withSandboxEnv(fn) {
37
+ const envVars = loadEnvironmentVariables();
38
+ const originalEnv = { ...process.env };
39
+ for (const [key, value] of Object.entries(envVars)) {
40
+ process.env[key] = value;
41
+ }
42
+ try {
43
+ return await fn();
44
+ }
45
+ finally {
46
+ process.env = originalEnv;
47
+ }
48
+ }
49
+ /**
50
+ * Loads bundled JSON data from dist folder, failing with clear error if not found.
51
+ */
52
+ function loadBundledJsonOrFail(filename, entityType) {
53
+ const filePath = path.join(process.cwd(), 'dist', filename);
54
+ if (!fs.existsSync(filePath)) {
55
+ console.error(`āŒ Bundled ${entityType} data not found. Please run compilation first.`);
56
+ process.exit(1);
57
+ }
58
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
59
+ if (Array.isArray(data) && data.length === 0) {
60
+ console.error(`āŒ No ${entityType}s found.`);
61
+ process.exit(1);
62
+ }
63
+ return data;
64
+ }
65
+ /**
66
+ * Parses JSON input, failing with formatted error message.
67
+ */
68
+ function parseJsonInputOrFail(inputJson, expectedFormat) {
69
+ try {
70
+ return JSON.parse(inputJson);
71
+ }
72
+ catch (error) {
73
+ console.error(`āŒ Invalid JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
74
+ console.log(`Expected format: ${expectedFormat}`);
75
+ process.exit(1);
76
+ }
77
+ }
78
+ /**
79
+ * Selects an entity by name (non-interactive) or prompts user (interactive).
80
+ */
81
+ async function selectEntityOrPrompt(options) {
82
+ const { items, entityName, entityType, idProperty, nameProperty, promptMessage, formatChoice } = options;
83
+ if (entityName) {
84
+ const selected = items.find((item) => item[idProperty] === entityName || item[nameProperty] === entityName);
85
+ if (!selected) {
86
+ console.error(`āŒ ${entityType} "${entityName}" not found`);
87
+ process.exit(1);
88
+ }
89
+ writeProgress(`āœ… Selected ${entityType.toLowerCase()}: ${selected[nameProperty]}`);
90
+ return selected;
91
+ }
92
+ const answer = await safePrompt([
93
+ {
94
+ type: 'list',
95
+ name: 'selected',
96
+ message: promptMessage,
97
+ choices: items.map((item) => ({
98
+ name: formatChoice ? formatChoice(item) : `${item[nameProperty]}`,
99
+ value: item
100
+ }))
101
+ }
102
+ ]);
103
+ if (!answer)
104
+ return null;
105
+ return answer.selected;
106
+ }
107
+ /**
108
+ * Handles execution errors with consistent formatting.
109
+ */
110
+ function handleExecutionError(error, entityType) {
111
+ console.error(`\nāŒ ${entityType} execution failed:`);
112
+ console.error(error.message);
113
+ if (error.stack) {
114
+ console.error(error.stack);
115
+ }
116
+ }
117
+ // ─────────────────────────────────────────────────────────────────────────────
118
+ // Main Command
119
+ // ─────────────────────────────────────────────────────────────────────────────
15
120
  /**
16
121
  * Main test command - tests tools, webhooks, jobs, preprocessors, or postprocessors.
17
- *
18
- * This command can test:
19
- * - Skills/Tools: Interactive tool execution with input prompts
20
- * - Webhooks: Test webhook with query params, headers, and body
21
- * - Jobs: Trigger job execution manually
22
- * - PreProcessors: Test message preprocessing
23
- * - PostProcessors: Test response postprocessing
24
- *
25
- * @param type - Optional type argument ('skill', 'webhook', 'job', 'preprocessor', 'postprocessor')
26
- * @returns Promise that resolves when test completes
27
122
  */
28
- export async function testCommand(type) {
123
+ export async function testCommand(type, cmdObj) {
29
124
  return withErrorHandling(async () => {
125
+ const entityName = cmdObj?.name || null;
126
+ const inputJson = cmdObj?.input || null;
30
127
  let selectedType;
31
- // Step 1: Check if type was provided as argument
32
128
  if (type) {
33
- // Validate the provided type
34
- if (type !== 'skill' && type !== 'webhook' && type !== 'job' && type !== 'preprocessor' && type !== 'postprocessor') {
129
+ if (!['skill', 'webhook', 'job', 'preprocessor', 'postprocessor'].includes(type)) {
35
130
  console.error(`āŒ Invalid type: "${type}". Must be "skill", "webhook", "job", "preprocessor", or "postprocessor".`);
36
131
  console.log('\nUsage:');
37
132
  console.log(' lua test - Interactive selection');
@@ -44,8 +139,14 @@ export async function testCommand(type) {
44
139
  }
45
140
  selectedType = type;
46
141
  }
142
+ else if (entityName) {
143
+ console.error(`āŒ Type must be specified when using the --name option.`);
144
+ console.log('\nUsage:');
145
+ console.log(' lua test skill --name mySkill --input "{...}" Test skill with JSON input');
146
+ console.log(' lua test webhook --name myWebhook --input "{...}" Test webhook with JSON input');
147
+ process.exit(1);
148
+ }
47
149
  else {
48
- // Step 2: Prompt for type selection
49
150
  const typeAnswer = await safePrompt([
50
151
  {
51
152
  type: 'list',
@@ -66,517 +167,373 @@ export async function testCommand(type) {
66
167
  }
67
168
  selectedType = typeAnswer.type;
68
169
  }
69
- // Step 3: Route to appropriate function
70
- if (selectedType === 'skill') {
71
- await testSkill();
72
- }
73
- else if (selectedType === 'webhook') {
74
- await testWebhook();
75
- }
76
- else if (selectedType === 'job') {
77
- await testJob();
78
- }
79
- else if (selectedType === 'preprocessor') {
80
- await testPreProcessor();
81
- }
82
- else if (selectedType === 'postprocessor') {
83
- await testPostProcessor();
170
+ switch (selectedType) {
171
+ case 'skill':
172
+ await testSkill(entityName, inputJson);
173
+ break;
174
+ case 'webhook':
175
+ await testWebhook(entityName, inputJson);
176
+ break;
177
+ case 'job':
178
+ await testJob(entityName);
179
+ break;
180
+ case 'preprocessor':
181
+ await testPreProcessor(entityName, inputJson);
182
+ break;
183
+ case 'postprocessor':
184
+ await testPostProcessor(entityName, inputJson);
185
+ break;
84
186
  }
85
187
  }, "testing");
86
188
  }
87
- /**
88
- * Test a skill/tool interactively.
89
- */
90
- async function testSkill() {
189
+ // ─────────────────────────────────────────────────────────────────────────────
190
+ // Test Functions
191
+ // ─────────────────────────────────────────────────────────────────────────────
192
+ async function testSkill(entityName, inputJson) {
91
193
  writeProgress("🧪 Testing Lua skill...");
92
- // Step 1: Compile the code
93
194
  writeProgress("šŸ“¦ Compiling code first...");
94
195
  await compileCommand();
95
- // Step 2: Load deploy data and extract tools
96
196
  const deployData = readDeployJson();
97
197
  const allTools = extractToolsFromDeployData(deployData);
98
- // Step 3: Load authentication and configuration
99
- const apiKey = await loadApiKey();
100
- if (!apiKey) {
101
- throw new Error("No API key found. Please run 'lua auth configure' first.");
102
- }
103
- const config = readSkillConfig();
104
- const agentId = config?.agent?.agentId;
105
- if (!agentId) {
106
- throw new Error("No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
107
- }
108
- // Step 4: Load environment variables
109
- const envVars = loadEnvironmentVariables();
198
+ const { apiKey, agentId } = await loadAuthOrFail();
110
199
  if (hasEnvFile()) {
111
200
  writeProgress(`šŸ“„ Loaded environment variables from .env file`);
112
201
  }
113
- // Step 5: Let user select a tool
114
- const selectedTool = await promptToolSelection(allTools);
115
- clearPromptLines(2);
116
- writeProgress(`āœ… Selected tool: ${selectedTool.name}`);
117
- // Step 6: Collect input values based on schema
202
+ // Select tool
203
+ let selectedTool;
204
+ if (entityName) {
205
+ selectedTool = allTools.find((t) => t.id === entityName || t.name === entityName);
206
+ if (!selectedTool) {
207
+ console.error(`āŒ Tool "${entityName}" not found`);
208
+ process.exit(1);
209
+ }
210
+ writeProgress(`āœ… Selected tool: ${selectedTool.name}`);
211
+ }
212
+ else {
213
+ selectedTool = await promptToolSelection(allTools);
214
+ clearPromptLines(2);
215
+ writeProgress(`āœ… Selected tool: ${selectedTool.name}`);
216
+ }
217
+ // Get input values
118
218
  let inputValues = {};
119
219
  const inputSchema = selectedTool.inputSchema;
120
- if (inputSchema.properties) {
220
+ if (inputJson) {
221
+ inputValues = parseJsonInputOrFail(inputJson, '{"param1": "value1", ...}');
222
+ writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
223
+ }
224
+ else if (inputSchema && inputSchema.properties) {
121
225
  writeProgress("\nšŸ“ Enter input values:");
122
226
  inputValues = await generatePromptsForObject(inputSchema, '', inputSchema.required || []);
123
227
  }
124
- // Step 7: Execute the tool
228
+ // Execute
125
229
  writeProgress("\nšŸš€ Executing tool...");
126
- writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
127
230
  const toolCode = decompressCode(selectedTool.execute);
128
- // Set environment variables for sandbox
129
- const originalEnv = { ...process.env };
130
- for (const [key, value] of Object.entries(envVars)) {
131
- process.env[key] = value;
132
- }
133
- try {
134
- const result = await executeTool({
135
- toolCode,
136
- inputs: inputValues,
137
- apiKey,
138
- agentId,
139
- channel: 'dev',
140
- });
141
- writeSuccess("āœ… Tool execution successful!");
142
- console.log(`Output: ${JSON.stringify(result, null, 2)}`);
143
- }
144
- catch (executionError) {
145
- console.error("\nāŒ Tool execution failed:");
146
- console.error(executionError.message);
147
- if (executionError.stack) {
148
- console.error(executionError.stack);
231
+ await withSandboxEnv(async () => {
232
+ try {
233
+ const result = await executeTool({
234
+ toolCode,
235
+ inputs: inputValues,
236
+ apiKey,
237
+ agentId,
238
+ channel: 'dev',
239
+ });
240
+ writeSuccess("āœ… Tool execution successful!");
241
+ console.log(`Output: ${JSON.stringify(result, null, 2)}`);
149
242
  }
150
- }
151
- finally {
152
- // Restore original environment variables
153
- process.env = originalEnv;
154
- }
243
+ catch (error) {
244
+ handleExecutionError(error, 'Tool');
245
+ }
246
+ });
155
247
  }
156
- /**
157
- * Test a webhook interactively.
158
- */
159
- async function testWebhook() {
248
+ async function testWebhook(entityName, inputJson) {
160
249
  writeProgress("šŸŖ Testing webhook...");
161
- // Step 1: Compile the code
162
250
  writeProgress("šŸ“¦ Compiling code first...");
163
251
  await compileCommand();
164
- // Step 2: Load configuration
165
- const config = readSkillConfig();
252
+ const { apiKey, agentId, config } = await loadAuthOrFail();
166
253
  const webhooks = config.webhooks || [];
167
254
  if (webhooks.length === 0) {
168
255
  console.error("āŒ No webhooks found in configuration.");
169
256
  console.log("šŸ’” Create a webhook using LuaWebhook in your code.");
170
257
  return;
171
258
  }
172
- // Step 3: Load bundled webhook data
173
- const bundledWebhooksPath = path.join(process.cwd(), 'dist', 'webhooks.json');
174
- if (!fs.existsSync(bundledWebhooksPath)) {
175
- console.error("āŒ Bundled webhook data not found. Please run compilation first.");
176
- return;
177
- }
178
- const bundledWebhooks = JSON.parse(fs.readFileSync(bundledWebhooksPath, 'utf8'));
179
- // Step 4: Select webhook to test
180
- const webhookAnswer = await safePrompt([
181
- {
182
- type: 'list',
183
- name: 'selectedWebhook',
184
- message: 'Select a webhook to test:',
185
- choices: webhooks.map((webhook) => ({
186
- name: `${webhook.name} (v${webhook.version})`,
187
- value: webhook
188
- }))
189
- }
190
- ]);
191
- if (!webhookAnswer) {
259
+ const bundledWebhooks = loadBundledJsonOrFail('webhooks.json', 'webhook');
260
+ // Select webhook
261
+ const selectedWebhook = await selectEntityOrPrompt({
262
+ items: webhooks,
263
+ entityName,
264
+ entityType: 'Webhook',
265
+ idProperty: 'webhookId',
266
+ nameProperty: 'name',
267
+ promptMessage: 'Select a webhook to test:',
268
+ formatChoice: (w) => `${w.name} (v${w.version})`
269
+ });
270
+ if (!selectedWebhook) {
192
271
  console.log("Test cancelled.");
193
272
  return;
194
273
  }
195
- const selectedWebhook = webhookAnswer.selectedWebhook;
196
- // Find bundled webhook data
197
274
  const bundledWebhook = bundledWebhooks.find((w) => w.name === selectedWebhook.name);
198
275
  if (!bundledWebhook || !bundledWebhook.code) {
199
- console.error("āŒ Bundled webhook code not found.");
200
- return;
201
- }
202
- // Step 5: Load authentication
203
- const apiKey = await loadApiKey();
204
- if (!apiKey) {
205
- throw new Error("No API key found. Please run 'lua auth configure' first.");
276
+ console.error(`āŒ Bundled webhook code not found for "${selectedWebhook.name}"`);
277
+ process.exit(1);
206
278
  }
207
- const agentId = config?.agent?.agentId;
208
- if (!agentId) {
209
- throw new Error("No agent ID found in lua.skill.yaml.");
210
- }
211
- // Step 6: Collect query parameters based on schema
279
+ // Get inputs
212
280
  let query = {};
213
- if (bundledWebhook.querySchema && bundledWebhook.querySchema.properties) {
214
- writeProgress("\nšŸ“ Enter query parameters:");
215
- query = await generatePromptsForObject(bundledWebhook.querySchema, '', bundledWebhook.querySchema.required || []);
216
- }
217
- // Step 7: Collect headers based on schema
218
281
  let headers = {};
219
- if (bundledWebhook.headerSchema && bundledWebhook.headerSchema.properties) {
220
- writeProgress("\nšŸ“ Enter headers:");
221
- headers = await generatePromptsForObject(bundledWebhook.headerSchema, '', bundledWebhook.headerSchema.required || []);
222
- }
223
- // Step 8: Collect body based on schema
224
282
  let body = {};
225
- if (bundledWebhook.bodySchema && bundledWebhook.bodySchema.properties) {
226
- writeProgress("\nšŸ“ Enter request body:");
227
- body = await generatePromptsForObject(bundledWebhook.bodySchema, '', bundledWebhook.bodySchema.required || []);
283
+ if (inputJson) {
284
+ const input = parseJsonInputOrFail(inputJson, '{"query": {}, "headers": {}, "body": {}}');
285
+ query = input.query || {};
286
+ headers = input.headers || {};
287
+ body = input.body || {};
288
+ }
289
+ else {
290
+ if (bundledWebhook.querySchema?.properties) {
291
+ writeProgress("\nšŸ“ Enter query parameters:");
292
+ query = await generatePromptsForObject(bundledWebhook.querySchema, '', bundledWebhook.querySchema.required || []);
293
+ }
294
+ if (bundledWebhook.headerSchema?.properties) {
295
+ writeProgress("\nšŸ“ Enter headers:");
296
+ headers = await generatePromptsForObject(bundledWebhook.headerSchema, '', bundledWebhook.headerSchema.required || []);
297
+ }
298
+ if (bundledWebhook.bodySchema?.properties) {
299
+ writeProgress("\nšŸ“ Enter request body:");
300
+ body = await generatePromptsForObject(bundledWebhook.bodySchema, '', bundledWebhook.bodySchema.required || []);
301
+ }
228
302
  }
229
- // Step 9: Execute webhook through sandbox
303
+ // Execute
230
304
  writeProgress("\nšŸš€ Executing webhook...");
231
305
  writeProgress(`Query: ${JSON.stringify(query, null, 2)}`);
232
306
  writeProgress(`Headers: ${JSON.stringify(headers, null, 2)}`);
233
307
  writeProgress(`Body: ${JSON.stringify(body, null, 2)}`);
234
308
  const webhookCode = decompressCode(bundledWebhook.code);
235
- // Load environment variables
236
- const envVars = loadEnvironmentVariables();
237
- const originalEnv = { ...process.env };
238
- for (const [key, value] of Object.entries(envVars)) {
239
- process.env[key] = value;
240
- }
241
- try {
242
- const result = await executeWebhook({
243
- webhookCode,
244
- query,
245
- headers,
246
- body,
247
- apiKey,
248
- agentId
249
- });
250
- writeSuccess("\nāœ… Webhook execution successful!");
251
- console.log(`Output: ${JSON.stringify(result, null, 2)}`);
252
- }
253
- catch (executionError) {
254
- console.error("\nāŒ Webhook execution failed:");
255
- console.error(executionError.message);
256
- if (executionError.stack) {
257
- console.error(executionError.stack);
309
+ await withSandboxEnv(async () => {
310
+ try {
311
+ const result = await executeWebhook({ webhookCode, query, headers, body, apiKey, agentId });
312
+ writeSuccess("\nāœ… Webhook execution successful!");
313
+ console.log(`Output: ${JSON.stringify(result, null, 2)}`);
258
314
  }
259
- }
260
- finally {
261
- // Restore original environment variables
262
- process.env = originalEnv;
263
- }
315
+ catch (error) {
316
+ handleExecutionError(error, 'Webhook');
317
+ }
318
+ });
264
319
  }
265
- /**
266
- * Test a job by manually triggering it.
267
- */
268
- async function testJob() {
320
+ async function testJob(entityName) {
269
321
  writeProgress("ā° Testing job...");
270
- // Step 1: Compile the code
271
322
  writeProgress("šŸ“¦ Compiling code first...");
272
323
  await compileCommand();
273
- // Step 2: Load configuration
274
- const apiKey = await loadApiKey();
275
- if (!apiKey) {
276
- throw new Error("No API key found. Please run 'lua auth configure' first.");
277
- }
278
- const config = readSkillConfig();
279
- const agentId = config?.agent?.agentId;
280
- if (!agentId) {
281
- throw new Error("No agent ID found in lua.skill.yaml.");
282
- }
324
+ const { apiKey, agentId, config } = await loadAuthOrFail();
283
325
  const jobs = config.jobs || [];
284
326
  if (jobs.length === 0) {
285
327
  console.error("āŒ No jobs found in configuration.");
286
328
  console.log("šŸ’” Create a job using LuaJob in your code.");
287
329
  return;
288
330
  }
289
- // Step 3: Load bundled job data
290
- const bundledJobsPath = path.join(process.cwd(), 'dist', 'jobs.json');
291
- if (!fs.existsSync(bundledJobsPath)) {
292
- console.error("āŒ Bundled job data not found. Please run compilation first.");
293
- return;
294
- }
295
- const bundledJobs = JSON.parse(fs.readFileSync(bundledJobsPath, 'utf8'));
296
- // Step 4: Select job to test
297
- const jobAnswer = await safePrompt([
298
- {
299
- type: 'list',
300
- name: 'selectedJob',
301
- message: 'Select a job to test:',
302
- choices: jobs.map((job) => ({
303
- name: `${job.name} (v${job.version}) - ${formatSchedule(job.schedule)}`,
304
- value: job
305
- }))
306
- }
307
- ]);
308
- if (!jobAnswer) {
331
+ const bundledJobs = loadBundledJsonOrFail('jobs.json', 'job');
332
+ // Select job
333
+ const selectedJob = await selectEntityOrPrompt({
334
+ items: jobs,
335
+ entityName,
336
+ entityType: 'Job',
337
+ idProperty: 'jobId',
338
+ nameProperty: 'name',
339
+ promptMessage: 'Select a job to test:',
340
+ formatChoice: (j) => `${j.name} (v${j.version}) - ${formatSchedule(j.schedule)}`
341
+ });
342
+ if (!selectedJob) {
309
343
  console.log("Test cancelled.");
310
344
  return;
311
345
  }
312
- const selectedJob = jobAnswer.selectedJob;
313
- // Find bundled job data
314
346
  const bundledJob = bundledJobs.find((j) => j.name === selectedJob.name);
315
347
  if (!bundledJob || !bundledJob.code) {
316
- console.error("āŒ Bundled job code not found.");
317
- return;
348
+ console.error(`āŒ Bundled job code not found for "${selectedJob.name}"`);
349
+ process.exit(1);
318
350
  }
319
- // Step 5: Execute job through sandbox
351
+ // Execute
320
352
  writeProgress(`\nšŸš€ Executing job: ${selectedJob.name}...`);
321
353
  writeProgress(`šŸ“… Schedule: ${formatSchedule(selectedJob.schedule)}`);
322
354
  const jobCode = decompressCode(bundledJob.code);
323
- // Load environment variables
324
- const envVars = loadEnvironmentVariables();
325
- const originalEnv = { ...process.env };
326
- for (const [key, value] of Object.entries(envVars)) {
327
- process.env[key] = value;
328
- }
329
- try {
330
- const result = await executeJob({
331
- jobCode,
332
- apiKey,
333
- agentId,
334
- jobData: {
335
- id: selectedJob.jobId,
336
- jobId: selectedJob.jobId,
337
- name: selectedJob.name,
338
- schedule: selectedJob.schedule,
339
- metadata: bundledJob.metadata || selectedJob.metadata || {}
340
- }
341
- });
342
- writeSuccess("\nāœ… Job execution successful!");
343
- console.log(`Output: ${JSON.stringify(result, null, 2)}`);
344
- }
345
- catch (executionError) {
346
- console.error("\nāŒ Job execution failed:");
347
- console.error(executionError.message);
348
- if (executionError.stack) {
349
- console.error(executionError.stack);
355
+ await withSandboxEnv(async () => {
356
+ try {
357
+ const result = await executeJob({
358
+ jobCode,
359
+ apiKey,
360
+ agentId,
361
+ jobData: {
362
+ id: selectedJob.jobId,
363
+ jobId: selectedJob.jobId,
364
+ name: selectedJob.name,
365
+ schedule: selectedJob.schedule,
366
+ metadata: bundledJob.metadata || selectedJob.metadata || {}
367
+ }
368
+ });
369
+ writeSuccess("\nāœ… Job execution successful!");
370
+ console.log(`Output: ${JSON.stringify(result, null, 2)}`);
350
371
  }
351
- }
352
- finally {
353
- // Restore original environment variables
354
- process.env = originalEnv;
355
- }
372
+ catch (error) {
373
+ handleExecutionError(error, 'Job');
374
+ }
375
+ });
356
376
  }
357
- /**
358
- * Test a preprocessor interactively.
359
- */
360
- async function testPreProcessor() {
377
+ async function testPreProcessor(entityName, inputJson) {
361
378
  writeProgress("šŸ“„ Testing preprocessor...");
362
- // Step 1: Compile the code
363
379
  writeProgress("šŸ“¦ Compiling code first...");
364
380
  await compileCommand();
365
- // Step 2: Load bundled preprocessor data
366
- const preprocessorsPath = path.join(process.cwd(), 'dist', 'preprocessors.json');
367
- if (!fs.existsSync(preprocessorsPath)) {
368
- console.error("āŒ No preprocessors found. Create a PreProcessor in your code.");
369
- return;
370
- }
371
- const preprocessors = JSON.parse(fs.readFileSync(preprocessorsPath, 'utf8'));
372
- if (preprocessors.length === 0) {
373
- console.error("āŒ No preprocessors found.");
381
+ const preprocessors = loadBundledJsonOrFail('preprocessors.json', 'preprocessor');
382
+ // Select preprocessor
383
+ const selected = await selectEntityOrPrompt({
384
+ items: preprocessors,
385
+ entityName,
386
+ entityType: 'Preprocessor',
387
+ idProperty: 'preprocessorId',
388
+ nameProperty: 'name',
389
+ promptMessage: 'Select a preprocessor to test:',
390
+ formatChoice: (p) => `${p.name} (v${p.version})`
391
+ });
392
+ if (!selected)
374
393
  return;
375
- }
376
- // Step 3: Select preprocessor to test
377
- const preprocessorAnswer = await safePrompt([
378
- {
379
- type: 'list',
380
- name: 'selected',
381
- message: 'Select a preprocessor to test:',
382
- choices: preprocessors.map((p) => ({
383
- name: `${p.name} (v${p.version})`,
384
- value: p
385
- }))
386
- }
387
- ]);
388
- if (!preprocessorAnswer)
389
- return;
390
- const selected = preprocessorAnswer.selected;
391
394
  if (!selected.code) {
392
395
  console.error("āŒ Preprocessor code not found.");
393
396
  return;
394
397
  }
395
- // Step 4: Collect test inputs
396
- const messageAnswer = await safePrompt([
397
- {
398
- type: 'input',
399
- name: 'message',
400
- message: 'Enter test message:',
401
- default: 'Hello, I need help with my order'
402
- }
403
- ]);
404
- if (!messageAnswer)
405
- return;
406
- const channelAnswer = await safePrompt([
407
- {
408
- type: 'input',
409
- name: 'channel',
410
- message: 'Enter channel:',
411
- default: 'web'
412
- }
413
- ]);
414
- if (!channelAnswer)
415
- return;
416
- // Step 5: Execute preprocessor
398
+ // Get inputs
399
+ let message;
400
+ let channel;
401
+ if (inputJson) {
402
+ const input = parseJsonInputOrFail(inputJson, '{"message": "text", "channel": "channel_name"}');
403
+ message = input.message || 'Hello, I need help with my order';
404
+ channel = input.channel || 'web';
405
+ }
406
+ else {
407
+ const messageAnswer = await safePrompt([
408
+ { type: 'input', name: 'message', message: 'Enter test message:', default: 'Hello, I need help with my order' }
409
+ ]);
410
+ if (!messageAnswer)
411
+ return;
412
+ message = messageAnswer.message;
413
+ const channelAnswer = await safePrompt([
414
+ { type: 'input', name: 'channel', message: 'Enter channel:', default: 'web' }
415
+ ]);
416
+ if (!channelAnswer)
417
+ return;
418
+ channel = channelAnswer.channel;
419
+ }
420
+ // Execute
417
421
  writeProgress("\nšŸš€ Executing preprocessor...");
418
- writeProgress(`Input message: ${messageAnswer.message}`);
419
- writeProgress(`Channel: ${channelAnswer.channel}`);
420
- const apiKey = await loadApiKey();
421
- if (!apiKey)
422
- throw new Error("No API key found.");
423
- const config = readSkillConfig();
424
- const agentId = config?.agent?.agentId;
425
- if (!agentId)
426
- throw new Error("No agent ID found.");
422
+ writeProgress(`Input message: ${message}`);
423
+ writeProgress(`Channel: ${channel}`);
424
+ const { apiKey, agentId } = await loadAuthOrFail();
427
425
  const preprocessorCode = decompressCode(selected.code);
428
- // Load environment variables
429
- const envVars = loadEnvironmentVariables();
430
- const originalEnv = { ...process.env };
431
- for (const [key, value] of Object.entries(envVars)) {
432
- process.env[key] = value;
433
- }
434
- try {
435
- // Convert string message to ChatMessage array
436
- const messages = [{ type: 'text', text: messageAnswer.message }];
437
- const result = await executePreProcessor({
438
- processorCode: preprocessorCode,
439
- messages: messages, // Pass array instead of string
440
- channel: channelAnswer.channel,
441
- apiKey,
442
- agentId
443
- });
444
- writeSuccess("\nāœ… PreProcessor execution successful!");
445
- console.log(`\nProcessed messages (${result.length}):`);
446
- result.forEach((msg, idx) => {
447
- if (msg.type === 'text') {
448
- console.log(` ${idx + 1}. [TEXT] ${msg.text}`);
449
- }
450
- else if (msg.type === 'image') {
451
- console.log(` ${idx + 1}. [IMAGE] ${msg.mimeType}`);
452
- }
453
- else if (msg.type === 'file') {
454
- console.log(` ${idx + 1}. [FILE] ${msg.mimeType}`);
455
- }
456
- else {
457
- console.log(` ${idx + 1}. [${msg.type}]`, msg);
458
- }
459
- });
460
- }
461
- catch (error) {
462
- console.error("\nāŒ PreProcessor execution failed:");
463
- console.error(error.message);
464
- }
465
- finally {
466
- process.env = originalEnv;
467
- }
426
+ await withSandboxEnv(async () => {
427
+ try {
428
+ const messages = [{ type: 'text', text: message }];
429
+ const result = await executePreProcessor({
430
+ processorCode: preprocessorCode,
431
+ messages,
432
+ channel,
433
+ apiKey,
434
+ agentId
435
+ });
436
+ writeSuccess("\nāœ… PreProcessor execution successful!");
437
+ console.log(`\nProcessed messages (${result.length}):`);
438
+ result.forEach((msg, idx) => {
439
+ if (msg.type === 'text') {
440
+ console.log(` ${idx + 1}. [TEXT] ${msg.text}`);
441
+ }
442
+ else if (msg.type === 'image') {
443
+ console.log(` ${idx + 1}. [IMAGE] ${msg.mimeType}`);
444
+ }
445
+ else if (msg.type === 'file') {
446
+ console.log(` ${idx + 1}. [FILE] ${msg.mimeType}`);
447
+ }
448
+ else {
449
+ console.log(` ${idx + 1}. [${msg.type}]`, msg);
450
+ }
451
+ });
452
+ }
453
+ catch (error) {
454
+ handleExecutionError(error, 'PreProcessor');
455
+ }
456
+ });
468
457
  }
469
- /**
470
- * Test a postprocessor interactively.
471
- */
472
- async function testPostProcessor() {
458
+ async function testPostProcessor(entityName, inputJson) {
473
459
  writeProgress("šŸ“¤ Testing postprocessor...");
474
- // Step 1: Compile the code
475
460
  writeProgress("šŸ“¦ Compiling code first...");
476
461
  await compileCommand();
477
- // Step 2: Load bundled postprocessor data
478
- const postprocessorsPath = path.join(process.cwd(), 'dist', 'postprocessors.json');
479
- if (!fs.existsSync(postprocessorsPath)) {
480
- console.error("āŒ No postprocessors found. Create a PostProcessor in your code.");
481
- return;
482
- }
483
- const postprocessors = JSON.parse(fs.readFileSync(postprocessorsPath, 'utf8'));
484
- if (postprocessors.length === 0) {
485
- console.error("āŒ No postprocessors found.");
462
+ const postprocessors = loadBundledJsonOrFail('postprocessors.json', 'postprocessor');
463
+ // Select postprocessor
464
+ const selected = await selectEntityOrPrompt({
465
+ items: postprocessors,
466
+ entityName,
467
+ entityType: 'Postprocessor',
468
+ idProperty: 'postprocessorId',
469
+ nameProperty: 'name',
470
+ promptMessage: 'Select a postprocessor to test:',
471
+ formatChoice: (p) => `${p.name} (v${p.version})`
472
+ });
473
+ if (!selected)
486
474
  return;
487
- }
488
- // Step 3: Select postprocessor to test
489
- const postprocessorAnswer = await safePrompt([
490
- {
491
- type: 'list',
492
- name: 'selected',
493
- message: 'Select a postprocessor to test:',
494
- choices: postprocessors.map((p) => ({
495
- name: `${p.name} (v${p.version})`,
496
- value: p
497
- }))
498
- }
499
- ]);
500
- if (!postprocessorAnswer)
501
- return;
502
- const selected = postprocessorAnswer.selected;
503
475
  if (!selected.code) {
504
476
  console.error("āŒ Postprocessor code not found.");
505
477
  return;
506
478
  }
507
- // Step 4: Collect test inputs
508
- const messageAnswer = await safePrompt([
509
- {
510
- type: 'input',
511
- name: 'message',
512
- message: 'Enter original user message:',
513
- default: 'What products do you have?'
514
- }
515
- ]);
516
- if (!messageAnswer)
517
- return;
518
- const responseAnswer = await safePrompt([
519
- {
520
- type: 'input',
521
- name: 'response',
522
- message: 'Enter agent response to process:',
523
- default: 'We have laptops, phones, and tablets available.'
524
- }
525
- ]);
526
- if (!responseAnswer)
527
- return;
528
- const channelAnswer = await safePrompt([
529
- {
530
- type: 'input',
531
- name: 'channel',
532
- message: 'Enter channel:',
533
- default: 'web'
534
- }
535
- ]);
536
- if (!channelAnswer)
537
- return;
538
- // Step 5: Execute postprocessor
479
+ // Get inputs
480
+ let message;
481
+ let response;
482
+ let channel;
483
+ if (inputJson) {
484
+ const input = parseJsonInputOrFail(inputJson, '{"message": "text", "response": "text", "channel": "channel_name"}');
485
+ message = input.message || 'What products do you have?';
486
+ response = input.response || 'We have laptops, phones, and tablets available.';
487
+ channel = input.channel || 'web';
488
+ }
489
+ else {
490
+ const messageAnswer = await safePrompt([
491
+ { type: 'input', name: 'message', message: 'Enter original user message:', default: 'What products do you have?' }
492
+ ]);
493
+ if (!messageAnswer)
494
+ return;
495
+ message = messageAnswer.message;
496
+ const responseAnswer = await safePrompt([
497
+ { type: 'input', name: 'response', message: 'Enter agent response to process:', default: 'We have laptops, phones, and tablets available.' }
498
+ ]);
499
+ if (!responseAnswer)
500
+ return;
501
+ response = responseAnswer.response;
502
+ const channelAnswer = await safePrompt([
503
+ { type: 'input', name: 'channel', message: 'Enter channel:', default: 'web' }
504
+ ]);
505
+ if (!channelAnswer)
506
+ return;
507
+ channel = channelAnswer.channel;
508
+ }
509
+ // Execute
539
510
  writeProgress("\nšŸš€ Executing postprocessor...");
540
- writeProgress(`Original message: ${messageAnswer.message}`);
541
- writeProgress(`Agent response: ${responseAnswer.response}`);
542
- writeProgress(`Channel: ${channelAnswer.channel}`);
543
- const apiKey = await loadApiKey();
544
- if (!apiKey)
545
- throw new Error("No API key found.");
546
- const config = readSkillConfig();
547
- const agentId = config?.agent?.agentId;
548
- if (!agentId)
549
- throw new Error("No agent ID found.");
511
+ writeProgress(`Original message: ${message}`);
512
+ writeProgress(`Agent response: ${response}`);
513
+ writeProgress(`Channel: ${channel}`);
514
+ const { apiKey, agentId } = await loadAuthOrFail();
550
515
  const postprocessorCode = decompressCode(selected.code);
551
- // Load environment variables
552
- const envVars = loadEnvironmentVariables();
553
- const originalEnv = { ...process.env };
554
- for (const [key, value] of Object.entries(envVars)) {
555
- process.env[key] = value;
556
- }
557
- try {
558
- const result = await executePostProcessor({
559
- processorCode: postprocessorCode,
560
- message: messageAnswer.message,
561
- response: responseAnswer.response,
562
- channel: channelAnswer.channel,
563
- apiKey,
564
- agentId
565
- });
566
- writeSuccess("\nāœ… PostProcessor execution successful!");
567
- console.log(`Processed response: ${result}`);
568
- }
569
- catch (error) {
570
- console.error("\nāŒ PostProcessor execution failed:");
571
- console.error(error.message);
572
- }
573
- finally {
574
- process.env = originalEnv;
575
- }
516
+ await withSandboxEnv(async () => {
517
+ try {
518
+ const result = await executePostProcessor({
519
+ processorCode: postprocessorCode,
520
+ message,
521
+ response,
522
+ channel,
523
+ apiKey,
524
+ agentId
525
+ });
526
+ writeSuccess("\nāœ… PostProcessor execution successful!");
527
+ console.log(`Processed response: ${result}`);
528
+ }
529
+ catch (error) {
530
+ handleExecutionError(error, 'PostProcessor');
531
+ }
532
+ });
576
533
  }
577
- /**
578
- * Format schedule for display
579
- */
534
+ // ─────────────────────────────────────────────────────────────────────────────
535
+ // Utility Functions
536
+ // ─────────────────────────────────────────────────────────────────────────────
580
537
  function formatSchedule(schedule) {
581
538
  if (!schedule)
582
539
  return 'Not configured';
@@ -591,3 +548,4 @@ function formatSchedule(schedule) {
591
548
  return 'Unknown schedule type';
592
549
  }
593
550
  }
551
+ //# sourceMappingURL=test.js.map