lua-cli 3.12.2 → 3.14.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 (568) hide show
  1. package/README.md +14 -13
  2. package/dist/api/agent.api.service.d.ts +20 -20
  3. package/dist/api/agent.api.service.d.ts.map +1 -1
  4. package/dist/api/agent.api.service.js +1 -1
  5. package/dist/api/agent.api.service.js.map +1 -1
  6. package/dist/api/agents.api.service.d.ts +3 -3
  7. package/dist/api/agents.api.service.d.ts.map +1 -1
  8. package/dist/api/agents.api.service.js +11 -9
  9. package/dist/api/agents.api.service.js.map +1 -1
  10. package/dist/api/ai.api.service.d.ts +4 -4
  11. package/dist/api/ai.api.service.d.ts.map +1 -1
  12. package/dist/api/ai.api.service.js +10 -8
  13. package/dist/api/ai.api.service.js.map +1 -1
  14. package/dist/api/auth.api.service.d.ts +3 -3
  15. package/dist/api/auth.api.service.d.ts.map +1 -1
  16. package/dist/api/auth.api.service.js +1 -1
  17. package/dist/api/auth.api.service.js.map +1 -1
  18. package/dist/api/backup.api.service.d.ts.map +1 -1
  19. package/dist/api/backup.api.service.js +21 -7
  20. package/dist/api/backup.api.service.js.map +1 -1
  21. package/dist/api/basket.api.service.d.ts +5 -5
  22. package/dist/api/basket.api.service.d.ts.map +1 -1
  23. package/dist/api/basket.api.service.js +4 -4
  24. package/dist/api/basket.api.service.js.map +1 -1
  25. package/dist/api/cdn.api.service.d.ts +1 -1
  26. package/dist/api/cdn.api.service.js +3 -3
  27. package/dist/api/cdn.api.service.js.map +1 -1
  28. package/dist/api/chat.api.service.d.ts +4 -4
  29. package/dist/api/chat.api.service.js +3 -3
  30. package/dist/api/chat.api.service.js.map +1 -1
  31. package/dist/api/credentials.js +3 -3
  32. package/dist/api/custom.data.api.service.d.ts +4 -4
  33. package/dist/api/custom.data.api.service.d.ts.map +1 -1
  34. package/dist/api/custom.data.api.service.js +2 -2
  35. package/dist/api/custom.data.api.service.js.map +1 -1
  36. package/dist/api/developer.api.service.d.ts +3 -3
  37. package/dist/api/developer.api.service.d.ts.map +1 -1
  38. package/dist/api/developer.api.service.js +7 -3
  39. package/dist/api/developer.api.service.js.map +1 -1
  40. package/dist/api/device-trigger.api.service.d.ts +3 -3
  41. package/dist/api/device-trigger.api.service.d.ts.map +1 -1
  42. package/dist/api/device-trigger.api.service.js +1 -1
  43. package/dist/api/device-trigger.api.service.js.map +1 -1
  44. package/dist/api/device.api.service.d.ts +3 -3
  45. package/dist/api/device.api.service.d.ts.map +1 -1
  46. package/dist/api/device.api.service.js +1 -1
  47. package/dist/api/device.api.service.js.map +1 -1
  48. package/dist/api/http.client.d.ts +1 -1
  49. package/dist/api/http.client.d.ts.map +1 -1
  50. package/dist/api/http.client.js +6 -6
  51. package/dist/api/http.client.js.map +1 -1
  52. package/dist/api/job.api.service.d.ts +13 -14
  53. package/dist/api/job.api.service.d.ts.map +1 -1
  54. package/dist/api/job.api.service.js +12 -20
  55. package/dist/api/job.api.service.js.map +1 -1
  56. package/dist/api/lazy-instances.d.ts +12 -12
  57. package/dist/api/lazy-instances.js +14 -14
  58. package/dist/api/logs.api.service.d.ts +9 -6
  59. package/dist/api/logs.api.service.d.ts.map +1 -1
  60. package/dist/api/logs.api.service.js +12 -11
  61. package/dist/api/logs.api.service.js.map +1 -1
  62. package/dist/api/marketplace.api.service.d.ts +1 -1
  63. package/dist/api/marketplace.api.service.d.ts.map +1 -1
  64. package/dist/api/marketplace.api.service.js +18 -18
  65. package/dist/api/marketplace.api.service.js.map +1 -1
  66. package/dist/api/order.api.service.d.ts +4 -4
  67. package/dist/api/order.api.service.d.ts.map +1 -1
  68. package/dist/api/order.api.service.js +2 -2
  69. package/dist/api/order.api.service.js.map +1 -1
  70. package/dist/api/persona.api.service.d.ts +3 -3
  71. package/dist/api/persona.api.service.d.ts.map +1 -1
  72. package/dist/api/persona.api.service.js +2 -2
  73. package/dist/api/persona.api.service.js.map +1 -1
  74. package/dist/api/postprocessor.api.service.d.ts +8 -9
  75. package/dist/api/postprocessor.api.service.d.ts.map +1 -1
  76. package/dist/api/postprocessor.api.service.js +1 -2
  77. package/dist/api/postprocessor.api.service.js.map +1 -1
  78. package/dist/api/preprocessor.api.service.d.ts +8 -9
  79. package/dist/api/preprocessor.api.service.d.ts.map +1 -1
  80. package/dist/api/preprocessor.api.service.js +1 -2
  81. package/dist/api/preprocessor.api.service.js.map +1 -1
  82. package/dist/api/products.api.service.d.ts +9 -9
  83. package/dist/api/products.api.service.d.ts.map +1 -1
  84. package/dist/api/products.api.service.js +10 -10
  85. package/dist/api/products.api.service.js.map +1 -1
  86. package/dist/api/resource.api.service.d.ts +2 -2
  87. package/dist/api/resource.api.service.js +1 -1
  88. package/dist/api/skills.api.service.d.ts +4 -4
  89. package/dist/api/skills.api.service.d.ts.map +1 -1
  90. package/dist/api/skills.api.service.js +1 -1
  91. package/dist/api/skills.api.service.js.map +1 -1
  92. package/dist/api/tool.api.service.d.ts +2 -2
  93. package/dist/api/tool.api.service.js +1 -1
  94. package/dist/api/unifiedto.api.service.d.ts +3 -3
  95. package/dist/api/unifiedto.api.service.d.ts.map +1 -1
  96. package/dist/api/unifiedto.api.service.js +28 -10
  97. package/dist/api/unifiedto.api.service.js.map +1 -1
  98. package/dist/api/user.data.api.service.d.ts +6 -6
  99. package/dist/api/user.data.api.service.d.ts.map +1 -1
  100. package/dist/api/user.data.api.service.js +5 -5
  101. package/dist/api/user.data.api.service.js.map +1 -1
  102. package/dist/api/webhook.api.service.d.ts +3 -3
  103. package/dist/api/webhook.api.service.d.ts.map +1 -1
  104. package/dist/api/webhook.api.service.js +1 -1
  105. package/dist/api/webhook.api.service.js.map +1 -1
  106. package/dist/api/whatsapp-templates.api.service.d.ts +3 -3
  107. package/dist/api/whatsapp-templates.api.service.js +1 -1
  108. package/dist/api-exports.d.ts +25 -25
  109. package/dist/api-exports.d.ts.map +1 -1
  110. package/dist/api-exports.js +26 -26
  111. package/dist/api-exports.js.map +1 -1
  112. package/dist/cli/command-definitions.d.ts +1 -1
  113. package/dist/cli/command-definitions.d.ts.map +1 -1
  114. package/dist/cli/command-definitions.js +209 -196
  115. package/dist/cli/command-definitions.js.map +1 -1
  116. package/dist/commands/agents.js +2 -2
  117. package/dist/commands/apiKey.js +12 -12
  118. package/dist/commands/channels.d.ts.map +1 -1
  119. package/dist/commands/channels.js +165 -174
  120. package/dist/commands/channels.js.map +1 -1
  121. package/dist/commands/chat-log-probe.d.ts +59 -0
  122. package/dist/commands/chat-log-probe.d.ts.map +1 -0
  123. package/dist/commands/chat-log-probe.js +87 -0
  124. package/dist/commands/chat-log-probe.js.map +1 -0
  125. package/dist/commands/chat.d.ts.map +1 -1
  126. package/dist/commands/chat.js +143 -40
  127. package/dist/commands/chat.js.map +1 -1
  128. package/dist/commands/chatClear.d.ts.map +1 -1
  129. package/dist/commands/chatClear.js +10 -6
  130. package/dist/commands/chatClear.js.map +1 -1
  131. package/dist/commands/compile.d.ts +7 -0
  132. package/dist/commands/compile.d.ts.map +1 -1
  133. package/dist/commands/compile.js +49 -12
  134. package/dist/commands/compile.js.map +1 -1
  135. package/dist/commands/completion.d.ts.map +1 -1
  136. package/dist/commands/completion.js +8 -9
  137. package/dist/commands/completion.js.map +1 -1
  138. package/dist/commands/configure.js +5 -5
  139. package/dist/commands/deploy.d.ts.map +1 -1
  140. package/dist/commands/deploy.js +132 -35
  141. package/dist/commands/deploy.js.map +1 -1
  142. package/dist/commands/destroy.d.ts.map +1 -1
  143. package/dist/commands/destroy.js +27 -17
  144. package/dist/commands/destroy.js.map +1 -1
  145. package/dist/commands/devices.d.ts.map +1 -1
  146. package/dist/commands/devices.js +4 -5
  147. package/dist/commands/devices.js.map +1 -1
  148. package/dist/commands/env.d.ts.map +1 -1
  149. package/dist/commands/env.js +101 -80
  150. package/dist/commands/env.js.map +1 -1
  151. package/dist/commands/features.d.ts.map +1 -1
  152. package/dist/commands/features.js +71 -82
  153. package/dist/commands/features.js.map +1 -1
  154. package/dist/commands/governance.d.ts.map +1 -1
  155. package/dist/commands/governance.js +17 -15
  156. package/dist/commands/governance.js.map +1 -1
  157. package/dist/commands/index.d.ts +37 -36
  158. package/dist/commands/index.d.ts.map +1 -1
  159. package/dist/commands/index.js +37 -36
  160. package/dist/commands/index.js.map +1 -1
  161. package/dist/commands/init.d.ts.map +1 -1
  162. package/dist/commands/init.js +80 -70
  163. package/dist/commands/init.js.map +1 -1
  164. package/dist/commands/integrations.d.ts.map +1 -1
  165. package/dist/commands/integrations.js +373 -341
  166. package/dist/commands/integrations.js.map +1 -1
  167. package/dist/commands/jobs.d.ts.map +1 -1
  168. package/dist/commands/jobs.js +110 -78
  169. package/dist/commands/jobs.js.map +1 -1
  170. package/dist/commands/log-tip.d.ts +79 -0
  171. package/dist/commands/log-tip.d.ts.map +1 -0
  172. package/dist/commands/log-tip.js +83 -0
  173. package/dist/commands/log-tip.js.map +1 -0
  174. package/dist/commands/logs.d.ts.map +1 -1
  175. package/dist/commands/logs.js +166 -198
  176. package/dist/commands/logs.js.map +1 -1
  177. package/dist/commands/marketplace.d.ts.map +1 -1
  178. package/dist/commands/marketplace.js +381 -427
  179. package/dist/commands/marketplace.js.map +1 -1
  180. package/dist/commands/mcp.d.ts.map +1 -1
  181. package/dist/commands/mcp.js +54 -56
  182. package/dist/commands/mcp.js.map +1 -1
  183. package/dist/commands/models.d.ts.map +1 -1
  184. package/dist/commands/models.js +4 -3
  185. package/dist/commands/models.js.map +1 -1
  186. package/dist/commands/persona.d.ts.map +1 -1
  187. package/dist/commands/persona.js +100 -126
  188. package/dist/commands/persona.js.map +1 -1
  189. package/dist/commands/postprocessors.d.ts.map +1 -1
  190. package/dist/commands/postprocessors.js +87 -61
  191. package/dist/commands/postprocessors.js.map +1 -1
  192. package/dist/commands/preprocessors.d.ts.map +1 -1
  193. package/dist/commands/preprocessors.js +87 -61
  194. package/dist/commands/preprocessors.js.map +1 -1
  195. package/dist/commands/production.d.ts.map +1 -1
  196. package/dist/commands/production.js +101 -113
  197. package/dist/commands/production.js.map +1 -1
  198. package/dist/commands/push-helpers.d.ts +42 -0
  199. package/dist/commands/push-helpers.d.ts.map +1 -0
  200. package/dist/commands/push-helpers.js +48 -0
  201. package/dist/commands/push-helpers.js.map +1 -0
  202. package/dist/commands/push.d.ts +2 -0
  203. package/dist/commands/push.d.ts.map +1 -1
  204. package/dist/commands/push.js +388 -124
  205. package/dist/commands/push.js.map +1 -1
  206. package/dist/commands/pushBackup.d.ts.map +1 -1
  207. package/dist/commands/pushBackup.js +8 -4
  208. package/dist/commands/pushBackup.js.map +1 -1
  209. package/dist/commands/resources.d.ts.map +1 -1
  210. package/dist/commands/resources.js +47 -60
  211. package/dist/commands/resources.js.map +1 -1
  212. package/dist/commands/skills.d.ts.map +1 -1
  213. package/dist/commands/skills.js +117 -89
  214. package/dist/commands/skills.js.map +1 -1
  215. package/dist/commands/status.d.ts +14 -0
  216. package/dist/commands/status.d.ts.map +1 -0
  217. package/dist/commands/status.js +731 -0
  218. package/dist/commands/status.js.map +1 -0
  219. package/dist/commands/sync.d.ts.map +1 -1
  220. package/dist/commands/sync.js +70 -30
  221. package/dist/commands/sync.js.map +1 -1
  222. package/dist/commands/telemetry.d.ts.map +1 -1
  223. package/dist/commands/telemetry.js +4 -0
  224. package/dist/commands/telemetry.js.map +1 -1
  225. package/dist/commands/test-output.helpers.d.ts +24 -0
  226. package/dist/commands/test-output.helpers.d.ts.map +1 -0
  227. package/dist/commands/test-output.helpers.js +62 -0
  228. package/dist/commands/test-output.helpers.js.map +1 -0
  229. package/dist/commands/test.d.ts.map +1 -1
  230. package/dist/commands/test.js +291 -121
  231. package/dist/commands/test.js.map +1 -1
  232. package/dist/commands/update.d.ts.map +1 -1
  233. package/dist/commands/update.js +15 -3
  234. package/dist/commands/update.js.map +1 -1
  235. package/dist/commands/webhooks.d.ts.map +1 -1
  236. package/dist/commands/webhooks.js +94 -87
  237. package/dist/commands/webhooks.js.map +1 -1
  238. package/dist/compiler/agent-traverser.d.ts +50 -14
  239. package/dist/compiler/agent-traverser.d.ts.map +1 -1
  240. package/dist/compiler/agent-traverser.js +189 -86
  241. package/dist/compiler/agent-traverser.js.map +1 -1
  242. package/dist/compiler/bundler.d.ts.map +1 -1
  243. package/dist/compiler/bundler.js +5 -5
  244. package/dist/compiler/bundler.js.map +1 -1
  245. package/dist/compiler/compiler.d.ts +32 -0
  246. package/dist/compiler/compiler.d.ts.map +1 -1
  247. package/dist/compiler/compiler.js +154 -28
  248. package/dist/compiler/compiler.js.map +1 -1
  249. package/dist/compiler/index.d.ts +3 -3
  250. package/dist/compiler/index.d.ts.map +1 -1
  251. package/dist/compiler/index.js +3 -3
  252. package/dist/compiler/index.js.map +1 -1
  253. package/dist/compiler/plugins/agent.plugin.d.ts.map +1 -1
  254. package/dist/compiler/plugins/agent.plugin.js +2 -4
  255. package/dist/compiler/plugins/agent.plugin.js.map +1 -1
  256. package/dist/compiler/plugins/base.d.ts +21 -0
  257. package/dist/compiler/plugins/base.d.ts.map +1 -1
  258. package/dist/compiler/plugins/base.js +13 -3
  259. package/dist/compiler/plugins/base.js.map +1 -1
  260. package/dist/compiler/plugins/device-trigger.plugin.d.ts.map +1 -1
  261. package/dist/compiler/plugins/device-trigger.plugin.js +8 -4
  262. package/dist/compiler/plugins/device-trigger.plugin.js.map +1 -1
  263. package/dist/compiler/plugins/device.plugin.d.ts.map +1 -1
  264. package/dist/compiler/plugins/device.plugin.js +4 -4
  265. package/dist/compiler/plugins/device.plugin.js.map +1 -1
  266. package/dist/compiler/plugins/job.plugin.d.ts.map +1 -1
  267. package/dist/compiler/plugins/job.plugin.js +15 -11
  268. package/dist/compiler/plugins/job.plugin.js.map +1 -1
  269. package/dist/compiler/plugins/mcp-server.plugin.d.ts.map +1 -1
  270. package/dist/compiler/plugins/mcp-server.plugin.js +10 -4
  271. package/dist/compiler/plugins/mcp-server.plugin.js.map +1 -1
  272. package/dist/compiler/plugins/registry.js +2 -2
  273. package/dist/compiler/plugins/registry.js.map +1 -1
  274. package/dist/compiler/plugins/skill.plugin.d.ts +35 -9
  275. package/dist/compiler/plugins/skill.plugin.d.ts.map +1 -1
  276. package/dist/compiler/plugins/skill.plugin.js +129 -87
  277. package/dist/compiler/plugins/skill.plugin.js.map +1 -1
  278. package/dist/compiler/plugins/tool.plugin.d.ts.map +1 -1
  279. package/dist/compiler/plugins/tool.plugin.js +13 -9
  280. package/dist/compiler/plugins/tool.plugin.js.map +1 -1
  281. package/dist/compiler/plugins/webhook.plugin.d.ts.map +1 -1
  282. package/dist/compiler/plugins/webhook.plugin.js +7 -5
  283. package/dist/compiler/plugins/webhook.plugin.js.map +1 -1
  284. package/dist/compiler/source-writer.d.ts.map +1 -1
  285. package/dist/compiler/source-writer.js +2 -4
  286. package/dist/compiler/source-writer.js.map +1 -1
  287. package/dist/compiler/types.d.ts +33 -0
  288. package/dist/compiler/types.d.ts.map +1 -1
  289. package/dist/compiler/types.js.map +1 -1
  290. package/dist/compiler/utils/ast-helpers.d.ts +1 -16
  291. package/dist/compiler/utils/ast-helpers.d.ts.map +1 -1
  292. package/dist/compiler/utils/ast-helpers.js +14 -38
  293. package/dist/compiler/utils/ast-helpers.js.map +1 -1
  294. package/dist/compiler/utils/common.d.ts +14 -0
  295. package/dist/compiler/utils/common.d.ts.map +1 -1
  296. package/dist/compiler/utils/common.js +39 -11
  297. package/dist/compiler/utils/common.js.map +1 -1
  298. package/dist/compiler/utils/file-discovery.d.ts.map +1 -1
  299. package/dist/compiler/utils/file-discovery.js +2 -10
  300. package/dist/compiler/utils/file-discovery.js.map +1 -1
  301. package/dist/compiler/utils/path-resolver.d.ts +67 -10
  302. package/dist/compiler/utils/path-resolver.d.ts.map +1 -1
  303. package/dist/compiler/utils/path-resolver.js +120 -24
  304. package/dist/compiler/utils/path-resolver.js.map +1 -1
  305. package/dist/compiler/utils/reference-resolver.d.ts +196 -0
  306. package/dist/compiler/utils/reference-resolver.d.ts.map +1 -0
  307. package/dist/compiler/utils/reference-resolver.js +1026 -0
  308. package/dist/compiler/utils/reference-resolver.js.map +1 -0
  309. package/dist/compiler/utils/schema-converter.d.ts +25 -0
  310. package/dist/compiler/utils/schema-converter.d.ts.map +1 -1
  311. package/dist/compiler/utils/schema-converter.js +80 -4
  312. package/dist/compiler/utils/schema-converter.js.map +1 -1
  313. package/dist/compiler/utils/workspace.d.ts +35 -0
  314. package/dist/compiler/utils/workspace.d.ts.map +1 -0
  315. package/dist/compiler/utils/workspace.js +121 -0
  316. package/dist/compiler/utils/workspace.js.map +1 -0
  317. package/dist/compiler/utils/zod-runtime.mjs +5334 -0
  318. package/dist/config/compile.constants.d.ts.map +1 -1
  319. package/dist/config/compile.constants.js +3 -1
  320. package/dist/config/compile.constants.js.map +1 -1
  321. package/dist/config/constants.d.ts.map +1 -1
  322. package/dist/config/constants.js +1 -5
  323. package/dist/config/constants.js.map +1 -1
  324. package/dist/errors/auth.error.d.ts.map +1 -1
  325. package/dist/errors/auth.error.js +3 -5
  326. package/dist/errors/auth.error.js.map +1 -1
  327. package/dist/errors/index.d.ts +1 -1
  328. package/dist/errors/index.js +1 -1
  329. package/dist/index.js +9 -8
  330. package/dist/index.js.map +1 -1
  331. package/dist/instances/basket.instance.d.ts +3 -3
  332. package/dist/instances/basket.instance.d.ts.map +1 -1
  333. package/dist/instances/basket.instance.js +26 -8
  334. package/dist/instances/basket.instance.js.map +1 -1
  335. package/dist/instances/data.entry.instance.d.ts +2 -2
  336. package/dist/instances/data.entry.instance.d.ts.map +1 -1
  337. package/dist/instances/data.entry.instance.js +5 -5
  338. package/dist/instances/data.entry.instance.js.map +1 -1
  339. package/dist/instances/order.instance.d.ts +2 -2
  340. package/dist/instances/order.instance.d.ts.map +1 -1
  341. package/dist/instances/order.instance.js +20 -9
  342. package/dist/instances/order.instance.js.map +1 -1
  343. package/dist/instances/product.instance.d.ts +1 -1
  344. package/dist/instances/product.instance.d.ts.map +1 -1
  345. package/dist/instances/product.instance.js +3 -3
  346. package/dist/instances/product.instance.js.map +1 -1
  347. package/dist/instances/product.pagination.instance.d.ts +2 -2
  348. package/dist/instances/product.pagination.instance.d.ts.map +1 -1
  349. package/dist/instances/product.pagination.instance.js +6 -7
  350. package/dist/instances/product.pagination.instance.js.map +1 -1
  351. package/dist/instances/product.search.instance.d.ts +3 -3
  352. package/dist/instances/product.search.instance.d.ts.map +1 -1
  353. package/dist/instances/product.search.instance.js +3 -4
  354. package/dist/instances/product.search.instance.js.map +1 -1
  355. package/dist/instances/user.instance.d.ts +3 -3
  356. package/dist/instances/user.instance.d.ts.map +1 -1
  357. package/dist/instances/user.instance.js +19 -36
  358. package/dist/instances/user.instance.js.map +1 -1
  359. package/dist/interfaces/agent.d.ts +8 -8
  360. package/dist/interfaces/agent.d.ts.map +1 -1
  361. package/dist/interfaces/backup.d.ts +19 -1
  362. package/dist/interfaces/backup.d.ts.map +1 -1
  363. package/dist/interfaces/device-triggers.d.ts +0 -2
  364. package/dist/interfaces/device-triggers.d.ts.map +1 -1
  365. package/dist/interfaces/devices.d.ts +0 -1
  366. package/dist/interfaces/devices.d.ts.map +1 -1
  367. package/dist/interfaces/index.d.ts +8 -8
  368. package/dist/interfaces/index.d.ts.map +1 -1
  369. package/dist/interfaces/jobs.d.ts +2 -3
  370. package/dist/interfaces/jobs.d.ts.map +1 -1
  371. package/dist/interfaces/logs.d.ts +7 -4
  372. package/dist/interfaces/logs.d.ts.map +1 -1
  373. package/dist/interfaces/message.d.ts +3 -3
  374. package/dist/interfaces/message.d.ts.map +1 -1
  375. package/dist/interfaces/orders.d.ts +1 -1
  376. package/dist/interfaces/webhooks.d.ts +2 -2
  377. package/dist/interfaces/webhooks.d.ts.map +1 -1
  378. package/dist/primitives/agent.handler.d.ts.map +1 -1
  379. package/dist/primitives/agent.handler.js +1 -1
  380. package/dist/primitives/agent.handler.js.map +1 -1
  381. package/dist/primitives/base.handler.d.ts +12 -2
  382. package/dist/primitives/base.handler.d.ts.map +1 -1
  383. package/dist/primitives/base.handler.js +104 -73
  384. package/dist/primitives/base.handler.js.map +1 -1
  385. package/dist/primitives/device-trigger.handler.d.ts +1 -1
  386. package/dist/primitives/device-trigger.handler.d.ts.map +1 -1
  387. package/dist/primitives/device-trigger.handler.js +2 -3
  388. package/dist/primitives/device-trigger.handler.js.map +1 -1
  389. package/dist/primitives/device.handler.d.ts +1 -1
  390. package/dist/primitives/device.handler.d.ts.map +1 -1
  391. package/dist/primitives/device.handler.js +2 -3
  392. package/dist/primitives/device.handler.js.map +1 -1
  393. package/dist/primitives/index.d.ts +1 -1
  394. package/dist/primitives/index.d.ts.map +1 -1
  395. package/dist/primitives/index.js +2 -3
  396. package/dist/primitives/index.js.map +1 -1
  397. package/dist/primitives/job.handler.d.ts +6 -1
  398. package/dist/primitives/job.handler.d.ts.map +1 -1
  399. package/dist/primitives/job.handler.js +9 -3
  400. package/dist/primitives/job.handler.js.map +1 -1
  401. package/dist/primitives/mcp-server.handler.d.ts.map +1 -1
  402. package/dist/primitives/mcp-server.handler.js +2 -2
  403. package/dist/primitives/mcp-server.handler.js.map +1 -1
  404. package/dist/primitives/postprocessor.handler.d.ts.map +1 -1
  405. package/dist/primitives/postprocessor.handler.js.map +1 -1
  406. package/dist/primitives/preprocessor.handler.d.ts +1 -1
  407. package/dist/primitives/preprocessor.handler.d.ts.map +1 -1
  408. package/dist/primitives/preprocessor.handler.js +2 -3
  409. package/dist/primitives/preprocessor.handler.js.map +1 -1
  410. package/dist/primitives/skill.handler.d.ts +1 -1
  411. package/dist/primitives/skill.handler.d.ts.map +1 -1
  412. package/dist/primitives/skill.handler.js +34 -13
  413. package/dist/primitives/skill.handler.js.map +1 -1
  414. package/dist/primitives/types.d.ts +1 -1
  415. package/dist/primitives/types.d.ts.map +1 -1
  416. package/dist/primitives/types.js.map +1 -1
  417. package/dist/primitives/webhook.handler.d.ts +3 -2
  418. package/dist/primitives/webhook.handler.d.ts.map +1 -1
  419. package/dist/primitives/webhook.handler.js +9 -4
  420. package/dist/primitives/webhook.handler.js.map +1 -1
  421. package/dist/services/analytics.d.ts.map +1 -1
  422. package/dist/services/analytics.js +4 -5
  423. package/dist/services/analytics.js.map +1 -1
  424. package/dist/services/auth.d.ts +9 -1
  425. package/dist/services/auth.d.ts.map +1 -1
  426. package/dist/services/auth.js +26 -7
  427. package/dist/services/auth.js.map +1 -1
  428. package/dist/services/sandbox.service.d.ts.map +1 -1
  429. package/dist/services/sandbox.service.js +132 -80
  430. package/dist/services/sandbox.service.js.map +1 -1
  431. package/dist/types/api-contracts.d.ts +4 -4
  432. package/dist/types/api-contracts.d.ts.map +1 -1
  433. package/dist/types/index.d.ts +2 -2
  434. package/dist/types/index.d.ts.map +1 -1
  435. package/dist/types/index.js.map +1 -1
  436. package/dist/types/skill.d.ts +7 -7
  437. package/dist/types/skill.d.ts.map +1 -1
  438. package/dist/types/skill.js +2 -2
  439. package/dist/types/skill.js.map +1 -1
  440. package/dist/types/tool-validation.js.map +1 -1
  441. package/dist/types/yaml.types.js +0 -1
  442. package/dist/types/yaml.types.js.map +1 -1
  443. package/dist/utils/aliases.d.ts +7 -0
  444. package/dist/utils/aliases.d.ts.map +1 -0
  445. package/dist/utils/aliases.js +492 -0
  446. package/dist/utils/aliases.js.map +1 -0
  447. package/dist/utils/artifact-loader.d.ts +9 -0
  448. package/dist/utils/artifact-loader.d.ts.map +1 -1
  449. package/dist/utils/artifact-loader.js +16 -6
  450. package/dist/utils/artifact-loader.js.map +1 -1
  451. package/dist/utils/auth-flows.d.ts.map +1 -1
  452. package/dist/utils/auth-flows.js +54 -54
  453. package/dist/utils/auth-flows.js.map +1 -1
  454. package/dist/utils/backup-helpers.d.ts +24 -0
  455. package/dist/utils/backup-helpers.d.ts.map +1 -1
  456. package/dist/utils/backup-helpers.js +102 -22
  457. package/dist/utils/backup-helpers.js.map +1 -1
  458. package/dist/utils/bundle-upload.d.ts +42 -0
  459. package/dist/utils/bundle-upload.d.ts.map +1 -0
  460. package/dist/utils/bundle-upload.js +90 -0
  461. package/dist/utils/bundle-upload.js.map +1 -0
  462. package/dist/utils/chat-attachments.js +1 -1
  463. package/dist/utils/chat-attachments.js.map +1 -1
  464. package/dist/utils/cli.d.ts +24 -6
  465. package/dist/utils/cli.d.ts.map +1 -1
  466. package/dist/utils/cli.js +26 -14
  467. package/dist/utils/cli.js.map +1 -1
  468. package/dist/utils/command-utils.d.ts.map +1 -1
  469. package/dist/utils/command-utils.js +4 -4
  470. package/dist/utils/command-utils.js.map +1 -1
  471. package/dist/utils/deploy-helpers.d.ts.map +1 -1
  472. package/dist/utils/deploy-helpers.js +13 -13
  473. package/dist/utils/deploy-helpers.js.map +1 -1
  474. package/dist/utils/env-loader.utils.d.ts +1 -1
  475. package/dist/utils/env-loader.utils.d.ts.map +1 -1
  476. package/dist/utils/env-loader.utils.js +15 -22
  477. package/dist/utils/env-loader.utils.js.map +1 -1
  478. package/dist/utils/files.d.ts.map +1 -1
  479. package/dist/utils/files.js +23 -13
  480. package/dist/utils/files.js.map +1 -1
  481. package/dist/utils/hints.d.ts +81 -0
  482. package/dist/utils/hints.d.ts.map +1 -0
  483. package/dist/utils/hints.js +81 -0
  484. package/dist/utils/hints.js.map +1 -0
  485. package/dist/utils/init-agent.d.ts.map +1 -1
  486. package/dist/utils/init-agent.js +18 -20
  487. package/dist/utils/init-agent.js.map +1 -1
  488. package/dist/utils/init-helpers.d.ts.map +1 -1
  489. package/dist/utils/init-helpers.js +11 -11
  490. package/dist/utils/init-helpers.js.map +1 -1
  491. package/dist/utils/init-prompts.d.ts.map +1 -1
  492. package/dist/utils/init-prompts.js +34 -36
  493. package/dist/utils/init-prompts.js.map +1 -1
  494. package/dist/utils/prompt-handler.js +1 -1
  495. package/dist/utils/prompt-handler.js.map +1 -1
  496. package/dist/utils/sandbox-storage.d.ts.map +1 -1
  497. package/dist/utils/sandbox-storage.js.map +1 -1
  498. package/dist/utils/sandbox.d.ts +1 -1
  499. package/dist/utils/sandbox.d.ts.map +1 -1
  500. package/dist/utils/sandbox.js +107 -106
  501. package/dist/utils/sandbox.js.map +1 -1
  502. package/dist/utils/semver.js +1 -1
  503. package/dist/utils/semver.js.map +1 -1
  504. package/dist/utils/suggest.d.ts +3 -0
  505. package/dist/utils/suggest.d.ts.map +1 -0
  506. package/dist/utils/suggest.js +32 -0
  507. package/dist/utils/suggest.js.map +1 -0
  508. package/dist/utils/sync-display.d.ts.map +1 -1
  509. package/dist/utils/sync-display.js +15 -13
  510. package/dist/utils/sync-display.js.map +1 -1
  511. package/dist/utils/sync-fetch.d.ts.map +1 -1
  512. package/dist/utils/sync-fetch.js +33 -24
  513. package/dist/utils/sync-fetch.js.map +1 -1
  514. package/dist/utils/version-check.js +1 -1
  515. package/dist/utils/version-check.js.map +1 -1
  516. package/dist/utils/write-info.d.ts +9 -0
  517. package/dist/utils/write-info.d.ts.map +1 -0
  518. package/dist/utils/write-info.js +11 -0
  519. package/dist/utils/write-info.js.map +1 -0
  520. package/docs/README.md +1 -1
  521. package/node_modules/@lua/shared-types/dist/index.d.mts +76 -2
  522. package/node_modules/@lua/shared-types/dist/index.d.ts +76 -2
  523. package/node_modules/@lua/shared-types/dist/index.js +27 -0
  524. package/node_modules/@lua/shared-types/dist/index.mjs +24 -0
  525. package/node_modules/@lua/shared-types/src/ai-generate.types.ts +1 -6
  526. package/node_modules/@lua/shared-types/src/ai-generate.utils.ts +1 -4
  527. package/node_modules/@lua/shared-types/src/channel.type.ts +1 -0
  528. package/node_modules/@lua/shared-types/src/chat-stream.types.ts +11 -0
  529. package/node_modules/@lua/shared-types/src/client-tools.types.ts +47 -0
  530. package/node_modules/@lua/shared-types/src/device.types.ts +6 -6
  531. package/node_modules/@lua/shared-types/src/index.ts +3 -0
  532. package/node_modules/@lua/shared-types/src/sandbox-contract.ts +26 -5
  533. package/node_modules/@lua/shared-types/src/vm-execution-log.types.ts +41 -0
  534. package/package.json +10 -6
  535. package/scripts/build-vendor.mjs +53 -0
  536. package/scripts/vendor-entry.mjs +11 -0
  537. package/template/QUICKSTART.md +33 -33
  538. package/template/README.md +35 -34
  539. package/template/examples/README.md +44 -38
  540. package/template/examples/jobs/AbandonedBasketProcessorJob.ts +30 -31
  541. package/template/examples/jobs/DailyCleanupJob.ts +17 -18
  542. package/template/examples/jobs/DataMigrationJob.ts +18 -23
  543. package/template/examples/jobs/HealthCheckJob.ts +13 -14
  544. package/template/examples/postprocessors/modifyResponse.ts +14 -15
  545. package/template/examples/preprocessors/messageMatching.ts +28 -29
  546. package/template/examples/services/ApiService.ts +68 -64
  547. package/template/examples/services/GetWeather.ts +39 -33
  548. package/template/examples/skills/basket.skill.ts +27 -7
  549. package/template/examples/skills/product.skill.ts +21 -8
  550. package/template/examples/skills/tools/BasketTool.ts +97 -98
  551. package/template/examples/skills/tools/CreateInlineJob.ts +38 -36
  552. package/template/examples/skills/tools/CreatePostTool.ts +27 -28
  553. package/template/examples/skills/tools/CustomDataTool.ts +72 -67
  554. package/template/examples/skills/tools/GameScoreTrackerTool.ts +72 -78
  555. package/template/examples/skills/tools/GetWeatherTool.ts +43 -45
  556. package/template/examples/skills/tools/OrderTool.ts +58 -58
  557. package/template/examples/skills/tools/PaymentTool.ts +43 -43
  558. package/template/examples/skills/tools/PremiumFeatureTool.ts +81 -79
  559. package/template/examples/skills/tools/ProductsTool.ts +68 -69
  560. package/template/examples/skills/tools/SmartBasketTool.ts +43 -44
  561. package/template/examples/skills/tools/UserDataTool.ts +97 -98
  562. package/template/examples/skills/user.skill.ts +7 -8
  563. package/template/examples/webhooks/FileUploadWebhook.ts +38 -31
  564. package/template/examples/webhooks/PaymentWebhook.ts +23 -22
  565. package/template/examples/webhooks/UserEventWebhook.ts +16 -19
  566. package/template/lua.skill.yaml +2 -2
  567. package/template/package.json +1 -1
  568. package/template/src/index.ts +28 -28
@@ -23,8 +23,9 @@ import { safePrompt } from '../utils/prompt-handler.js';
23
23
  import { initializeCommand } from '../utils/command-utils.js';
24
24
  import DeveloperApi from '../api/developer.api.service.js';
25
25
  import UnifiedToApi from '../api/unifiedto.api.service.js';
26
- import { fetchServersCore, activateServerCore, deactivateServerCore, } from './mcp.js';
26
+ import { fetchServersCore, activateServerCore, deactivateServerCore } from './mcp.js';
27
27
  import { trackEvent } from '../services/analytics.js';
28
+ import { validateOrSuggest } from '../utils/aliases.js';
28
29
  // ─────────────────────────────────────────────────────────────────────────────
29
30
  // Configuration
30
31
  // ─────────────────────────────────────────────────────────────────────────────
@@ -73,9 +74,7 @@ function startCallbackServer(timeoutMs = 300000) {
73
74
  resolved = true;
74
75
  if (error) {
75
76
  // Unified.to redirects to failure_redirect with ?error=<oauth_error>&log_id=<trace_id>
76
- const logIdHtml = logId
77
- ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${logId}</code></p>`
78
- : '';
77
+ const logIdHtml = logId ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${logId}</code></p>` : '';
79
78
  res.writeHead(200, { 'Content-Type': 'text/html' });
80
79
  res.end(`
81
80
  <!DOCTYPE html>
@@ -145,8 +144,8 @@ export async function integrationsCommand(action, subaction, cmdObj) {
145
144
  const { agentId, apiKey, userData } = await initializeCommand({ showProgress: false, validateAuth: true });
146
145
  const userId = userData?.admin?.userId;
147
146
  if (!userId) {
148
- console.error("āŒ Failed to get user ID from authentication.");
149
- throw new Error("Failed to get user ID from authentication.");
147
+ console.error('āŒ Failed to get user ID from authentication.');
148
+ throw new Error('Failed to get user ID from authentication.');
150
149
  }
151
150
  const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
152
151
  const unifiedToApi = new UnifiedToApi(BASE_URLS.API, apiKey);
@@ -171,13 +170,13 @@ export async function integrationsCommand(action, subaction, cmdObj) {
171
170
  integration_type: cmdObj?.integration || null,
172
171
  non_interactive: !!action,
173
172
  });
174
- }, "integrations");
173
+ }, 'integrations');
175
174
  }
176
175
  // ─────────────────────────────────────────────────────────────────────────────
177
176
  // Non-Interactive Mode
178
177
  // ─────────────────────────────────────────────────────────────────────────────
179
178
  async function executeNonInteractive(context, action, cmdOptions) {
180
- const normalizedAction = action.toLowerCase();
179
+ const normalizedAction = validateOrSuggest('integrations.action', action);
181
180
  // Extract typed options
182
181
  const options = {
183
182
  integration: cmdOptions?.integration,
@@ -198,9 +197,9 @@ async function executeNonInteractive(context, action, cmdOptions) {
198
197
  break;
199
198
  case 'update':
200
199
  if (!options.integration) {
201
- console.error("āŒ --integration is required for update");
200
+ console.error('āŒ --integration is required for update');
202
201
  console.log("\nšŸ’” Run 'lua integrations list' to see connected integrations");
203
- throw new Error("--integration is required for update");
202
+ throw new Error('--integration is required for update');
204
203
  }
205
204
  await updateConnectionFlow(context, options);
206
205
  break;
@@ -215,18 +214,18 @@ async function executeNonInteractive(context, action, cmdOptions) {
215
214
  // Integration type can be passed as positional arg (info <type>) or as --integration flag
216
215
  const infoIntegrationType = options.integration || cmdOptions?._?.[0];
217
216
  if (!infoIntegrationType) {
218
- console.error("āŒ Integration type is required");
219
- console.log("\nUsage: lua integrations info <type>");
220
- console.log(" lua integrations info <type> --json");
221
- throw new Error("Integration type is required");
217
+ console.error('āŒ Integration type is required');
218
+ console.log('\nUsage: lua integrations info <type>');
219
+ console.log(' lua integrations info <type> --json');
220
+ throw new Error('Integration type is required');
222
221
  }
223
222
  await showIntegrationInfo(context, infoIntegrationType, jsonOutput);
224
223
  break;
225
224
  case 'disconnect':
226
225
  if (!options.connectionId) {
227
- console.error("āŒ --connection-id is required for disconnect");
226
+ console.error('āŒ --connection-id is required for disconnect');
228
227
  console.log("\nšŸ’” Run 'lua integrations list' to see connection IDs");
229
- throw new Error("--connection-id is required for disconnect");
228
+ throw new Error('--connection-id is required for disconnect');
230
229
  }
231
230
  await disconnectIntegration(context, options.connectionId);
232
231
  break;
@@ -239,7 +238,7 @@ async function executeNonInteractive(context, action, cmdOptions) {
239
238
  default:
240
239
  console.error(`āŒ Invalid action: "${action}"`);
241
240
  showUsage();
242
- throw new Error("Invalid action:");
241
+ throw new Error('Invalid action:');
243
242
  }
244
243
  }
245
244
  // ─────────────────────────────────────────────────────────────────────────────
@@ -248,9 +247,9 @@ async function executeNonInteractive(context, action, cmdOptions) {
248
247
  async function interactiveIntegrationsManagement(context) {
249
248
  let continueManaging = true;
250
249
  while (continueManaging) {
251
- console.log("\n" + "=".repeat(60));
252
- console.log("šŸ”— Integrations");
253
- console.log("=".repeat(60) + "\n");
250
+ console.log('\n' + '='.repeat(60));
251
+ console.log('šŸ”— Integrations');
252
+ console.log('='.repeat(60) + '\n');
254
253
  const actionAnswer = await safePrompt([
255
254
  {
256
255
  type: 'list',
@@ -264,9 +263,9 @@ async function interactiveIntegrationsManagement(context) {
264
263
  { name: 'šŸ”” Manage triggers', value: 'webhooks' },
265
264
  { name: 'šŸ”Œ Manage MCP servers', value: 'mcp' },
266
265
  { name: 'šŸ—‘ļø Disconnect an integration', value: 'disconnect' },
267
- { name: 'āŒ Exit', value: 'exit' }
268
- ]
269
- }
266
+ { name: 'āŒ Exit', value: 'exit' },
267
+ ],
268
+ },
270
269
  ]);
271
270
  if (!actionAnswer)
272
271
  return;
@@ -295,7 +294,7 @@ async function interactiveIntegrationsManagement(context) {
295
294
  break;
296
295
  case 'exit':
297
296
  continueManaging = false;
298
- console.log("\nšŸ‘‹ Goodbye!\n");
297
+ console.log('\nšŸ‘‹ Goodbye!\n');
299
298
  break;
300
299
  }
301
300
  }
@@ -304,15 +303,15 @@ async function interactiveIntegrationsManagement(context) {
304
303
  // List Available Integrations
305
304
  // ─────────────────────────────────────────────────────────────────────────────
306
305
  async function listAvailableIntegrations(context) {
307
- writeProgress("šŸ”„ Fetching available integrations...");
306
+ writeProgress('šŸ”„ Fetching available integrations...');
308
307
  try {
309
308
  const integrations = await fetchAvailableIntegrations(context.unifiedToApi);
310
- console.log("\n" + "=".repeat(60));
311
- console.log("šŸ”Œ Available Integrations");
312
- console.log("=".repeat(60) + "\n");
309
+ console.log('\n' + '='.repeat(60));
310
+ console.log('šŸ”Œ Available Integrations');
311
+ console.log('='.repeat(60) + '\n');
313
312
  if (integrations.length === 0) {
314
- console.log("ā„¹ļø No integrations available.");
315
- console.log("šŸ’” Contact support to enable integrations for your workspace.\n");
313
+ console.log('ā„¹ļø No integrations available.');
314
+ console.log('šŸ’” Contact support to enable integrations for your workspace.\n');
316
315
  return;
317
316
  }
318
317
  // Group by category
@@ -325,15 +324,15 @@ async function listAvailableIntegrations(context) {
325
324
  }
326
325
  for (const [category, items] of Object.entries(byCategory)) {
327
326
  console.log(`šŸ“ ${category.toUpperCase()}`);
328
- items.forEach(i => {
327
+ items.forEach((i) => {
329
328
  const authBadge = i.authSupport === 'oauth' ? 'šŸ”' : i.authSupport === 'token' ? 'šŸ”‘' : 'šŸ”šŸ”‘';
330
329
  console.log(` ${authBadge} ${i.name} (${i.value})`);
331
330
  });
332
331
  console.log();
333
332
  }
334
- console.log("=".repeat(60));
333
+ console.log('='.repeat(60));
335
334
  console.log(`Total: ${integrations.length} integration(s) available`);
336
- console.log("šŸ” = OAuth šŸ”‘ = API Key/Token šŸ”šŸ”‘ = Both\n");
335
+ console.log('šŸ” = OAuth šŸ”‘ = API Key/Token šŸ”šŸ”‘ = Both\n');
337
336
  }
338
337
  catch (error) {
339
338
  writeError(`āŒ Failed to fetch integrations: ${error.message}`);
@@ -350,7 +349,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
350
349
  try {
351
350
  // Fetch integration details
352
351
  const integrations = await fetchAvailableIntegrations(context.unifiedToApi);
353
- const integration = integrations.find(i => i.value === integrationType);
352
+ const integration = integrations.find((i) => i.value === integrationType);
354
353
  if (!integration) {
355
354
  if (jsonOutput) {
356
355
  console.log(JSON.stringify({ error: `Integration not found: ${integrationType}` }));
@@ -358,9 +357,9 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
358
357
  else {
359
358
  console.error(`āŒ Integration not found: ${integrationType}`);
360
359
  console.log('\nAvailable integrations:');
361
- integrations.forEach(i => console.log(` - ${i.value} (${i.name})`));
360
+ integrations.forEach((i) => console.log(` - ${i.value} (${i.name})`));
362
361
  }
363
- throw new Error("Operation failed");
362
+ throw new Error('Operation failed');
364
363
  }
365
364
  // Fetch available webhook events for this integration
366
365
  let webhookEvents = [];
@@ -383,7 +382,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
383
382
  oauthConfigured: integration.oauthConfigured,
384
383
  oauthScopes: integration.oauthScopes || [],
385
384
  tokenFields: integration.tokenFields || [],
386
- webhookEvents: webhookEvents.map(e => ({
385
+ webhookEvents: webhookEvents.map((e) => ({
387
386
  trigger: `${e.objectType}.${e.event}`,
388
387
  objectType: e.objectType,
389
388
  event: e.event,
@@ -401,9 +400,9 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
401
400
  }
402
401
  else {
403
402
  // Human-readable output
404
- console.log("\n" + "=".repeat(60));
403
+ console.log('\n' + '='.repeat(60));
405
404
  console.log(`šŸ“‹ Integration: ${integration.name}`);
406
- console.log("=".repeat(60));
405
+ console.log('='.repeat(60));
407
406
  console.log(`\n Type: ${integration.value}`);
408
407
  console.log(` Categories: ${integration.categories.join(', ')}`);
409
408
  console.log(` Auth Support: ${integration.authSupport}`);
@@ -411,7 +410,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
411
410
  // OAuth Scopes
412
411
  if (integration.oauthScopes && integration.oauthScopes.length > 0) {
413
412
  console.log('\n OAuth Scopes:');
414
- integration.oauthScopes.forEach(s => {
413
+ integration.oauthScopes.forEach((s) => {
415
414
  if (s.friendlyLabel) {
416
415
  console.log(` - ${s.friendlyLabel} (${s.unifiedScope})`);
417
416
  if (s.friendlyDescription) {
@@ -426,7 +425,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
426
425
  // Token Fields
427
426
  if (integration.tokenFields && integration.tokenFields.length > 0) {
428
427
  console.log('\n Token Fields:');
429
- integration.tokenFields.forEach(f => {
428
+ integration.tokenFields.forEach((f) => {
430
429
  console.log(` - ${f.name}`);
431
430
  if (f.instructions) {
432
431
  console.log(` šŸ’” ${f.instructions}`);
@@ -436,15 +435,15 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
436
435
  // Webhook Events/Triggers
437
436
  if (webhookEvents.length > 0) {
438
437
  console.log('\n Available Triggers:');
439
- webhookEvents.forEach(e => {
438
+ webhookEvents.forEach((e) => {
440
439
  console.log(` - ${e.objectType}.${e.event} [${e.webhookType}] - ${e.friendlyDescription}`);
441
440
  });
442
441
  }
443
442
  else {
444
443
  console.log('\n Available Triggers: None');
445
444
  }
446
- console.log("\n" + "=".repeat(60));
447
- console.log("\nšŸ’” Use with non-interactive commands:");
445
+ console.log('\n' + '='.repeat(60));
446
+ console.log('\nšŸ’” Use with non-interactive commands:');
448
447
  console.log(` lua integrations connect --integration ${integrationType} --auth-method oauth --scopes all`);
449
448
  if (webhookEvents.length > 0) {
450
449
  const exampleTrigger = `${webhookEvents[0].objectType}.${webhookEvents[0].event}`;
@@ -460,7 +459,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
460
459
  else {
461
460
  writeError(`āŒ Failed to get integration info: ${error.message}`);
462
461
  }
463
- throw new Error("Operation failed");
462
+ throw new Error('Operation failed');
464
463
  }
465
464
  }
466
465
  // ─────────────────────────────────────────────────────────────────────────────
@@ -468,7 +467,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
468
467
  // ─────────────────────────────────────────────────────────────────────────────
469
468
  async function connectIntegrationFlow(context, options = {}) {
470
469
  // Step 1: Fetch available integrations (API excludes already-connected types)
471
- writeProgress("šŸ”„ Fetching integrations...");
470
+ writeProgress('šŸ”„ Fetching integrations...');
472
471
  let availableIntegrations;
473
472
  try {
474
473
  availableIntegrations = await fetchAvailableIntegrations(context.unifiedToApi, context.agentId);
@@ -478,7 +477,7 @@ async function connectIntegrationFlow(context, options = {}) {
478
477
  return;
479
478
  }
480
479
  if (availableIntegrations.length === 0) {
481
- writeInfo("All available integrations are already connected (or none are enabled).");
480
+ writeInfo('All available integrations are already connected (or none are enabled).');
482
481
  console.log("šŸ’” Use 'lua integrations update' to change scopes on an existing connection.\n");
483
482
  return;
484
483
  }
@@ -486,16 +485,18 @@ async function connectIntegrationFlow(context, options = {}) {
486
485
  // Step 2: Select integration (with search/filter support)
487
486
  let selectedIntegration;
488
487
  if (options.integration) {
489
- selectedIntegration = availableIntegrations.find(i => i.value === options.integration);
488
+ selectedIntegration = availableIntegrations.find((i) => i.value === options.integration);
490
489
  if (!selectedIntegration) {
491
490
  // Not in available list — either already connected or doesn't exist
492
491
  console.error(`āŒ Integration "${options.integration}" not found or already connected.`);
493
- console.log("šŸ’” If already connected, use 'lua integrations update --integration " + options.integration + "' to change scopes.");
492
+ console.log("šŸ’” If already connected, use 'lua integrations update --integration " +
493
+ options.integration +
494
+ "' to change scopes.");
494
495
  if (availableIntegrations.length > 0) {
495
496
  console.log('\nAvailable integrations to connect:');
496
- availableIntegrations.forEach(i => console.log(` - ${i.value} (${i.name})`));
497
+ availableIntegrations.forEach((i) => console.log(` - ${i.value} (${i.name})`));
497
498
  }
498
- throw new Error("Integration");
499
+ throw new Error('Integration');
499
500
  }
500
501
  }
501
502
  else {
@@ -505,7 +506,7 @@ async function connectIntegrationFlow(context, options = {}) {
505
506
  type: 'input',
506
507
  name: 'searchTerm',
507
508
  message: 'Search integrations (or press Enter to browse all):',
508
- }
509
+ },
509
510
  ]);
510
511
  if (!searchAnswer)
511
512
  return;
@@ -513,9 +514,9 @@ async function connectIntegrationFlow(context, options = {}) {
513
514
  let filteredIntegrations = availableIntegrations;
514
515
  if (searchAnswer.searchTerm.trim()) {
515
516
  const searchLower = searchAnswer.searchTerm.toLowerCase().trim();
516
- filteredIntegrations = availableIntegrations.filter(i => i.name.toLowerCase().includes(searchLower) ||
517
+ filteredIntegrations = availableIntegrations.filter((i) => i.name.toLowerCase().includes(searchLower) ||
517
518
  i.value.toLowerCase().includes(searchLower) ||
518
- i.categories.some(c => c.toLowerCase().includes(searchLower)));
519
+ i.categories.some((c) => c.toLowerCase().includes(searchLower)));
519
520
  if (filteredIntegrations.length === 0) {
520
521
  writeInfo(`No available integrations found matching "${searchAnswer.searchTerm}"`);
521
522
  console.log(`šŸ’” If the integration is already connected, use 'lua integrations update' to change scopes.`);
@@ -525,8 +526,8 @@ async function connectIntegrationFlow(context, options = {}) {
525
526
  type: 'confirm',
526
527
  name: 'browseAll',
527
528
  message: 'Would you like to browse all available integrations?',
528
- default: true
529
- }
529
+ default: true,
530
+ },
530
531
  ]);
531
532
  if (!browseAnswer?.browseAll)
532
533
  return;
@@ -542,14 +543,14 @@ async function connectIntegrationFlow(context, options = {}) {
542
543
  name: 'integration',
543
544
  message: 'Select an integration to connect:',
544
545
  pageSize: 15,
545
- choices: filteredIntegrations.map(i => {
546
+ choices: filteredIntegrations.map((i) => {
546
547
  const authBadge = i.authSupport === 'oauth' ? 'šŸ”' : i.authSupport === 'token' ? 'šŸ”‘' : 'šŸ”šŸ”‘';
547
548
  return {
548
549
  name: `${authBadge} ${i.name} (${i.categories.join(', ')})`,
549
- value: i
550
+ value: i,
550
551
  };
551
- })
552
- }
552
+ }),
553
+ },
553
554
  ]);
554
555
  if (!integrationAnswer)
555
556
  return;
@@ -560,8 +561,7 @@ async function connectIntegrationFlow(context, options = {}) {
560
561
  console.log(` Auth Support: ${selectedIntegration.authSupport}`);
561
562
  console.log(` OAuth Configured: ${selectedIntegration.oauthConfigured ? 'Yes' : 'No'}`);
562
563
  // Step 3: Determine auth method and get scopes
563
- const canUseOAuth = selectedIntegration.oauthConfigured &&
564
- ['oauth', 'both'].includes(selectedIntegration.authSupport);
564
+ const canUseOAuth = selectedIntegration.oauthConfigured && ['oauth', 'both'].includes(selectedIntegration.authSupport);
565
565
  const canUseToken = ['token', 'both'].includes(selectedIntegration.authSupport);
566
566
  let authMethod;
567
567
  let selectedScopes = [];
@@ -569,36 +569,38 @@ async function connectIntegrationFlow(context, options = {}) {
569
569
  if (options.authMethod) {
570
570
  if (!['oauth', 'token'].includes(options.authMethod)) {
571
571
  console.error(`āŒ Invalid --auth-method: "${options.authMethod}". Use 'oauth' or 'token'`);
572
- throw new Error("Invalid --auth-method:");
572
+ throw new Error('Invalid --auth-method:');
573
573
  }
574
574
  if (options.authMethod === 'oauth' && !canUseOAuth) {
575
575
  console.error(`āŒ OAuth is not available for ${selectedIntegration.name}.`);
576
576
  if (canUseToken) {
577
577
  console.log(`šŸ’” Use --auth-method token instead.`);
578
578
  }
579
- throw new Error("Operation failed");
579
+ throw new Error('Operation failed');
580
580
  }
581
581
  if (options.authMethod === 'token' && !canUseToken) {
582
582
  console.error(`āŒ Token authentication is not available for ${selectedIntegration.name}.`);
583
583
  if (canUseOAuth) {
584
584
  console.log(`šŸ’” Use --auth-method oauth instead.`);
585
585
  }
586
- throw new Error("Operation failed");
586
+ throw new Error('Operation failed');
587
587
  }
588
588
  authMethod = options.authMethod;
589
589
  writeInfo(`Using ${authMethod === 'oauth' ? 'OAuth 2.0' : 'API Token'} authentication`);
590
590
  }
591
591
  else if (canUseOAuth && canUseToken) {
592
592
  // Both available - let user choose interactively
593
- const authAnswer = await safePrompt([{
593
+ const authAnswer = await safePrompt([
594
+ {
594
595
  type: 'list',
595
596
  name: 'method',
596
597
  message: 'Choose authentication method:',
597
598
  choices: [
598
599
  { name: 'šŸ” OAuth 2.0 (recommended)', value: 'oauth' },
599
- { name: 'šŸ”‘ API Token / Personal Access Token', value: 'token' }
600
- ]
601
- }]);
600
+ { name: 'šŸ”‘ API Token / Personal Access Token', value: 'token' },
601
+ ],
602
+ },
603
+ ]);
602
604
  if (!authAnswer)
603
605
  return;
604
606
  authMethod = authAnswer.method;
@@ -619,7 +621,7 @@ async function connectIntegrationFlow(context, options = {}) {
619
621
  }
620
622
  // Handle OAuth scope selection
621
623
  if (authMethod === 'oauth' && selectedIntegration.oauthScopes?.length) {
622
- const availableScopes = selectedIntegration.oauthScopes.map(s => s.unifiedScope);
624
+ const availableScopes = selectedIntegration.oauthScopes.map((s) => s.unifiedScope);
623
625
  if (options.scopes) {
624
626
  // Non-interactive: use provided scopes
625
627
  if (options.scopes.toLowerCase() === 'all') {
@@ -628,13 +630,13 @@ async function connectIntegrationFlow(context, options = {}) {
628
630
  }
629
631
  else {
630
632
  // Parse comma-separated scopes
631
- const requestedScopes = options.scopes.split(',').map(s => s.trim());
632
- const invalidScopes = requestedScopes.filter(s => !availableScopes.includes(s));
633
+ const requestedScopes = options.scopes.split(',').map((s) => s.trim());
634
+ const invalidScopes = requestedScopes.filter((s) => !availableScopes.includes(s));
633
635
  if (invalidScopes.length > 0) {
634
636
  console.error(`āŒ Invalid scopes: ${invalidScopes.join(', ')}`);
635
637
  console.log(`\nAvailable scopes for ${selectedIntegration.name}:`);
636
- availableScopes.forEach(s => console.log(` - ${s}`));
637
- throw new Error("Invalid scopes: ${invalidScopes.join(");
638
+ availableScopes.forEach((s) => console.log(` - ${s}`));
639
+ throw new Error('Invalid scopes: ${invalidScopes.join(');
638
640
  }
639
641
  selectedScopes = requestedScopes;
640
642
  writeInfo(`Using ${selectedScopes.length} specified scope(s)`);
@@ -642,13 +644,14 @@ async function connectIntegrationFlow(context, options = {}) {
642
644
  }
643
645
  else {
644
646
  // Interactive: prompt for scope selection
645
- const scopeAnswer = await safePrompt([{
647
+ const scopeAnswer = await safePrompt([
648
+ {
646
649
  type: 'checkbox',
647
650
  name: 'scopes',
648
651
  message: 'Select OAuth scopes (Space to toggle, Enter to confirm, leave empty for all):',
649
652
  pageSize: 15,
650
653
  loop: false,
651
- choices: selectedIntegration.oauthScopes.map(s => {
654
+ choices: selectedIntegration.oauthScopes.map((s) => {
652
655
  // Use friendly label if available, otherwise fall back to technical name
653
656
  const displayName = s.friendlyLabel || s.unifiedScope;
654
657
  const description = s.friendlyDescription
@@ -657,16 +660,15 @@ async function connectIntegrationFlow(context, options = {}) {
657
660
  return {
658
661
  name: `${displayName}${description}`,
659
662
  value: s.unifiedScope,
660
- checked: false
663
+ checked: false,
661
664
  };
662
- })
663
- }]);
665
+ }),
666
+ },
667
+ ]);
664
668
  if (!scopeAnswer)
665
669
  return;
666
670
  // If none selected, request all scopes
667
- selectedScopes = scopeAnswer.scopes.length > 0
668
- ? scopeAnswer.scopes
669
- : availableScopes;
671
+ selectedScopes = scopeAnswer.scopes.length > 0 ? scopeAnswer.scopes : availableScopes;
670
672
  console.log(`\nāœ“ Will request ${selectedScopes.length} scope(s)`);
671
673
  }
672
674
  }
@@ -695,12 +697,14 @@ async function connectIntegrationFlow(context, options = {}) {
695
697
  }
696
698
  else {
697
699
  // Interactive: ask user
698
- const sensitiveAnswer = await safePrompt([{
700
+ const sensitiveAnswer = await safePrompt([
701
+ {
699
702
  type: 'confirm',
700
703
  name: 'hide',
701
704
  message: 'Hide sensitive data (PII) from MCP tools?',
702
- default: false
703
- }]);
705
+ default: false,
706
+ },
707
+ ]);
704
708
  if (sensitiveAnswer) {
705
709
  hideSensitive = sensitiveAnswer.hide;
706
710
  }
@@ -722,24 +726,25 @@ async function connectIntegrationFlow(context, options = {}) {
722
726
  }
723
727
  if (options.triggers) {
724
728
  // Non-interactive: parse comma-separated triggers (e.g., 'task_task.created,task_task.updated')
725
- const requestedTriggers = options.triggers.split(',').map(t => t.trim());
729
+ const requestedTriggers = options.triggers.split(',').map((t) => t.trim());
726
730
  for (const trigger of requestedTriggers) {
727
731
  const [objectType, event] = trigger.split('.');
728
- const matchingEvent = availableEvents.find(e => e.objectType === objectType && e.event === event);
732
+ const matchingEvent = availableEvents.find((e) => e.objectType === objectType && e.event === event);
729
733
  if (!matchingEvent) {
730
734
  console.error(`āŒ Invalid trigger: ${trigger}`);
731
735
  console.log(`\nAvailable triggers for ${selectedIntegration.name}:`);
732
- availableEvents.forEach(e => {
736
+ availableEvents.forEach((e) => {
733
737
  console.log(` - ${e.objectType}.${e.event} [${e.webhookType}] - ${e.friendlyDescription}`);
734
738
  });
735
- throw new Error("Invalid trigger: ${trigger}");
739
+ throw new Error('Invalid trigger: ${trigger}');
736
740
  }
737
741
  selectedTriggers.push(matchingEvent);
738
742
  }
739
743
  writeInfo(`Selected ${selectedTriggers.length} trigger(s)`);
740
744
  // If custom webhook mode, prompt for URL if not provided
741
745
  if (isCustomWebhook && !options.hookUrl) {
742
- const urlAnswer = await safePrompt([{
746
+ const urlAnswer = await safePrompt([
747
+ {
743
748
  type: 'input',
744
749
  name: 'url',
745
750
  message: 'Enter your webhook URL:',
@@ -751,8 +756,9 @@ async function connectIntegrationFlow(context, options = {}) {
751
756
  catch {
752
757
  return 'Please enter a valid URL';
753
758
  }
754
- }
755
- }]);
759
+ },
760
+ },
761
+ ]);
756
762
  if (!urlAnswer)
757
763
  return;
758
764
  webhookUrl = urlAnswer.url;
@@ -765,46 +771,53 @@ async function connectIntegrationFlow(context, options = {}) {
765
771
  console.log('─'.repeat(60));
766
772
  console.log('\nTriggers wake your agent when something happens in the integration.');
767
773
  console.log('We recommend adding only what you actually need — you can always add them later.');
768
- const wantTriggersAnswer = await safePrompt([{
774
+ const wantTriggersAnswer = await safePrompt([
775
+ {
769
776
  type: 'confirm',
770
777
  name: 'want',
771
778
  message: 'Do you want to configure triggers now?',
772
779
  default: false,
773
- }]);
780
+ },
781
+ ]);
774
782
  if (!wantTriggersAnswer)
775
783
  return;
776
784
  if (wantTriggersAnswer.want) {
777
785
  console.log('\nSelect the events you actually need:');
778
786
  console.log('(Space to toggle, Enter to confirm. Nothing pre-selected.)');
779
- const triggerAnswer = await safePrompt([{
787
+ const triggerAnswer = await safePrompt([
788
+ {
780
789
  type: 'checkbox',
781
790
  name: 'triggers',
782
791
  message: 'Select triggers:',
783
792
  pageSize: 15,
784
793
  loop: false,
785
- choices: availableEvents.map(e => ({
794
+ choices: availableEvents.map((e) => ({
786
795
  name: `${e.friendlyDescription} [${e.webhookType}]`,
787
796
  value: e,
788
- checked: false // None pre-selected — user chooses what they need
789
- }))
790
- }]);
797
+ checked: false, // None pre-selected — user chooses what they need
798
+ })),
799
+ },
800
+ ]);
791
801
  if (triggerAnswer && triggerAnswer.triggers.length > 0) {
792
802
  selectedTriggers = triggerAnswer.triggers;
793
803
  // Ask about webhook mode only if triggers are selected
794
- const modeAnswer = await safePrompt([{
804
+ const modeAnswer = await safePrompt([
805
+ {
795
806
  type: 'list',
796
807
  name: 'mode',
797
808
  message: 'How should these events be handled?',
798
809
  choices: [
799
810
  { name: 'šŸ¤– Agent Trigger (recommended) - Events wake up your agent', value: 'agent' },
800
- { name: 'šŸ”— Custom URL - Send events to your own webhook URL', value: 'custom' }
801
- ]
802
- }]);
811
+ { name: 'šŸ”— Custom URL - Send events to your own webhook URL', value: 'custom' },
812
+ ],
813
+ },
814
+ ]);
803
815
  if (!modeAnswer)
804
816
  return;
805
817
  if (modeAnswer.mode === 'custom') {
806
818
  isCustomWebhook = true;
807
- const urlAnswer = await safePrompt([{
819
+ const urlAnswer = await safePrompt([
820
+ {
808
821
  type: 'input',
809
822
  name: 'url',
810
823
  message: 'Enter your webhook URL:',
@@ -816,8 +829,9 @@ async function connectIntegrationFlow(context, options = {}) {
816
829
  catch {
817
830
  return 'Please enter a valid URL';
818
831
  }
819
- }
820
- }]);
832
+ },
833
+ },
834
+ ]);
821
835
  if (!urlAnswer)
822
836
  return;
823
837
  webhookUrl = urlAnswer.url;
@@ -845,12 +859,12 @@ async function connectIntegrationFlow(context, options = {}) {
845
859
  writeInfo(`Note: Could not fetch available triggers (${error.message})`);
846
860
  }
847
861
  // Step 5: Get authorization URL from Lua API
848
- writeProgress("šŸ”„ Preparing authorization...");
862
+ writeProgress('šŸ”„ Preparing authorization...');
849
863
  const state = Buffer.from(JSON.stringify({
850
864
  agentId: context.agentId,
851
865
  integration: selectedIntegration.value,
852
866
  authMethod,
853
- timestamp: Date.now()
867
+ timestamp: Date.now(),
854
868
  })).toString('base64');
855
869
  // Encode both agentId and userId in externalXref for the connection
856
870
  const externalXref = JSON.stringify({
@@ -871,9 +885,9 @@ async function connectIntegrationFlow(context, options = {}) {
871
885
  // Auth URL is already resolved by the API (redirect wrappers followed server-side)
872
886
  const authUrl = authUrlResult.data.authUrl;
873
887
  // Step 4: Start callback server and open browser
874
- console.log("\n" + "─".repeat(60));
875
- console.log("🌐 Starting OAuth authorization flow...");
876
- console.log("─".repeat(60));
888
+ console.log('\n' + '─'.repeat(60));
889
+ console.log('🌐 Starting OAuth authorization flow...');
890
+ console.log('─'.repeat(60));
877
891
  console.log(`\nIntegration: ${selectedIntegration.name}`);
878
892
  console.log(`\nšŸ“‹ Authorization URL (copy if browser doesn't open):\n ${authUrl}\n`);
879
893
  // Start the callback server
@@ -881,17 +895,17 @@ async function connectIntegrationFlow(context, options = {}) {
881
895
  // Auto-open browser
882
896
  try {
883
897
  await open(authUrl);
884
- writeInfo("🌐 Browser opened - please complete the authorization");
898
+ writeInfo('🌐 Browser opened - please complete the authorization');
885
899
  }
886
900
  catch (error) {
887
- writeInfo("šŸ’” Could not open browser automatically. Please open the URL above manually.");
901
+ writeInfo('šŸ’” Could not open browser automatically. Please open the URL above manually.');
888
902
  }
889
- console.log("\nā³ Waiting for authorization (5 minute timeout)...");
890
- console.log("šŸ’” Complete the authorization in your browser.\n");
903
+ console.log('\nā³ Waiting for authorization (5 minute timeout)...');
904
+ console.log('šŸ’” Complete the authorization in your browser.\n');
891
905
  // Wait for callback
892
906
  const result = await callbackPromise;
893
907
  if (result.success && result.connectionId) {
894
- writeSuccess("\nāœ… Authorization successful!");
908
+ writeSuccess('\nāœ… Authorization successful!');
895
909
  // Finalize the connection (sets up MCP server internally and creates webhooks)
896
910
  await finalizeConnection(context, selectedIntegration, result.connectionId, selectedScopes, hideSensitive, {
897
911
  triggers: selectedTriggers,
@@ -905,13 +919,15 @@ async function connectIntegrationFlow(context, options = {}) {
905
919
  console.log(` Log ID: ${result.logId}`);
906
920
  }
907
921
  // Report auth failure for observability (fire and forget)
908
- context.unifiedToApi.reportAuthFailure({
922
+ context.unifiedToApi
923
+ .reportAuthFailure({
909
924
  integrationType: selectedIntegration.value,
910
925
  error: result.error || 'Unknown OAuth failure',
911
926
  logId: result.logId,
912
927
  agentId: context.agentId,
913
928
  source: 'cli',
914
- }).catch(() => { });
929
+ })
930
+ .catch(() => { });
915
931
  console.log("šŸ’” Please try again with 'lua integrations connect'\n");
916
932
  }
917
933
  }
@@ -922,7 +938,7 @@ async function connectIntegrationFlow(context, options = {}) {
922
938
  async function finalizeConnection(context, integration, connectionId, scopes, hideSensitive = false, webhookConfig = { triggers: [], webhookUrl: '', isCustomWebhook: false }) {
923
939
  writeProgress(`šŸ”„ Setting up ${integration.name} connection...`);
924
940
  // Build trigger params for the API (include per-trigger hookUrl/interval if set)
925
- const triggers = webhookConfig.triggers.map(t => ({
941
+ const triggers = webhookConfig.triggers.map((t) => ({
926
942
  objectType: t.objectType,
927
943
  event: t.event,
928
944
  hookUrl: t.hookUrl || (webhookConfig.isCustomWebhook ? webhookConfig.webhookUrl : undefined),
@@ -944,9 +960,9 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
944
960
  // ─────────────────────────────────────────────────────────────────────────
945
961
  // Display Results
946
962
  // ─────────────────────────────────────────────────────────────────────────
947
- console.log("\n" + "─".repeat(60));
948
- console.log("šŸŽ‰ Connection Established!");
949
- console.log("─".repeat(60));
963
+ console.log('\n' + '─'.repeat(60));
964
+ console.log('šŸŽ‰ Connection Established!');
965
+ console.log('─'.repeat(60));
950
966
  console.log(`\n Integration: ${integration.name}`);
951
967
  console.log(` Connection ID: ${connectionId}`);
952
968
  // MCP Server status
@@ -957,8 +973,8 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
957
973
  // Show requested scopes with friendly labels
958
974
  if (scopes.length > 0) {
959
975
  console.log(`\n šŸ”‘ Permissions (${scopes.length}):`);
960
- scopes.forEach(scopeName => {
961
- const scopeInfo = integration.oauthScopes?.find(s => s.unifiedScope === scopeName);
976
+ scopes.forEach((scopeName) => {
977
+ const scopeInfo = integration.oauthScopes?.find((s) => s.unifiedScope === scopeName);
962
978
  if (scopeInfo?.friendlyLabel) {
963
979
  console.log(` • ${scopeInfo.friendlyLabel}`);
964
980
  }
@@ -979,20 +995,20 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
979
995
  else {
980
996
  console.log(` Mode: Agent wake-up`);
981
997
  }
982
- webhooks.forEach(wh => {
983
- const trigger = webhookConfig.triggers.find(t => t.objectType === wh.objectType && t.event === wh.event);
998
+ webhooks.forEach((wh) => {
999
+ const trigger = webhookConfig.triggers.find((t) => t.objectType === wh.objectType && t.event === wh.event);
984
1000
  const desc = trigger?.friendlyDescription || `${wh.objectType}.${wh.event}`;
985
1001
  console.log(` āœ“ ${desc}`);
986
1002
  });
987
1003
  if (failedWebhooks && failedWebhooks.length > 0) {
988
- failedWebhooks.forEach(t => console.log(` āœ— ${t.objectType}.${t.event}: ${t.error}`));
1004
+ failedWebhooks.forEach((t) => console.log(` āœ— ${t.objectType}.${t.event}: ${t.error}`));
989
1005
  }
990
1006
  }
991
1007
  else {
992
1008
  console.log(`\n ⚔ Triggers: none (add later with: lua triggers create --connection ${connectionId})`);
993
1009
  }
994
1010
  // Summary message
995
- console.log("\n" + "─".repeat(60));
1011
+ console.log('\n' + '─'.repeat(60));
996
1012
  const capabilities = [];
997
1013
  if (mcpServer.active) {
998
1014
  capabilities.push('tools via MCP');
@@ -1020,16 +1036,16 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
1020
1036
  });
1021
1037
  }
1022
1038
  async function listConnections(context) {
1023
- writeProgress("šŸ”„ Loading connections...");
1039
+ writeProgress('šŸ”„ Loading connections...');
1024
1040
  try {
1025
1041
  // API now returns connections enriched with MCP server info
1026
1042
  const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
1027
1043
  const connections = connectionsResult.success ? connectionsResult.data || [] : [];
1028
- console.log("\n" + "=".repeat(60));
1029
- console.log("šŸ”— Connected Integrations");
1030
- console.log("=".repeat(60) + "\n");
1044
+ console.log('\n' + '='.repeat(60));
1045
+ console.log('šŸ”— Connected Integrations');
1046
+ console.log('='.repeat(60) + '\n');
1031
1047
  if (connections.length === 0) {
1032
- console.log("ā„¹ļø No integrations connected yet.");
1048
+ console.log('ā„¹ļø No integrations connected yet.');
1033
1049
  console.log("šŸ’” Run 'lua integrations connect' to connect an integration.\n");
1034
1050
  return;
1035
1051
  }
@@ -1063,7 +1079,7 @@ async function listConnections(context) {
1063
1079
  console.log(` Connected: ${new Date(connection.createdAt).toLocaleDateString()}`);
1064
1080
  console.log();
1065
1081
  }
1066
- console.log("=".repeat(60));
1082
+ console.log('='.repeat(60));
1067
1083
  console.log(`Total: ${connections.length} integration(s)\n`);
1068
1084
  }
1069
1085
  catch (error) {
@@ -1102,7 +1118,7 @@ async function disconnectIntegrationInteractive(context) {
1102
1118
  }
1103
1119
  const connections = connectionsResult.data || [];
1104
1120
  if (connections.length === 0) {
1105
- console.log("\nā„¹ļø No integrations to disconnect.\n");
1121
+ console.log('\nā„¹ļø No integrations to disconnect.\n');
1106
1122
  return;
1107
1123
  }
1108
1124
  const connectionAnswer = await safePrompt([
@@ -1110,25 +1126,25 @@ async function disconnectIntegrationInteractive(context) {
1110
1126
  type: 'list',
1111
1127
  name: 'connection',
1112
1128
  message: 'Select an integration to disconnect:',
1113
- choices: connections.map(c => ({
1129
+ choices: connections.map((c) => ({
1114
1130
  name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
1115
- value: c.id
1116
- }))
1117
- }
1131
+ value: c.id,
1132
+ })),
1133
+ },
1118
1134
  ]);
1119
1135
  if (!connectionAnswer?.connection)
1120
1136
  return;
1121
- const selectedConnection = connections.find(c => c.id === connectionAnswer.connection);
1137
+ const selectedConnection = connections.find((c) => c.id === connectionAnswer.connection);
1122
1138
  const confirmAnswer = await safePrompt([
1123
1139
  {
1124
1140
  type: 'confirm',
1125
1141
  name: 'confirm',
1126
1142
  message: `Disconnect ${selectedConnection?.integrationName || selectedConnection?.integrationType}? Your agent will lose access to this integration.`,
1127
- default: false
1128
- }
1143
+ default: false,
1144
+ },
1129
1145
  ]);
1130
1146
  if (!confirmAnswer?.confirm) {
1131
- console.log("\nāŒ Cancelled.\n");
1147
+ console.log('\nāŒ Cancelled.\n');
1132
1148
  return;
1133
1149
  }
1134
1150
  await disconnectIntegration(context, connectionAnswer.connection);
@@ -1142,13 +1158,13 @@ async function disconnectIntegrationInteractive(context) {
1142
1158
  // ─────────────────────────────────────────────────────────────────────────────
1143
1159
  async function updateConnectionFlow(context, options = {}) {
1144
1160
  // Step 1: Fetch existing connections and available integrations
1145
- writeProgress("šŸ”„ Loading connections...");
1161
+ writeProgress('šŸ”„ Loading connections...');
1146
1162
  let connections = [];
1147
1163
  let integrations = [];
1148
1164
  try {
1149
1165
  const [connectionsResult, integrationsResult] = await Promise.all([
1150
1166
  context.unifiedToApi.getConnections(context.agentId),
1151
- fetchAvailableIntegrations(context.unifiedToApi)
1167
+ fetchAvailableIntegrations(context.unifiedToApi),
1152
1168
  ]);
1153
1169
  connections = connectionsResult.success ? connectionsResult.data || [] : [];
1154
1170
  integrations = integrationsResult;
@@ -1158,7 +1174,7 @@ async function updateConnectionFlow(context, options = {}) {
1158
1174
  return;
1159
1175
  }
1160
1176
  if (connections.length === 0) {
1161
- writeInfo("No integrations to update.");
1177
+ writeInfo('No integrations to update.');
1162
1178
  console.log("šŸ’” Run 'lua integrations connect' to connect an integration.\n");
1163
1179
  return;
1164
1180
  }
@@ -1167,14 +1183,14 @@ async function updateConnectionFlow(context, options = {}) {
1167
1183
  let selectedIntegration;
1168
1184
  if (options.integration) {
1169
1185
  // Find connection by integration type
1170
- selectedConnection = connections.find(c => c.integrationType === options.integration);
1186
+ selectedConnection = connections.find((c) => c.integrationType === options.integration);
1171
1187
  if (!selectedConnection) {
1172
1188
  console.error(`āŒ No connection found for integration "${options.integration}".`);
1173
1189
  console.log('\nConnected integrations:');
1174
- connections.forEach(c => console.log(` - ${c.integrationType} (${c.integrationName || c.integrationType})`));
1175
- throw new Error("No connection found for integration");
1190
+ connections.forEach((c) => console.log(` - ${c.integrationType} (${c.integrationName || c.integrationType})`));
1191
+ throw new Error('No connection found for integration');
1176
1192
  }
1177
- selectedIntegration = integrations.find(i => i.value === options.integration);
1193
+ selectedIntegration = integrations.find((i) => i.value === options.integration);
1178
1194
  }
1179
1195
  else {
1180
1196
  // Interactive selection
@@ -1183,16 +1199,16 @@ async function updateConnectionFlow(context, options = {}) {
1183
1199
  type: 'list',
1184
1200
  name: 'connection',
1185
1201
  message: 'Select a connection to update:',
1186
- choices: connections.map(c => ({
1202
+ choices: connections.map((c) => ({
1187
1203
  name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
1188
- value: c
1189
- }))
1190
- }
1204
+ value: c,
1205
+ })),
1206
+ },
1191
1207
  ]);
1192
1208
  if (!connectionAnswer?.connection)
1193
1209
  return;
1194
1210
  selectedConnection = connectionAnswer.connection;
1195
- selectedIntegration = integrations.find(i => i.value === selectedConnection.integrationType);
1211
+ selectedIntegration = integrations.find((i) => i.value === selectedConnection.integrationType);
1196
1212
  }
1197
1213
  if (!selectedIntegration) {
1198
1214
  writeError(`āŒ Integration details not found for ${selectedConnection.integrationType}`);
@@ -1201,15 +1217,14 @@ async function updateConnectionFlow(context, options = {}) {
1201
1217
  console.log(`\nšŸ“Œ Updating: ${selectedIntegration.name}`);
1202
1218
  console.log(` Current Connection ID: ${selectedConnection.id}`);
1203
1219
  // Step 3: Check if OAuth with configurable scopes
1204
- const canUseOAuth = selectedIntegration.oauthConfigured &&
1205
- ['oauth', 'both'].includes(selectedIntegration.authSupport);
1220
+ const canUseOAuth = selectedIntegration.oauthConfigured && ['oauth', 'both'].includes(selectedIntegration.authSupport);
1206
1221
  if (!canUseOAuth || !selectedIntegration.oauthScopes?.length) {
1207
- writeInfo("This integration does not have configurable scopes.");
1208
- console.log("šŸ’” To reconnect with different credentials, disconnect and connect again.\n");
1222
+ writeInfo('This integration does not have configurable scopes.');
1223
+ console.log('šŸ’” To reconnect with different credentials, disconnect and connect again.\n');
1209
1224
  return;
1210
1225
  }
1211
1226
  // Step 4: Select new scopes
1212
- const availableScopes = selectedIntegration.oauthScopes.map(s => s.unifiedScope);
1227
+ const availableScopes = selectedIntegration.oauthScopes.map((s) => s.unifiedScope);
1213
1228
  let selectedScopes = [];
1214
1229
  if (options.scopes) {
1215
1230
  // Non-interactive: use provided scopes
@@ -1218,13 +1233,13 @@ async function updateConnectionFlow(context, options = {}) {
1218
1233
  writeInfo(`Using all ${selectedScopes.length} available scope(s)`);
1219
1234
  }
1220
1235
  else {
1221
- const requestedScopes = options.scopes.split(',').map(s => s.trim());
1222
- const invalidScopes = requestedScopes.filter(s => !availableScopes.includes(s));
1236
+ const requestedScopes = options.scopes.split(',').map((s) => s.trim());
1237
+ const invalidScopes = requestedScopes.filter((s) => !availableScopes.includes(s));
1223
1238
  if (invalidScopes.length > 0) {
1224
1239
  console.error(`āŒ Invalid scopes: ${invalidScopes.join(', ')}`);
1225
1240
  console.log(`\nAvailable scopes for ${selectedIntegration.name}:`);
1226
- availableScopes.forEach(s => console.log(` - ${s}`));
1227
- throw new Error("Invalid scopes: ${invalidScopes.join(");
1241
+ availableScopes.forEach((s) => console.log(` - ${s}`));
1242
+ throw new Error('Invalid scopes: ${invalidScopes.join(');
1228
1243
  }
1229
1244
  selectedScopes = requestedScopes;
1230
1245
  writeInfo(`Using ${selectedScopes.length} specified scope(s)`);
@@ -1232,13 +1247,14 @@ async function updateConnectionFlow(context, options = {}) {
1232
1247
  }
1233
1248
  else {
1234
1249
  // Interactive: prompt for scope selection
1235
- const scopeAnswer = await safePrompt([{
1250
+ const scopeAnswer = await safePrompt([
1251
+ {
1236
1252
  type: 'checkbox',
1237
1253
  name: 'scopes',
1238
1254
  message: 'Select new OAuth scopes (Space to toggle, Enter to confirm, leave empty for all):',
1239
1255
  pageSize: 15,
1240
1256
  loop: false,
1241
- choices: selectedIntegration.oauthScopes.map(s => {
1257
+ choices: selectedIntegration.oauthScopes.map((s) => {
1242
1258
  // Use friendly label if available, otherwise fall back to technical name
1243
1259
  const displayName = s.friendlyLabel || s.unifiedScope;
1244
1260
  const description = s.friendlyDescription
@@ -1247,15 +1263,14 @@ async function updateConnectionFlow(context, options = {}) {
1247
1263
  return {
1248
1264
  name: `${displayName}${description}`,
1249
1265
  value: s.unifiedScope,
1250
- checked: false
1266
+ checked: false,
1251
1267
  };
1252
- })
1253
- }]);
1268
+ }),
1269
+ },
1270
+ ]);
1254
1271
  if (!scopeAnswer)
1255
1272
  return;
1256
- selectedScopes = scopeAnswer.scopes.length > 0
1257
- ? scopeAnswer.scopes
1258
- : availableScopes;
1273
+ selectedScopes = scopeAnswer.scopes.length > 0 ? scopeAnswer.scopes : availableScopes;
1259
1274
  console.log(`\nāœ“ Will request ${selectedScopes.length} scope(s)`);
1260
1275
  }
1261
1276
  // Determine hide_sensitive setting
@@ -1265,12 +1280,14 @@ async function updateConnectionFlow(context, options = {}) {
1265
1280
  }
1266
1281
  else {
1267
1282
  // Interactive: ask user
1268
- const sensitiveAnswer = await safePrompt([{
1283
+ const sensitiveAnswer = await safePrompt([
1284
+ {
1269
1285
  type: 'confirm',
1270
1286
  name: 'hide',
1271
1287
  message: 'Hide sensitive data (PII) from MCP tools?',
1272
- default: false
1273
- }]);
1288
+ default: false,
1289
+ },
1290
+ ]);
1274
1291
  if (sensitiveAnswer) {
1275
1292
  hideSensitive = sensitiveAnswer.hide;
1276
1293
  }
@@ -1281,8 +1298,8 @@ async function updateConnectionFlow(context, options = {}) {
1281
1298
  const webhooksResult = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
1282
1299
  if (webhooksResult.success && webhooksResult.data && webhooksResult.data.length > 0) {
1283
1300
  // Filter webhooks to only those belonging to this connection
1284
- const connectionWebhooks = webhooksResult.data.filter(w => w.connectionId === selectedConnection.id);
1285
- existingTriggers = connectionWebhooks.map(w => ({
1301
+ const connectionWebhooks = webhooksResult.data.filter((w) => w.connectionId === selectedConnection.id);
1302
+ existingTriggers = connectionWebhooks.map((w) => ({
1286
1303
  objectType: w.objectType,
1287
1304
  event: w.event,
1288
1305
  hookUrl: w.hookUrl,
@@ -1303,11 +1320,11 @@ async function updateConnectionFlow(context, options = {}) {
1303
1320
  type: 'confirm',
1304
1321
  name: 'confirm',
1305
1322
  message: `Update ${selectedIntegration.name}? This will re-authorize with new scopes.`,
1306
- default: true
1307
- }
1323
+ default: true,
1324
+ },
1308
1325
  ]);
1309
1326
  if (!confirmAnswer?.confirm) {
1310
- console.log("\nāŒ Cancelled.\n");
1327
+ console.log('\nāŒ Cancelled.\n');
1311
1328
  return;
1312
1329
  }
1313
1330
  }
@@ -1326,7 +1343,7 @@ async function updateConnectionFlow(context, options = {}) {
1326
1343
  agentId: context.agentId,
1327
1344
  integration: selectedIntegration.value,
1328
1345
  authMethod: 'oauth',
1329
- timestamp: Date.now()
1346
+ timestamp: Date.now(),
1330
1347
  })).toString('base64');
1331
1348
  const externalXref = JSON.stringify({
1332
1349
  agentId: context.agentId,
@@ -1346,25 +1363,25 @@ async function updateConnectionFlow(context, options = {}) {
1346
1363
  // Auth URL is already resolved by the API (redirect wrappers followed server-side)
1347
1364
  const authUrl = authUrlResult.data.authUrl;
1348
1365
  // Step 9: Open browser and wait for callback
1349
- console.log("\n" + "─".repeat(60));
1350
- console.log("🌐 Re-authorizing with new scopes...");
1351
- console.log("─".repeat(60));
1366
+ console.log('\n' + '─'.repeat(60));
1367
+ console.log('🌐 Re-authorizing with new scopes...');
1368
+ console.log('─'.repeat(60));
1352
1369
  console.log(`\nšŸ“‹ Authorization URL (copy if browser doesn't open):\n ${authUrl}\n`);
1353
1370
  const callbackPromise = startCallbackServer(300000);
1354
1371
  try {
1355
1372
  await open(authUrl);
1356
- writeInfo("🌐 Browser opened - please complete the authorization");
1373
+ writeInfo('🌐 Browser opened - please complete the authorization');
1357
1374
  }
1358
1375
  catch (error) {
1359
- writeInfo("šŸ’” Could not open browser automatically. Please open the URL above manually.");
1376
+ writeInfo('šŸ’” Could not open browser automatically. Please open the URL above manually.');
1360
1377
  }
1361
- console.log("\nā³ Waiting for authorization (5 minute timeout)...");
1362
- console.log("šŸ’” Complete the authorization in your browser.\n");
1378
+ console.log('\nā³ Waiting for authorization (5 minute timeout)...');
1379
+ console.log('šŸ’” Complete the authorization in your browser.\n');
1363
1380
  const result = await callbackPromise;
1364
1381
  if (result.success && result.connectionId) {
1365
- writeSuccess("\nāœ… Authorization successful!");
1382
+ writeSuccess('\nāœ… Authorization successful!');
1366
1383
  // Check if any triggers use custom webhooks
1367
- const hasCustomWebhook = existingTriggers.some(t => t.hookUrl !== AGENT_WEBHOOK_URL);
1384
+ const hasCustomWebhook = existingTriggers.some((t) => t.hookUrl !== AGENT_WEBHOOK_URL);
1368
1385
  // Convert existing triggers to TriggerWithSettings format, preserving per-trigger hookUrl and interval
1369
1386
  let triggersToRestore = [];
1370
1387
  if (existingTriggers.length > 0) {
@@ -1372,7 +1389,7 @@ async function updateConnectionFlow(context, options = {}) {
1372
1389
  const eventsResult = await context.unifiedToApi.getAvailableWebhookEventsByType(selectedIntegration.value);
1373
1390
  if (eventsResult.success && eventsResult.data) {
1374
1391
  for (const trigger of existingTriggers) {
1375
- const matchingEvent = eventsResult.data.find(e => e.objectType === trigger.objectType && e.event === trigger.event);
1392
+ const matchingEvent = eventsResult.data.find((e) => e.objectType === trigger.objectType && e.event === trigger.event);
1376
1393
  if (matchingEvent) {
1377
1394
  // Preserve per-trigger hookUrl and interval from original webhook
1378
1395
  triggersToRestore.push({
@@ -1403,13 +1420,15 @@ async function updateConnectionFlow(context, options = {}) {
1403
1420
  console.log(` Log ID: ${result.logId}`);
1404
1421
  }
1405
1422
  // Report auth failure for observability (fire and forget)
1406
- context.unifiedToApi.reportAuthFailure({
1423
+ context.unifiedToApi
1424
+ .reportAuthFailure({
1407
1425
  integrationType: selectedIntegration.value,
1408
1426
  error: result.error || 'Unknown OAuth failure',
1409
1427
  logId: result.logId,
1410
1428
  agentId: context.agentId,
1411
1429
  source: 'cli',
1412
- }).catch(() => { });
1430
+ })
1431
+ .catch(() => { });
1413
1432
  console.log("šŸ’” The old connection was removed. Please reconnect with 'lua integrations connect'\n");
1414
1433
  }
1415
1434
  }
@@ -1420,7 +1439,8 @@ async function updateConnectionFlow(context, options = {}) {
1420
1439
  * Handle webhooks subcommand (non-interactive)
1421
1440
  */
1422
1441
  async function webhooksSubcommand(context, cmdOptions) {
1423
- const subAction = cmdOptions?._?.[0]?.toLowerCase() || '';
1442
+ const rawSubAction = cmdOptions?._?.[0] || '';
1443
+ const subAction = rawSubAction ? validateOrSuggest('triggers.action', rawSubAction) : '';
1424
1444
  const options = {
1425
1445
  connectionId: cmdOptions?.connection || cmdOptions?.connectionId,
1426
1446
  webhookId: cmdOptions?.webhookId,
@@ -1441,9 +1461,9 @@ async function webhooksSubcommand(context, cmdOptions) {
1441
1461
  break;
1442
1462
  case 'delete':
1443
1463
  if (!options.webhookId) {
1444
- console.error("āŒ --webhook-id is required for delete");
1464
+ console.error('āŒ --webhook-id is required for delete');
1445
1465
  console.log("\nšŸ’” Run 'lua integrations webhooks list' to see trigger IDs");
1446
- throw new Error("--webhook-id is required for delete");
1466
+ throw new Error('--webhook-id is required for delete');
1447
1467
  }
1448
1468
  await webhooksDeleteFlow(context, options.webhookId);
1449
1469
  break;
@@ -1455,9 +1475,9 @@ async function webhooksSubcommand(context, cmdOptions) {
1455
1475
  await connectionPauseFlow(context, options.connectionId);
1456
1476
  }
1457
1477
  else {
1458
- console.error("āŒ --webhook-id or --connection-id is required for pause");
1478
+ console.error('āŒ --webhook-id or --connection-id is required for pause');
1459
1479
  console.log("\nšŸ’” Run 'lua integrations webhooks list' to see trigger IDs");
1460
- throw new Error("--webhook-id or --connection-id is required for pause");
1480
+ throw new Error('--webhook-id or --connection-id is required for pause');
1461
1481
  }
1462
1482
  break;
1463
1483
  case 'resume':
@@ -1468,9 +1488,9 @@ async function webhooksSubcommand(context, cmdOptions) {
1468
1488
  await connectionResumeFlow(context, options.connectionId);
1469
1489
  }
1470
1490
  else {
1471
- console.error("āŒ --webhook-id or --connection-id is required for resume");
1491
+ console.error('āŒ --webhook-id or --connection-id is required for resume');
1472
1492
  console.log("\nšŸ’” Run 'lua integrations webhooks list' to see trigger IDs");
1473
- throw new Error("--webhook-id or --connection-id is required for resume");
1493
+ throw new Error('--webhook-id or --connection-id is required for resume');
1474
1494
  }
1475
1495
  break;
1476
1496
  case 'events':
@@ -1527,17 +1547,17 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
1527
1547
  console.log(JSON.stringify({ error: 'Either --connection or --integration is required' }));
1528
1548
  }
1529
1549
  else {
1530
- console.error("āŒ Either --connection <id> or --integration <type> is required");
1531
- console.log("\nUsage:");
1532
- console.log(" lua integrations webhooks events --connection <id>");
1533
- console.log(" lua integrations webhooks events --integration <type>");
1550
+ console.error('āŒ Either --connection <id> or --integration <type> is required');
1551
+ console.log('\nUsage:');
1552
+ console.log(' lua integrations webhooks events --connection <id>');
1553
+ console.log(' lua integrations webhooks events --integration <type>');
1534
1554
  }
1535
- throw new Error("Operation failed");
1555
+ throw new Error('Operation failed');
1536
1556
  }
1537
1557
  if (jsonOutput) {
1538
1558
  const output = {
1539
1559
  source: sourceName,
1540
- events: webhookEvents.map(e => ({
1560
+ events: webhookEvents.map((e) => ({
1541
1561
  trigger: `${e.objectType}.${e.event}`,
1542
1562
  objectType: e.objectType,
1543
1563
  event: e.event,
@@ -1554,14 +1574,14 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
1554
1574
  console.log(JSON.stringify(output, null, 2));
1555
1575
  }
1556
1576
  else {
1557
- console.log("\n" + "=".repeat(60));
1577
+ console.log('\n' + '='.repeat(60));
1558
1578
  console.log(`šŸ“” Available Trigger Events for ${sourceName}`);
1559
- console.log("=".repeat(60) + "\n");
1579
+ console.log('='.repeat(60) + '\n');
1560
1580
  if (webhookEvents.length === 0) {
1561
- console.log("ā„¹ļø No trigger events available for this integration.\n");
1581
+ console.log('ā„¹ļø No trigger events available for this integration.\n');
1562
1582
  }
1563
1583
  else {
1564
- webhookEvents.forEach(e => {
1584
+ webhookEvents.forEach((e) => {
1565
1585
  console.log(` ${e.objectType}.${e.event} [${e.webhookType}]`);
1566
1586
  console.log(` ${e.friendlyDescription}`);
1567
1587
  if (e.availableFilters.length > 0) {
@@ -1569,10 +1589,13 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
1569
1589
  }
1570
1590
  console.log();
1571
1591
  });
1572
- console.log("─".repeat(60));
1592
+ console.log('─'.repeat(60));
1573
1593
  console.log(`Total: ${webhookEvents.length} event(s) available`);
1574
- console.log("\nšŸ’” Use with --triggers flag:");
1575
- const exampleTriggers = webhookEvents.slice(0, 2).map(e => `${e.objectType}.${e.event}`).join(',');
1594
+ console.log('\nšŸ’” Use with --triggers flag:');
1595
+ const exampleTriggers = webhookEvents
1596
+ .slice(0, 2)
1597
+ .map((e) => `${e.objectType}.${e.event}`)
1598
+ .join(',');
1576
1599
  console.log(` lua integrations connect --integration <type> --triggers ${exampleTriggers}\n`);
1577
1600
  }
1578
1601
  }
@@ -1584,16 +1607,16 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
1584
1607
  else {
1585
1608
  writeError(`āŒ Failed to get trigger events: ${error.message}`);
1586
1609
  }
1587
- throw new Error("Operation failed");
1610
+ throw new Error('Operation failed');
1588
1611
  }
1589
1612
  }
1590
1613
  /**
1591
1614
  * Interactive webhooks menu
1592
1615
  */
1593
1616
  async function webhooksInteractiveMenu(context) {
1594
- console.log("\n" + "─".repeat(60));
1595
- console.log("šŸ”” Triggers");
1596
- console.log("─".repeat(60) + "\n");
1617
+ console.log('\n' + '─'.repeat(60));
1618
+ console.log('šŸ”” Triggers');
1619
+ console.log('─'.repeat(60) + '\n');
1597
1620
  const actionAnswer = await safePrompt([
1598
1621
  {
1599
1622
  type: 'list',
@@ -1607,9 +1630,9 @@ async function webhooksInteractiveMenu(context) {
1607
1630
  { name: 'āøļø Pause all triggers for a connection', value: 'pauseConn' },
1608
1631
  { name: 'ā–¶ļø Resume all triggers for a connection', value: 'resumeConn' },
1609
1632
  { name: 'šŸ—‘ļø Delete a trigger', value: 'delete' },
1610
- { name: '← Back', value: 'back' }
1611
- ]
1612
- }
1633
+ { name: '← Back', value: 'back' },
1634
+ ],
1635
+ },
1613
1636
  ]);
1614
1637
  if (!actionAnswer || actionAnswer.action === 'back')
1615
1638
  return;
@@ -1641,7 +1664,7 @@ async function webhooksInteractiveMenu(context) {
1641
1664
  * List all webhook subscriptions
1642
1665
  */
1643
1666
  async function webhooksListFlow(context, jsonOutput = false) {
1644
- writeProgress("šŸ”„ Loading triggers...");
1667
+ writeProgress('šŸ”„ Loading triggers...');
1645
1668
  try {
1646
1669
  const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
1647
1670
  if (!result.success) {
@@ -1657,7 +1680,7 @@ async function webhooksListFlow(context, jsonOutput = false) {
1657
1680
  if (jsonOutput) {
1658
1681
  // Output as JSON for scripting
1659
1682
  console.log(JSON.stringify({
1660
- triggers: webhooks.map(wh => ({
1683
+ triggers: webhooks.map((wh) => ({
1661
1684
  id: wh.id,
1662
1685
  integrationType: wh.integrationType,
1663
1686
  objectType: wh.objectType,
@@ -1674,13 +1697,13 @@ async function webhooksListFlow(context, jsonOutput = false) {
1674
1697
  }, null, 2));
1675
1698
  return;
1676
1699
  }
1677
- console.log("\n" + "─".repeat(60));
1678
- console.log("⚔ Triggers / Webhook Subscriptions");
1679
- console.log("─".repeat(60) + "\n");
1700
+ console.log('\n' + '─'.repeat(60));
1701
+ console.log('⚔ Triggers / Webhook Subscriptions');
1702
+ console.log('─'.repeat(60) + '\n');
1680
1703
  if (webhooks.length === 0) {
1681
- console.log("ā„¹ļø No triggers configured yet.\n");
1682
- console.log("šŸ’” Add triggers when connecting: lua integrations connect");
1683
- console.log(" Or add one now: lua integrations webhooks create\n");
1704
+ console.log('ā„¹ļø No triggers configured yet.\n');
1705
+ console.log('šŸ’” Add triggers when connecting: lua integrations connect');
1706
+ console.log(' Or add one now: lua integrations webhooks create\n');
1684
1707
  return;
1685
1708
  }
1686
1709
  // Group by integration
@@ -1726,7 +1749,7 @@ async function webhooksListFlow(context, jsonOutput = false) {
1726
1749
  }
1727
1750
  console.log();
1728
1751
  }
1729
- console.log("─".repeat(60));
1752
+ console.log('─'.repeat(60));
1730
1753
  console.log(`Total: ${webhooks.length} trigger(s)\n`);
1731
1754
  }
1732
1755
  catch (error) {
@@ -1742,7 +1765,7 @@ async function webhooksListFlow(context, jsonOutput = false) {
1742
1765
  * Pause a single webhook subscription (non-interactive)
1743
1766
  */
1744
1767
  async function webhooksPauseFlow(context, webhookId, reason) {
1745
- writeProgress("šŸ”„ Pausing trigger...");
1768
+ writeProgress('šŸ”„ Pausing trigger...');
1746
1769
  try {
1747
1770
  const result = await context.unifiedToApi.pauseWebhookSubscription(context.agentId, webhookId, reason);
1748
1771
  if (result.success) {
@@ -1764,7 +1787,7 @@ async function webhooksPauseFlow(context, webhookId, reason) {
1764
1787
  * Resume a single webhook subscription (non-interactive)
1765
1788
  */
1766
1789
  async function webhooksResumeFlow(context, webhookId) {
1767
- writeProgress("šŸ”„ Resuming trigger...");
1790
+ writeProgress('šŸ”„ Resuming trigger...');
1768
1791
  try {
1769
1792
  const result = await context.unifiedToApi.resumeWebhookSubscription(context.agentId, webhookId);
1770
1793
  if (result.success) {
@@ -1790,7 +1813,7 @@ async function webhooksResumeFlow(context, webhookId) {
1790
1813
  * Pause all triggers for a connection (non-interactive)
1791
1814
  */
1792
1815
  async function connectionPauseFlow(context, connectionId) {
1793
- writeProgress("šŸ”„ Pausing all triggers for connection...");
1816
+ writeProgress('šŸ”„ Pausing all triggers for connection...');
1794
1817
  try {
1795
1818
  const result = await context.unifiedToApi.pauseConnection(context.agentId, connectionId);
1796
1819
  if (result.success && result.data) {
@@ -1799,7 +1822,11 @@ async function connectionPauseFlow(context, connectionId) {
1799
1822
  console.log(` āš ļø ${result.data.failedWebhooks} trigger(s) failed to pause at Unified.to — check logs.\n`);
1800
1823
  }
1801
1824
  console.log(`\nšŸ’” Resume later with: lua integrations webhooks resume --connection-id ${connectionId}\n`);
1802
- trackEvent('cli_connection_paused', { connection_id: connectionId, affected: result.data.affectedWebhooks, failed: result.data.failedWebhooks });
1825
+ trackEvent('cli_connection_paused', {
1826
+ connection_id: connectionId,
1827
+ affected: result.data.affectedWebhooks,
1828
+ failed: result.data.failedWebhooks,
1829
+ });
1803
1830
  }
1804
1831
  else {
1805
1832
  writeError(`āŒ Failed to pause connection triggers: ${result.error?.message}`);
@@ -1813,7 +1840,7 @@ async function connectionPauseFlow(context, connectionId) {
1813
1840
  * Resume all triggers for a connection (non-interactive)
1814
1841
  */
1815
1842
  async function connectionResumeFlow(context, connectionId) {
1816
- writeProgress("šŸ”„ Resuming triggers for connection...");
1843
+ writeProgress('šŸ”„ Resuming triggers for connection...');
1817
1844
  try {
1818
1845
  const result = await context.unifiedToApi.resumeConnection(context.agentId, connectionId);
1819
1846
  if (result.success && result.data) {
@@ -1825,7 +1852,12 @@ async function connectionResumeFlow(context, connectionId) {
1825
1852
  if (result.data.failedWebhooks > 0) {
1826
1853
  console.log(` āš ļø ${result.data.failedWebhooks} trigger(s) failed to resume at Unified.to — check logs.\n`);
1827
1854
  }
1828
- trackEvent('cli_connection_resumed', { connection_id: connectionId, affected: result.data.affectedWebhooks, skipped_credit: result.data.skippedCreditSuspended, failed: result.data.failedWebhooks });
1855
+ trackEvent('cli_connection_resumed', {
1856
+ connection_id: connectionId,
1857
+ affected: result.data.affectedWebhooks,
1858
+ skipped_credit: result.data.skippedCreditSuspended,
1859
+ failed: result.data.failedWebhooks,
1860
+ });
1829
1861
  }
1830
1862
  else {
1831
1863
  writeError(`āŒ Failed to resume connection triggers: ${result.error?.message}`);
@@ -1839,16 +1871,16 @@ async function connectionResumeFlow(context, connectionId) {
1839
1871
  * Interactive: pause a single trigger
1840
1872
  */
1841
1873
  async function webhooksPauseInteractive(context) {
1842
- writeProgress("šŸ”„ Loading triggers...");
1874
+ writeProgress('šŸ”„ Loading triggers...');
1843
1875
  try {
1844
1876
  const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
1845
1877
  if (!result.success) {
1846
1878
  writeError(`āŒ Failed to load triggers: ${result.error?.message}`);
1847
1879
  return;
1848
1880
  }
1849
- const webhooks = (result.data || []).filter(wh => !wh.userPaused && wh.status !== 'unhealthy');
1881
+ const webhooks = (result.data || []).filter((wh) => !wh.userPaused && wh.status !== 'unhealthy');
1850
1882
  if (webhooks.length === 0) {
1851
- console.log("\nā„¹ļø No active triggers to pause.\n");
1883
+ console.log('\nā„¹ļø No active triggers to pause.\n');
1852
1884
  return;
1853
1885
  }
1854
1886
  const webhookAnswer = await safePrompt([
@@ -1856,11 +1888,11 @@ async function webhooksPauseInteractive(context) {
1856
1888
  type: 'list',
1857
1889
  name: 'webhook',
1858
1890
  message: 'Select a trigger to pause:',
1859
- choices: webhooks.map(wh => ({
1891
+ choices: webhooks.map((wh) => ({
1860
1892
  name: `${wh.integrationType} — ${wh.objectType}.${wh.event} (${wh.id.substring(0, 8)}...)`,
1861
1893
  value: wh.id,
1862
- }))
1863
- }
1894
+ })),
1895
+ },
1864
1896
  ]);
1865
1897
  if (!webhookAnswer?.webhook)
1866
1898
  return;
@@ -1870,10 +1902,10 @@ async function webhooksPauseInteractive(context) {
1870
1902
  name: 'confirm',
1871
1903
  message: `Pause this trigger?`,
1872
1904
  default: true,
1873
- }
1905
+ },
1874
1906
  ]);
1875
1907
  if (!confirmAnswer?.confirm) {
1876
- console.log("\nāŒ Cancelled.\n");
1908
+ console.log('\nāŒ Cancelled.\n');
1877
1909
  return;
1878
1910
  }
1879
1911
  await webhooksPauseFlow(context, webhookAnswer.webhook);
@@ -1886,16 +1918,16 @@ async function webhooksPauseInteractive(context) {
1886
1918
  * Interactive: resume a single trigger
1887
1919
  */
1888
1920
  async function webhooksResumeInteractive(context) {
1889
- writeProgress("šŸ”„ Loading triggers...");
1921
+ writeProgress('šŸ”„ Loading triggers...');
1890
1922
  try {
1891
1923
  const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
1892
1924
  if (!result.success) {
1893
1925
  writeError(`āŒ Failed to load triggers: ${result.error?.message}`);
1894
1926
  return;
1895
1927
  }
1896
- const webhooks = (result.data || []).filter(wh => wh.userPaused && !wh.creditSuspended);
1928
+ const webhooks = (result.data || []).filter((wh) => wh.userPaused && !wh.creditSuspended);
1897
1929
  if (webhooks.length === 0) {
1898
- console.log("\nā„¹ļø No user-paused triggers to resume.\n");
1930
+ console.log('\nā„¹ļø No user-paused triggers to resume.\n');
1899
1931
  return;
1900
1932
  }
1901
1933
  const webhookAnswer = await safePrompt([
@@ -1903,11 +1935,11 @@ async function webhooksResumeInteractive(context) {
1903
1935
  type: 'list',
1904
1936
  name: 'webhook',
1905
1937
  message: 'Select a trigger to resume:',
1906
- choices: webhooks.map(wh => ({
1938
+ choices: webhooks.map((wh) => ({
1907
1939
  name: `${wh.integrationType} — ${wh.objectType}.${wh.event} (${wh.id.substring(0, 8)}...)`,
1908
1940
  value: wh.id,
1909
- }))
1910
- }
1941
+ })),
1942
+ },
1911
1943
  ]);
1912
1944
  if (!webhookAnswer?.webhook)
1913
1945
  return;
@@ -1925,7 +1957,7 @@ async function connectionPauseInteractive(context) {
1925
1957
  const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
1926
1958
  const connections = connectionsResult.success ? connectionsResult.data || [] : [];
1927
1959
  if (connections.length === 0) {
1928
- console.log("\nā„¹ļø No connected integrations.\n");
1960
+ console.log('\nā„¹ļø No connected integrations.\n');
1929
1961
  return;
1930
1962
  }
1931
1963
  const connectionAnswer = await safePrompt([
@@ -1933,11 +1965,11 @@ async function connectionPauseInteractive(context) {
1933
1965
  type: 'list',
1934
1966
  name: 'connection',
1935
1967
  message: 'Select a connection to pause all triggers:',
1936
- choices: connections.map(c => ({
1968
+ choices: connections.map((c) => ({
1937
1969
  name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)${c.allTriggersPaused ? ' [all triggers paused]' : ''}`,
1938
1970
  value: c.id,
1939
- }))
1940
- }
1971
+ })),
1972
+ },
1941
1973
  ]);
1942
1974
  if (!connectionAnswer?.connection)
1943
1975
  return;
@@ -1947,10 +1979,10 @@ async function connectionPauseInteractive(context) {
1947
1979
  name: 'confirm',
1948
1980
  message: `Pause all triggers for this connection?`,
1949
1981
  default: true,
1950
- }
1982
+ },
1951
1983
  ]);
1952
1984
  if (!confirmAnswer?.confirm) {
1953
- console.log("\nāŒ Cancelled.\n");
1985
+ console.log('\nāŒ Cancelled.\n');
1954
1986
  return;
1955
1987
  }
1956
1988
  await connectionPauseFlow(context, connectionAnswer.connection);
@@ -1967,7 +1999,7 @@ async function connectionResumeInteractive(context) {
1967
1999
  const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
1968
2000
  const connections = connectionsResult.success ? connectionsResult.data || [] : [];
1969
2001
  if (connections.length === 0) {
1970
- console.log("\nā„¹ļø No connected integrations.\n");
2002
+ console.log('\nā„¹ļø No connected integrations.\n');
1971
2003
  return;
1972
2004
  }
1973
2005
  const connectionAnswer = await safePrompt([
@@ -1975,11 +2007,11 @@ async function connectionResumeInteractive(context) {
1975
2007
  type: 'list',
1976
2008
  name: 'connection',
1977
2009
  message: 'Select a connection to resume triggers:',
1978
- choices: connections.map(c => ({
2010
+ choices: connections.map((c) => ({
1979
2011
  name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
1980
2012
  value: c.id,
1981
- }))
1982
- }
2013
+ })),
2014
+ },
1983
2015
  ]);
1984
2016
  if (!connectionAnswer?.connection)
1985
2017
  return;
@@ -1994,7 +2026,7 @@ async function connectionResumeInteractive(context) {
1994
2026
  */
1995
2027
  async function webhooksCreateFlow(context, options) {
1996
2028
  // Step 1: Fetch connections
1997
- writeProgress("šŸ”„ Loading connections...");
2029
+ writeProgress('šŸ”„ Loading connections...');
1998
2030
  let connections = [];
1999
2031
  try {
2000
2032
  const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
@@ -2009,19 +2041,19 @@ async function webhooksCreateFlow(context, options) {
2009
2041
  return;
2010
2042
  }
2011
2043
  if (connections.length === 0) {
2012
- writeInfo("No connections available.");
2044
+ writeInfo('No connections available.');
2013
2045
  console.log("šŸ’” Run 'lua integrations connect' to connect an integration first.\n");
2014
2046
  return;
2015
2047
  }
2016
2048
  // Step 2: Select connection
2017
2049
  let selectedConnection;
2018
2050
  if (options.connectionId) {
2019
- selectedConnection = connections.find(c => c.id === options.connectionId);
2051
+ selectedConnection = connections.find((c) => c.id === options.connectionId);
2020
2052
  if (!selectedConnection) {
2021
2053
  console.error(`āŒ Connection "${options.connectionId}" not found.`);
2022
2054
  console.log('\nAvailable connections:');
2023
- connections.forEach(c => console.log(` - ${c.id} (${c.integrationName || c.integrationType})`));
2024
- throw new Error("Connection");
2055
+ connections.forEach((c) => console.log(` - ${c.id} (${c.integrationName || c.integrationType})`));
2056
+ throw new Error('Connection');
2025
2057
  }
2026
2058
  }
2027
2059
  else {
@@ -2030,18 +2062,18 @@ async function webhooksCreateFlow(context, options) {
2030
2062
  type: 'list',
2031
2063
  name: 'connection',
2032
2064
  message: 'Select a connection:',
2033
- choices: connections.map(c => ({
2065
+ choices: connections.map((c) => ({
2034
2066
  name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
2035
- value: c
2036
- }))
2037
- }
2067
+ value: c,
2068
+ })),
2069
+ },
2038
2070
  ]);
2039
2071
  if (!connectionAnswer)
2040
2072
  return;
2041
2073
  selectedConnection = connectionAnswer.connection;
2042
2074
  }
2043
2075
  // Step 3: Get available events for this connection
2044
- writeProgress("šŸ”„ Loading available events...");
2076
+ writeProgress('šŸ”„ Loading available events...');
2045
2077
  let availableEvents = [];
2046
2078
  try {
2047
2079
  const eventsResult = await context.unifiedToApi.getAvailableWebhookEvents(context.agentId, selectedConnection.id);
@@ -2057,18 +2089,18 @@ async function webhooksCreateFlow(context, options) {
2057
2089
  }
2058
2090
  if (availableEvents.length === 0) {
2059
2091
  writeInfo(`No trigger events available for ${selectedConnection.integrationName || selectedConnection.integrationType}.`);
2060
- console.log("šŸ’” This integration may not support triggers.\n");
2092
+ console.log('šŸ’” This integration may not support triggers.\n');
2061
2093
  return;
2062
2094
  }
2063
2095
  // Step 4: Select event
2064
2096
  let selectedEvent;
2065
2097
  if (options.objectType && options.event) {
2066
- selectedEvent = availableEvents.find(e => e.objectType === options.objectType && e.event === options.event);
2098
+ selectedEvent = availableEvents.find((e) => e.objectType === options.objectType && e.event === options.event);
2067
2099
  if (!selectedEvent) {
2068
2100
  console.error(`āŒ Event '${options.objectType}.${options.event}' is not supported.`);
2069
2101
  console.log(`\nAvailable events for ${selectedConnection.integrationName || selectedConnection.integrationType}:`);
2070
- availableEvents.forEach(e => console.log(` - ${e.objectType}.${e.event} [${e.webhookType}]`));
2071
- throw new Error("Event");
2102
+ availableEvents.forEach((e) => console.log(` - ${e.objectType}.${e.event} [${e.webhookType}]`));
2103
+ throw new Error('Event');
2072
2104
  }
2073
2105
  }
2074
2106
  else {
@@ -2079,11 +2111,11 @@ async function webhooksCreateFlow(context, options) {
2079
2111
  name: 'event',
2080
2112
  message: 'Select an event to subscribe to:',
2081
2113
  pageSize: 15,
2082
- choices: availableEvents.map(e => ({
2114
+ choices: availableEvents.map((e) => ({
2083
2115
  name: `${e.objectTypeDisplay} - ${e.event.charAt(0).toUpperCase() + e.event.slice(1)} [${e.webhookType}]`,
2084
- value: e
2085
- }))
2086
- }
2116
+ value: e,
2117
+ })),
2118
+ },
2087
2119
  ]);
2088
2120
  if (!eventAnswer)
2089
2121
  return;
@@ -2112,7 +2144,7 @@ async function webhooksCreateFlow(context, options) {
2112
2144
  },
2113
2145
  ],
2114
2146
  default: 'agent',
2115
- }
2147
+ },
2116
2148
  ]);
2117
2149
  if (!urlModeAnswer)
2118
2150
  return;
@@ -2135,8 +2167,8 @@ async function webhooksCreateFlow(context, options) {
2135
2167
  catch {
2136
2168
  return 'Enter a valid URL (e.g., https://webhook.heylua.ai/myagent/handler)';
2137
2169
  }
2138
- }
2139
- }
2170
+ },
2171
+ },
2140
2172
  ]);
2141
2173
  if (!webhookAnswer)
2142
2174
  return;
@@ -2171,7 +2203,7 @@ async function webhooksCreateFlow(context, options) {
2171
2203
  message: 'Select polling interval:',
2172
2204
  choices: intervalOptions,
2173
2205
  default: 1,
2174
- }
2206
+ },
2175
2207
  ]);
2176
2208
  if (!intervalAnswer)
2177
2209
  return;
@@ -2180,35 +2212,35 @@ async function webhooksCreateFlow(context, options) {
2180
2212
  }
2181
2213
  // Helper to format interval display
2182
2214
  const formatInterval = (minutes) => {
2183
- const option = intervalOptions.find(o => o.value === minutes);
2215
+ const option = intervalOptions.find((o) => o.value === minutes);
2184
2216
  return option ? option.name : `${minutes} minutes`;
2185
2217
  };
2186
2218
  // Step 7: Confirmation (interactive only)
2187
2219
  if (!options.connectionId) {
2188
- console.log("\n" + "─".repeat(60));
2189
- console.log("šŸ“‹ Trigger Summary");
2190
- console.log("─".repeat(60));
2220
+ console.log('\n' + '─'.repeat(60));
2221
+ console.log('šŸ“‹ Trigger Summary');
2222
+ console.log('─'.repeat(60));
2191
2223
  console.log(` Connection: ${selectedConnection.integrationName || selectedConnection.integrationType}`);
2192
2224
  console.log(` Event: ${selectedEvent.objectType}.${selectedEvent.event} [${selectedEvent.webhookType}]`);
2193
2225
  console.log(` Webhook URL: ${hookUrl}`);
2194
2226
  if (interval)
2195
2227
  console.log(` Interval: ${formatInterval(interval)}`);
2196
- console.log("─".repeat(60) + "\n");
2228
+ console.log('─'.repeat(60) + '\n');
2197
2229
  const confirmAnswer = await safePrompt([
2198
2230
  {
2199
2231
  type: 'confirm',
2200
2232
  name: 'confirm',
2201
2233
  message: 'Create this trigger?',
2202
- default: true
2203
- }
2234
+ default: true,
2235
+ },
2204
2236
  ]);
2205
2237
  if (!confirmAnswer?.confirm) {
2206
- console.log("\nāŒ Cancelled.\n");
2238
+ console.log('\nāŒ Cancelled.\n');
2207
2239
  return;
2208
2240
  }
2209
2241
  }
2210
2242
  // Step 8: Create the webhook
2211
- writeProgress("šŸ”„ Creating trigger...");
2243
+ writeProgress('šŸ”„ Creating trigger...');
2212
2244
  try {
2213
2245
  const createResult = await context.unifiedToApi.createWebhookSubscription(context.agentId, {
2214
2246
  connectionId: selectedConnection.id,
@@ -2224,9 +2256,9 @@ async function webhooksCreateFlow(context, options) {
2224
2256
  const webhook = createResult.data;
2225
2257
  const isAgentTrigger = webhook.hookUrl.includes('webhook/unifiedto');
2226
2258
  const typeLabel = webhook.webhookType === 'native' ? 'push' : 'polling';
2227
- console.log("\n" + "─".repeat(60));
2228
- writeSuccess("āœ… Trigger created!");
2229
- console.log("─".repeat(60));
2259
+ console.log('\n' + '─'.repeat(60));
2260
+ writeSuccess('āœ… Trigger created!');
2261
+ console.log('─'.repeat(60));
2230
2262
  console.log(` Integration: ${webhook.integrationType}`);
2231
2263
  console.log(` Event: ${webhook.objectType}.${webhook.event}`);
2232
2264
  console.log(` Type: ${typeLabel}`);
@@ -2237,12 +2269,12 @@ async function webhooksCreateFlow(context, options) {
2237
2269
  if (webhook.interval)
2238
2270
  console.log(` Poll interval: ${formatInterval(webhook.interval)}`);
2239
2271
  console.log(` Status: ${webhook.status}`);
2240
- console.log("─".repeat(60) + "\n");
2272
+ console.log('─'.repeat(60) + '\n');
2241
2273
  if (isAgentTrigger) {
2242
- console.log("šŸ’” Your agent will now wake up when this event occurs.\n");
2274
+ console.log('šŸ’” Your agent will now wake up when this event occurs.\n');
2243
2275
  }
2244
2276
  else {
2245
- console.log("šŸ’” Ensure your webhook endpoint is ready to receive events.\n");
2277
+ console.log('šŸ’” Ensure your webhook endpoint is ready to receive events.\n');
2246
2278
  }
2247
2279
  }
2248
2280
  catch (error) {
@@ -2253,7 +2285,7 @@ async function webhooksCreateFlow(context, options) {
2253
2285
  * Delete a webhook subscription (interactive)
2254
2286
  */
2255
2287
  async function webhooksDeleteInteractive(context) {
2256
- writeProgress("šŸ”„ Loading triggers...");
2288
+ writeProgress('šŸ”„ Loading triggers...');
2257
2289
  try {
2258
2290
  const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
2259
2291
  if (!result.success) {
@@ -2262,7 +2294,7 @@ async function webhooksDeleteInteractive(context) {
2262
2294
  }
2263
2295
  const webhooks = result.data || [];
2264
2296
  if (webhooks.length === 0) {
2265
- console.log("\nā„¹ļø No triggers to delete.\n");
2297
+ console.log('\nā„¹ļø No triggers to delete.\n');
2266
2298
  return;
2267
2299
  }
2268
2300
  const webhookAnswer = await safePrompt([
@@ -2270,30 +2302,30 @@ async function webhooksDeleteInteractive(context) {
2270
2302
  type: 'list',
2271
2303
  name: 'webhook',
2272
2304
  message: 'Select a trigger to delete:',
2273
- choices: webhooks.map(wh => {
2305
+ choices: webhooks.map((wh) => {
2274
2306
  // Show last part of URL for readability
2275
2307
  const urlParts = (wh.hookUrl || '').split('/');
2276
2308
  const shortUrl = urlParts.length > 3 ? '.../' + urlParts.slice(-2).join('/') : wh.hookUrl || '';
2277
2309
  return {
2278
2310
  name: `${wh.id.substring(0, 8)}... - ${wh.integrationType} ${wh.objectType}.${wh.event} → ${shortUrl}`,
2279
- value: wh.id
2311
+ value: wh.id,
2280
2312
  };
2281
- })
2282
- }
2313
+ }),
2314
+ },
2283
2315
  ]);
2284
2316
  if (!webhookAnswer?.webhook)
2285
2317
  return;
2286
- const selectedWebhook = webhooks.find(wh => wh.id === webhookAnswer.webhook);
2318
+ const selectedWebhook = webhooks.find((wh) => wh.id === webhookAnswer.webhook);
2287
2319
  const confirmAnswer = await safePrompt([
2288
2320
  {
2289
2321
  type: 'confirm',
2290
2322
  name: 'confirm',
2291
2323
  message: `Delete trigger for ${selectedWebhook?.objectType}.${selectedWebhook?.event}?`,
2292
- default: false
2293
- }
2324
+ default: false,
2325
+ },
2294
2326
  ]);
2295
2327
  if (!confirmAnswer?.confirm) {
2296
- console.log("\nāŒ Cancelled.\n");
2328
+ console.log('\nāŒ Cancelled.\n');
2297
2329
  return;
2298
2330
  }
2299
2331
  await webhooksDeleteFlow(context, webhookAnswer.webhook);
@@ -2306,7 +2338,7 @@ async function webhooksDeleteInteractive(context) {
2306
2338
  * Delete a webhook subscription (non-interactive)
2307
2339
  */
2308
2340
  async function webhooksDeleteFlow(context, webhookId) {
2309
- writeProgress("šŸ”„ Deleting trigger...");
2341
+ writeProgress('šŸ”„ Deleting trigger...');
2310
2342
  try {
2311
2343
  const result = await context.unifiedToApi.deleteWebhookSubscription(context.agentId, webhookId);
2312
2344
  if (result.success) {
@@ -2344,7 +2376,7 @@ async function mcpManagementFlow(context, options, subAction) {
2344
2376
  }
2345
2377
  if (subAction === 'activate') {
2346
2378
  if (!options.connectionId) {
2347
- writeError("āŒ Missing required option: --connection <id>");
2379
+ writeError('āŒ Missing required option: --connection <id>');
2348
2380
  console.log("\nšŸ’” Use 'lua integrations mcp list' to see available connection IDs.\n");
2349
2381
  return;
2350
2382
  }
@@ -2353,7 +2385,7 @@ async function mcpManagementFlow(context, options, subAction) {
2353
2385
  }
2354
2386
  if (subAction === 'deactivate') {
2355
2387
  if (!options.connectionId) {
2356
- writeError("āŒ Missing required option: --connection <id>");
2388
+ writeError('āŒ Missing required option: --connection <id>');
2357
2389
  console.log("\nšŸ’” Use 'lua integrations mcp list' to see available connection IDs.\n");
2358
2390
  return;
2359
2391
  }
@@ -2370,9 +2402,9 @@ async function mcpManagementFlow(context, options, subAction) {
2370
2402
  { name: 'šŸ“‹ List connections with MCP status', value: 'list' },
2371
2403
  { name: 'āœ… Activate MCP server for a connection', value: 'activate' },
2372
2404
  { name: 'āøļø Deactivate MCP server for a connection', value: 'deactivate' },
2373
- { name: '← Back', value: 'back' }
2374
- ]
2375
- }
2405
+ { name: '← Back', value: 'back' },
2406
+ ],
2407
+ },
2376
2408
  ]);
2377
2409
  if (!actionAnswer || actionAnswer.action === 'back')
2378
2410
  return;
@@ -2392,11 +2424,11 @@ async function mcpManagementFlow(context, options, subAction) {
2392
2424
  * List all connections with their MCP server status
2393
2425
  */
2394
2426
  async function mcpListFlow(context) {
2395
- writeProgress("šŸ”„ Loading connections and MCP servers...");
2427
+ writeProgress('šŸ”„ Loading connections and MCP servers...');
2396
2428
  try {
2397
2429
  const [connectionsResult, mcpServers] = await Promise.all([
2398
2430
  context.unifiedToApi.getConnections(context.agentId),
2399
- fetchServersCore(context)
2431
+ fetchServersCore(context),
2400
2432
  ]);
2401
2433
  if (!connectionsResult.success) {
2402
2434
  writeError(`āŒ Failed to load connections: ${connectionsResult.error?.message}`);
@@ -2405,7 +2437,7 @@ async function mcpListFlow(context) {
2405
2437
  if (!mcpServers)
2406
2438
  return;
2407
2439
  const connections = connectionsResult.data || [];
2408
- const unifiedServers = mcpServers.filter(s => s.source === 'unifiedto');
2440
+ const unifiedServers = mcpServers.filter((s) => s.source === 'unifiedto');
2409
2441
  // Map connection IDs to MCP servers
2410
2442
  const serverByConnectionId = new Map();
2411
2443
  for (const server of unifiedServers) {
@@ -2414,12 +2446,12 @@ async function mcpListFlow(context) {
2414
2446
  serverByConnectionId.set(connectionMatch[1], server);
2415
2447
  }
2416
2448
  }
2417
- console.log("\n" + "─".repeat(80));
2418
- console.log("šŸ”Œ MCP Servers for Connections");
2419
- console.log("─".repeat(80) + "\n");
2449
+ console.log('\n' + '─'.repeat(80));
2450
+ console.log('šŸ”Œ MCP Servers for Connections');
2451
+ console.log('─'.repeat(80) + '\n');
2420
2452
  if (connections.length === 0) {
2421
- console.log("ā„¹ļø No connections found.\n");
2422
- console.log("šŸ’” Connect an integration with: lua integrations connect\n");
2453
+ console.log('ā„¹ļø No connections found.\n');
2454
+ console.log('šŸ’” Connect an integration with: lua integrations connect\n');
2423
2455
  return;
2424
2456
  }
2425
2457
  for (const conn of connections) {
@@ -2430,7 +2462,7 @@ async function mcpListFlow(context) {
2430
2462
  console.log(` Integration: ${conn.integrationName || conn.integrationType}`);
2431
2463
  console.log(` MCP Server: ${serverName}`);
2432
2464
  console.log(` Status: ${status}`);
2433
- console.log("─".repeat(80));
2465
+ console.log('─'.repeat(80));
2434
2466
  }
2435
2467
  console.log(`\nTotal: ${connections.length} connection(s)`);
2436
2468
  console.log("\nšŸ’” Use --connection <id> with 'activate' or 'deactivate' commands.\n");
@@ -2443,12 +2475,12 @@ async function mcpListFlow(context) {
2443
2475
  * Activate MCP server for a connection (non-interactive)
2444
2476
  */
2445
2477
  async function mcpActivateFlow(context, connectionId) {
2446
- writeProgress("šŸ”„ Finding MCP server for connection...");
2478
+ writeProgress('šŸ”„ Finding MCP server for connection...');
2447
2479
  try {
2448
2480
  const mcpServers = await fetchServersCore(context);
2449
2481
  if (!mcpServers)
2450
2482
  return;
2451
- const mcpServer = mcpServers.find(s => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
2483
+ const mcpServer = mcpServers.find((s) => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
2452
2484
  if (!mcpServer) {
2453
2485
  writeError(`āŒ No MCP server found for connection: ${connectionId}`);
2454
2486
  console.log("\nšŸ’” Make sure the connection exists. Use 'lua integrations list' to check.\n");
@@ -2464,12 +2496,12 @@ async function mcpActivateFlow(context, connectionId) {
2464
2496
  * Deactivate MCP server for a connection (non-interactive)
2465
2497
  */
2466
2498
  async function mcpDeactivateFlow(context, connectionId) {
2467
- writeProgress("šŸ”„ Finding MCP server for connection...");
2499
+ writeProgress('šŸ”„ Finding MCP server for connection...');
2468
2500
  try {
2469
2501
  const mcpServers = await fetchServersCore(context);
2470
2502
  if (!mcpServers)
2471
2503
  return;
2472
- const mcpServer = mcpServers.find(s => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
2504
+ const mcpServer = mcpServers.find((s) => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
2473
2505
  if (!mcpServer) {
2474
2506
  writeError(`āŒ No MCP server found for connection: ${connectionId}`);
2475
2507
  console.log("\nšŸ’” Make sure the connection exists. Use 'lua integrations list' to check.\n");
@@ -2485,11 +2517,11 @@ async function mcpDeactivateFlow(context, connectionId) {
2485
2517
  * Interactive flow for activating MCP server
2486
2518
  */
2487
2519
  async function mcpActivateInteractive(context) {
2488
- writeProgress("šŸ”„ Loading connections...");
2520
+ writeProgress('šŸ”„ Loading connections...');
2489
2521
  try {
2490
2522
  const [connectionsResult, mcpServers] = await Promise.all([
2491
2523
  context.unifiedToApi.getConnections(context.agentId),
2492
- fetchServersCore(context)
2524
+ fetchServersCore(context),
2493
2525
  ]);
2494
2526
  if (!connectionsResult.success) {
2495
2527
  writeError(`āŒ Failed to load connections: ${connectionsResult.error?.message}`);
@@ -2509,12 +2541,12 @@ async function mcpActivateInteractive(context) {
2509
2541
  }
2510
2542
  }
2511
2543
  // Filter to show only inactive MCP servers
2512
- const inactiveConnections = connections.filter(conn => {
2544
+ const inactiveConnections = connections.filter((conn) => {
2513
2545
  const server = serverByConnectionId.get(conn.id);
2514
2546
  return server && !server.active;
2515
2547
  });
2516
2548
  if (inactiveConnections.length === 0) {
2517
- writeInfo("ā„¹ļø All MCP servers are already active (or no connections found).\n");
2549
+ writeInfo('ā„¹ļø All MCP servers are already active (or no connections found).\n');
2518
2550
  return;
2519
2551
  }
2520
2552
  const connectionAnswer = await safePrompt([
@@ -2522,11 +2554,11 @@ async function mcpActivateInteractive(context) {
2522
2554
  type: 'list',
2523
2555
  name: 'connectionId',
2524
2556
  message: 'Select a connection to activate MCP:',
2525
- choices: inactiveConnections.map(conn => ({
2557
+ choices: inactiveConnections.map((conn) => ({
2526
2558
  name: `${conn.integrationName || conn.integrationType} (${conn.id.substring(0, 12)}...)`,
2527
- value: conn.id
2528
- }))
2529
- }
2559
+ value: conn.id,
2560
+ })),
2561
+ },
2530
2562
  ]);
2531
2563
  if (!connectionAnswer)
2532
2564
  return;
@@ -2540,11 +2572,11 @@ async function mcpActivateInteractive(context) {
2540
2572
  * Interactive flow for deactivating MCP server
2541
2573
  */
2542
2574
  async function mcpDeactivateInteractive(context) {
2543
- writeProgress("šŸ”„ Loading connections...");
2575
+ writeProgress('šŸ”„ Loading connections...');
2544
2576
  try {
2545
2577
  const [connectionsResult, mcpServers] = await Promise.all([
2546
2578
  context.unifiedToApi.getConnections(context.agentId),
2547
- fetchServersCore(context)
2579
+ fetchServersCore(context),
2548
2580
  ]);
2549
2581
  if (!connectionsResult.success) {
2550
2582
  writeError(`āŒ Failed to load connections: ${connectionsResult.error?.message}`);
@@ -2564,12 +2596,12 @@ async function mcpDeactivateInteractive(context) {
2564
2596
  }
2565
2597
  }
2566
2598
  // Filter to show only active MCP servers
2567
- const activeConnections = connections.filter(conn => {
2599
+ const activeConnections = connections.filter((conn) => {
2568
2600
  const server = serverByConnectionId.get(conn.id);
2569
2601
  return server && server.active;
2570
2602
  });
2571
2603
  if (activeConnections.length === 0) {
2572
- writeInfo("ā„¹ļø No active MCP servers found to deactivate.\n");
2604
+ writeInfo('ā„¹ļø No active MCP servers found to deactivate.\n');
2573
2605
  return;
2574
2606
  }
2575
2607
  const connectionAnswer = await safePrompt([
@@ -2577,11 +2609,11 @@ async function mcpDeactivateInteractive(context) {
2577
2609
  type: 'list',
2578
2610
  name: 'connectionId',
2579
2611
  message: 'Select a connection to deactivate MCP:',
2580
- choices: activeConnections.map(conn => ({
2612
+ choices: activeConnections.map((conn) => ({
2581
2613
  name: `${conn.integrationName || conn.integrationType} (${conn.id.substring(0, 12)}...)`,
2582
- value: conn.id
2583
- }))
2584
- }
2614
+ value: conn.id,
2615
+ })),
2616
+ },
2585
2617
  ]);
2586
2618
  if (!connectionAnswer)
2587
2619
  return;