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
@@ -3,19 +3,44 @@
3
3
  * Orchestrates pushing skill versions to the server
4
4
  */
5
5
  import { compileCommand } from './compile.js';
6
- import { readYamlConfig, } from '../utils/files.js';
7
- import { withErrorHandling, writeProgress, writeSuccess, writeInfo, clearPromptLines } from '../utils/cli.js';
6
+ import { readYamlConfig } from '../utils/files.js';
7
+ import { withErrorHandling, writeProgress, writeSuccess, writeInfo, clearPromptLines, writeNextStep, writeHintBlock, writeTip, } from '../utils/cli.js';
8
8
  import { requireAuthOrExit } from '../utils/command-utils.js';
9
9
  import { safePrompt } from '../utils/prompt-handler.js';
10
10
  import { incrementPatchVersion, maxSemver } from '../utils/semver.js';
11
+ import { AuthenticationError } from '../errors/auth.error.js';
11
12
  import { BASE_URLS } from '../config/constants.js';
12
13
  import PersonaApi from '../api/persona.api.service.js';
13
14
  import { loadManifest, getPrimitivesByKind } from '../utils/artifact-loader.js';
15
+ import { ensureBundlesUploaded } from '../utils/bundle-upload.js';
14
16
  import { PrimitiveKind } from '../compiler/types.js';
15
17
  import { agentHandler } from '../primitives/agent.handler.js';
16
18
  import { skillHandler as skillH, webhookHandler as webhookH, jobHandler as jobH, preprocessorHandler as preprocessorH, postprocessorHandler as postprocessorH, deviceHandler as deviceH, deviceTriggerHandler as deviceTriggerH, } from '../primitives/index.js';
17
19
  import { pushBackupCommand } from './pushBackup.js';
20
+ import { buildLogsCommand } from './log-tip.js';
18
21
  import { trackEvent } from '../services/analytics.js';
22
+ import { validateOrSuggest } from '../utils/aliases.js';
23
+ export { pickPushAllNextStepVariant, formatPushFailureSummary } from './push-helpers.js';
24
+ import { pickPushAllNextStepVariant, formatPushFailureSummary } from './push-helpers.js';
25
+ /**
26
+ * Maps push target type to a valid `lua deploy …` follow-up (or null when
27
+ * there is no deploy CLI surface for that type — e.g. mcp, device, backup).
28
+ */
29
+ function getDeployHint(type) {
30
+ const deployableMap = {
31
+ skill: 'lua deploy skill',
32
+ webhook: 'lua deploy webhook',
33
+ job: 'lua deploy job',
34
+ preprocessor: 'lua deploy preprocessor',
35
+ postprocessor: 'lua deploy postprocessor',
36
+ agent: 'lua deploy persona',
37
+ persona: 'lua deploy persona',
38
+ };
39
+ const cmd = deployableMap[type];
40
+ if (!cmd)
41
+ return null;
42
+ return { label: 'Deploy:', command: cmd };
43
+ }
19
44
  // ============================================================================
20
45
  // Core Push Helpers (shared by all push functions)
21
46
  // ============================================================================
@@ -29,25 +54,25 @@ async function promptVersionConfirmOrUpdate(currentVersion) {
29
54
  console.log(`\nCurrent version: ${currentVersion || '(none - first push)'}`);
30
55
  const answer = await safePrompt([
31
56
  {
32
- type: "input",
33
- name: "newVersion",
34
- message: "Enter new version to push:",
57
+ type: 'input',
58
+ name: 'newVersion',
59
+ message: 'Enter new version to push:',
35
60
  default: incrementPatchVersion(currentVersion),
36
61
  validate: (input) => {
37
- if (!input || input.trim() === "") {
38
- return "Version cannot be empty";
62
+ if (!input || input.trim() === '') {
63
+ return 'Version cannot be empty';
39
64
  }
40
65
  // Basic semver validation
41
66
  const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
42
67
  if (!semverRegex.test(input.trim())) {
43
- return "Version must follow semver format (e.g., 1.0.0, 1.0.0-alpha.1)";
68
+ return 'Version must follow semver format (e.g., 1.0.0, 1.0.0-alpha.1)';
44
69
  }
45
70
  return true;
46
- }
47
- }
71
+ },
72
+ },
48
73
  ]);
49
74
  if (!answer) {
50
- console.log("Push cancelled.");
75
+ console.log('Push cancelled.');
51
76
  process.exit(0);
52
77
  }
53
78
  clearPromptLines(2);
@@ -73,7 +98,7 @@ async function selectEntityOrFail(items, options, config) {
73
98
  }
74
99
  // Non-interactive: find by name
75
100
  if (options.entityName) {
76
- const found = items.find((item) => nameFields.some(field => item[field] === options.entityName));
101
+ const found = items.find((item) => nameFields.some((field) => item[field] === options.entityName));
77
102
  if (!found) {
78
103
  throw new Error(`${entityType} "${options.entityName}" not found`);
79
104
  }
@@ -93,12 +118,12 @@ async function selectEntityOrFail(items, options, config) {
93
118
  message: `Select a ${entityType} to push:`,
94
119
  choices: items.map((item) => ({
95
120
  name: formatChoice ? formatChoice(item) : `${item.name} (v${item.version})`,
96
- value: item
97
- }))
98
- }
121
+ value: item,
122
+ })),
123
+ },
99
124
  ]);
100
125
  if (!answer) {
101
- console.log("Push cancelled.");
126
+ console.log('Push cancelled.');
102
127
  process.exit(0);
103
128
  }
104
129
  writeInfo(`šŸ“¦ Selected ${entityType}: ${answer.selected.name}`);
@@ -128,8 +153,6 @@ async function resolveVersionOrFail(currentVersion, options, highestKnownVersion
128
153
  // Otherwise, prompt interactively
129
154
  return await promptVersionConfirmOrUpdate(currentVersion);
130
155
  }
131
- /**
132
-
133
156
  /**
134
157
  * Determines if we should deploy after push based on options or prompt
135
158
  */
@@ -148,8 +171,8 @@ async function shouldDeployAfterPush(options) {
148
171
  type: 'confirm',
149
172
  name: 'deployNow',
150
173
  message: 'Would you like to deploy this version to production now?',
151
- default: false
152
- }
174
+ default: false,
175
+ },
153
176
  ]);
154
177
  return answer?.deployNow || false;
155
178
  }
@@ -163,12 +186,12 @@ async function shouldDeployAfterPush(options) {
163
186
  async function pushVersionedPrimitive(handler, options = {}) {
164
187
  try {
165
188
  // Step 1: Compile
166
- writeProgress("šŸ“¦ Compiling project...");
189
+ writeProgress('šŸ“¦ Compiling project...');
167
190
  await compileCommand();
168
- writeSuccess("āœ… Compilation complete");
191
+ writeSuccess('āœ… Compilation complete');
169
192
  // Step 2: Authenticate
170
193
  const apiKey = await authenticateOrFail();
171
- writeSuccess("āœ… Authentication verified");
194
+ writeSuccess('āœ… Authentication verified');
172
195
  // Step 3: Read config
173
196
  const config = readYamlConfig();
174
197
  if (!config?.agent?.agentId) {
@@ -182,22 +205,32 @@ async function pushVersionedPrimitive(handler, options = {}) {
182
205
  }
183
206
  const selected = await selectEntityOrFail(items, options, {
184
207
  entityType: handler.displayName,
185
- nameFields: ['id', handler.yamlConfig.idField, 'name']
208
+ nameFields: ['id', handler.yamlConfig.idField, 'name'],
186
209
  });
187
210
  const entityId = selected[handler.yamlConfig.idField];
188
211
  if (!entityId) {
189
212
  throw new Error(`${handler.displayName} "${selected.name}" has no server ID. Run 'lua compile' first.`);
190
213
  }
191
- // Step 5: Load bundled data
214
+ // Step 5: Load bundled data — accumulate raw gzip blobs for presigned upload (BAC-196)
192
215
  const manifest = loadManifest();
193
- const pushData = handler.prepareForPush(manifest, selected.name);
216
+ const bundleAccumulator = new Map();
217
+ const pushData = handler.prepareForPush(manifest, selected.name, undefined, bundleAccumulator);
194
218
  if (!pushData) {
195
219
  throw new Error(`${handler.displayName} "${selected.name}" not found in compiled output.`);
196
220
  }
221
+ // Step 5b: Upload missing blobs to S3 via presigned PUT, skip ones already there.
222
+ let bundleStats = {
223
+ total: 0,
224
+ alreadyExisted: 0,
225
+ uploaded: 0,
226
+ };
227
+ if (bundleAccumulator.size > 0) {
228
+ writeProgress(`šŸ“¤ Uploading ${bundleAccumulator.size} bundle(s) to S3...`);
229
+ bundleStats = await ensureBundlesUploaded(apiKey, agentId, bundleAccumulator);
230
+ writeSuccess('āœ… Bundles uploaded');
231
+ }
197
232
  // Step 6: Resolve version (check server for highest to avoid conflicts)
198
- const serverHighest = options.force
199
- ? await handler.getHighestServerVersion(apiKey, agentId, entityId)
200
- : undefined;
233
+ const serverHighest = options.force ? await handler.getHighestServerVersion(apiKey, agentId, entityId) : undefined;
201
234
  const confirmedVersion = await resolveVersionOrFail(selected.version, options, serverHighest ?? undefined);
202
235
  if (confirmedVersion !== selected.version) {
203
236
  handler.updateVersionInYaml(selected.name, confirmedVersion);
@@ -206,16 +239,29 @@ async function pushVersionedPrimitive(handler, options = {}) {
206
239
  writeProgress(`\nšŸš€ Pushing ${selected.name} v${confirmedVersion} to server...`);
207
240
  const result = await handler.pushToServer(apiKey, agentId, entityId, { ...pushData, version: confirmedVersion });
208
241
  if (!result.success) {
242
+ const isVersionConflict = result.error?.toLowerCase().includes('already exists');
243
+ if (isVersionConflict) {
244
+ writeHintBlock({
245
+ headline: 'Version conflict — this version already exists on the server.',
246
+ lines: [
247
+ { label: 'Auto-bump:', command: `lua push ${handler.kind} --force` },
248
+ { label: 'Or push all:', command: 'lua push all --force' },
249
+ ],
250
+ when: 'error',
251
+ });
252
+ }
253
+ // Push rejected — the reason is already on screen in the error above.
254
+ // No lua logs hint here: the push never ran, so no execution logs exist.
209
255
  throw new Error(`Push Error: ${result.error || 'Unknown error'}`);
210
256
  }
211
257
  writeSuccess(`\nāœ… Successfully pushed ${selected.name} v${confirmedVersion}\n`);
212
258
  // Step 8: Deploy if requested
213
259
  if (await shouldDeployAfterPush(options)) {
214
- await genericDeployAfterPush(handler, apiKey, agentId, entityId, selected.name, confirmedVersion, options.autoDeploy || false);
215
- }
216
- else {
217
- writeInfo(`šŸ’” You can deploy later using: lua ${handler.displayNamePlural} production`);
260
+ const deployedOk = await genericDeployAfterPush(handler, apiKey, agentId, entityId, selected.name, confirmedVersion, options.autoDeploy || false);
261
+ return { productionDeploySucceeded: deployedOk, bundleStats };
218
262
  }
263
+ return { productionDeploySucceeded: false, bundleStats };
264
+ // Staging vs deployed hints run in pushCommand — avoid duplicates here (H8).
219
265
  }
220
266
  catch (error) {
221
267
  throw error;
@@ -227,31 +273,45 @@ async function pushVersionedPrimitive(handler, options = {}) {
227
273
  async function genericDeployAfterPush(handler, apiKey, agentId, entityId, entityName, version, skipConfirmation = false) {
228
274
  try {
229
275
  if (!skipConfirmation) {
230
- console.log("\nāš ļø WARNING: You are about to deploy to PRODUCTION!");
231
- console.log("āš ļø This will affect ALL users immediately.\n");
232
- const confirmAnswer = await safePrompt([{
276
+ console.log('\nāš ļø WARNING: You are about to deploy to PRODUCTION!');
277
+ console.log('āš ļø This will affect ALL users immediately.\n');
278
+ const confirmAnswer = await safePrompt([
279
+ {
233
280
  type: 'confirm',
234
281
  name: 'confirm',
235
282
  message: 'Are you absolutely sure you want to deploy?',
236
- default: false
237
- }]);
283
+ default: false,
284
+ },
285
+ ]);
238
286
  if (!confirmAnswer || !confirmAnswer.confirm) {
239
- console.log("\nāŒ Deployment cancelled. Version pushed but not deployed.\n");
240
- return;
287
+ console.log('\nāŒ Deployment cancelled. Version pushed but not deployed.\n');
288
+ return false;
241
289
  }
242
290
  }
243
291
  writeProgress(`šŸ”„ Publishing ${handler.displayName} version...`);
244
- const result = await handler.publishVersion(apiKey, agentId, entityId, version);
245
- if (!result.success) {
246
- console.error(`\nāŒ Deploy Error: ${result.error || 'Unknown error'}\n`);
247
- return;
292
+ writeInfo('ā±ļø Waiting for server to process the new version (3 seconds)...');
293
+ await new Promise((resolve) => setTimeout(resolve, 3000));
294
+ const deployed = await retryDeploy(async () => {
295
+ const result = await handler.publishVersion(apiKey, agentId, entityId, version);
296
+ if (!result.success)
297
+ throw new Error(result.error || 'Deploy failed');
298
+ }, entityName, version, 3);
299
+ if (!deployed) {
300
+ console.error(`\nāŒ Deploy Error: failed after retries\n`);
301
+ // Deploy is a management operation — no execution logs exist for a failed deploy.
302
+ // Suggest retrying via the deploy command.
303
+ writeTip(`Deploy later with: lua deploy ${handler.kind}`);
304
+ return false;
248
305
  }
249
306
  writeSuccess(`\nāœ… ${entityName} v${version} deployed to production\n`);
250
307
  writeInfo(`šŸ’” The new ${handler.displayName} version is now active.`);
308
+ return true;
251
309
  }
252
310
  catch (error) {
253
311
  console.error(`\nāŒ Error deploying ${handler.displayName}:`, error);
254
- console.log(`šŸ’” You can deploy later using: lua ${handler.displayNamePlural} production\n`);
312
+ // Deploy is a management operation — no execution logs exist for a failed deploy.
313
+ writeTip(`Deploy later with: lua deploy ${handler.kind}`);
314
+ return false;
255
315
  }
256
316
  }
257
317
  /**
@@ -272,9 +332,17 @@ export async function pushCommand(type, cmdObj) {
272
332
  force: cmdObj?.force || false,
273
333
  autoDeploy: cmdObj?.autoDeploy || false,
274
334
  entityName: cmdObj?.name || null,
275
- version: cmdObj?.setVersion || null
335
+ version: cmdObj?.setVersion || null,
276
336
  };
337
+ let agentOutcome;
277
338
  let selectedType;
339
+ /** Present only after a versioned-primitive route; indicates production publish success after optional deploy. */
340
+ let versionedPushDeployResult;
341
+ // Normalize alias first (e.g. 'everything' → 'all', 'skills' → 'skill')
342
+ // so that the early 'all' guard below can catch aliases like 'everything'
343
+ if (type) {
344
+ type = validateOrSuggest('push.type', type, { allowAll: true });
345
+ }
278
346
  // Handle 'all' type with force flag
279
347
  if (type === 'all') {
280
348
  if (!options.force) {
@@ -292,27 +360,7 @@ export async function pushCommand(type, cmdObj) {
292
360
  console.log(' lua push webhook --name myWebhook --set-version 2.0.0 Push specific webhook');
293
361
  throw new Error('Type must be specified when using the --name option.');
294
362
  }
295
- // Step 1: Check if type was provided as argument
296
363
  if (type) {
297
- // Validate the provided type
298
- const validTypes = ['skill', 'agent', 'persona', 'webhook', 'job', 'preprocessor', 'postprocessor', 'mcp', 'device', 'device-trigger', 'backup'];
299
- if (!validTypes.includes(type)) {
300
- console.log('\nUsage:');
301
- console.log(' lua push - Interactive selection');
302
- console.log(' lua push skill - Push a skill directly');
303
- console.log(' lua push agent - Push agent config (persona, model)');
304
- console.log(' lua push webhook - Push a webhook directly');
305
- console.log(' lua push job - Push a job directly');
306
- console.log(' lua push preprocessor - Push a preprocessor directly');
307
- console.log(' lua push postprocessor - Push a postprocessor directly');
308
- console.log(' lua push mcp - Push an MCP server directly');
309
- console.log(' lua push backup - Push project source backup');
310
- console.log(' lua push all --force - Push all components without prompts');
311
- throw new Error(`Invalid type: "${type}". Must be one of: ${validTypes.join(', ')}, or "all".`);
312
- }
313
- // 'persona' is an alias for 'agent' (backward compatibility)
314
- if (type === 'persona')
315
- type = 'agent';
316
364
  selectedType = type;
317
365
  }
318
366
  else {
@@ -332,46 +380,51 @@ export async function pushCommand(type, cmdObj) {
332
380
  { name: 'šŸ“” Device', value: 'device' },
333
381
  { name: 'šŸ“” Device Trigger', value: 'device-trigger' },
334
382
  { name: 'šŸ¤– Agent (persona, model)', value: 'agent' },
335
- { name: 'šŸ’¾ Backup (source files)', value: 'backup' }
336
- ]
337
- }
383
+ { name: 'šŸ’¾ Backup (source files)', value: 'backup' },
384
+ ],
385
+ },
338
386
  ]);
339
387
  if (!typeAnswer) {
340
- console.log("Push cancelled.");
388
+ console.log('Push cancelled.');
341
389
  return;
342
390
  }
343
391
  selectedType = typeAnswer.type;
344
392
  }
345
393
  // Step 3: Route to appropriate function
346
394
  if (selectedType === 'skill') {
347
- await pushVersionedPrimitive(skillH, options);
395
+ versionedPushDeployResult = await pushVersionedPrimitive(skillH, options);
348
396
  }
349
397
  else if (selectedType === 'webhook') {
350
- await pushVersionedPrimitive(webhookH, options);
398
+ versionedPushDeployResult = await pushVersionedPrimitive(webhookH, options);
351
399
  }
352
400
  else if (selectedType === 'job') {
353
- await pushVersionedPrimitive(jobH, options);
401
+ versionedPushDeployResult = await pushVersionedPrimitive(jobH, options);
354
402
  }
355
403
  else if (selectedType === 'preprocessor') {
356
- await pushVersionedPrimitive(preprocessorH, options);
404
+ versionedPushDeployResult = await pushVersionedPrimitive(preprocessorH, options);
357
405
  }
358
406
  else if (selectedType === 'postprocessor') {
359
- await pushVersionedPrimitive(postprocessorH, options);
407
+ versionedPushDeployResult = await pushVersionedPrimitive(postprocessorH, options);
360
408
  }
361
409
  else if (selectedType === 'device') {
362
- await pushVersionedPrimitive(deviceH, options);
410
+ versionedPushDeployResult = await pushVersionedPrimitive(deviceH, options);
363
411
  }
364
412
  else if (selectedType === 'device-trigger') {
365
- await pushVersionedPrimitive(deviceTriggerH, options);
413
+ versionedPushDeployResult = await pushVersionedPrimitive(deviceTriggerH, options);
366
414
  }
367
415
  else if (selectedType === 'mcp') {
368
- await pushMCPServer(options);
416
+ const mcpActivated = await pushMCPServer(options);
417
+ // B10: thread activation status so the final hint knows whether MCP is live.
418
+ versionedPushDeployResult = { productionDeploySucceeded: mcpActivated };
369
419
  }
370
420
  else if (selectedType === 'backup') {
371
421
  await pushBackupCommand({ force: options.force });
372
422
  }
373
423
  else if (selectedType === 'agent') {
374
- await pushAgentVersion(options);
424
+ agentOutcome = await pushAgentVersion(options);
425
+ }
426
+ if (agentOutcome?.cancelled) {
427
+ return;
375
428
  }
376
429
  trackEvent('cli_push_completed', {
377
430
  primitive_type: selectedType,
@@ -380,8 +433,79 @@ export async function pushCommand(type, cmdObj) {
380
433
  entity_selected_by_name: !!options.entityName,
381
434
  type_selected_by_arg: !!type,
382
435
  version_specified: !!options.version,
436
+ // BAC-196 presigned-upload telemetry. `bundles_total` = unique
437
+ // content-hashes referenced by this push; `bundles_uploaded` = hashes
438
+ // the server reported missing and we PUT to S3; `bundles_existed`
439
+ // measures delta-upload hit rate. Zero for non-versioned types
440
+ // (mcp/agent/backup) — they don't go through the S3 path.
441
+ bundles_total: versionedPushDeployResult?.bundleStats?.total ?? 0,
442
+ bundles_uploaded: versionedPushDeployResult?.bundleStats?.uploaded ?? 0,
443
+ bundles_existed: versionedPushDeployResult?.bundleStats?.alreadyExisted ?? 0,
383
444
  });
384
- }, "push");
445
+ const productionDeployedActually = versionedPushDeployResult?.productionDeploySucceeded === true ||
446
+ (!!agentOutcome && !agentOutcome.cancelled && agentOutcome.productionDeployedWithAutoDeploy);
447
+ const personaAutoDeployRanAndFailed = selectedType === 'agent' &&
448
+ options.autoDeploy &&
449
+ !!agentOutcome &&
450
+ !agentOutcome.cancelled &&
451
+ 'personaAutoDeployFailed' in agentOutcome &&
452
+ agentOutcome.personaAutoDeployFailed;
453
+ if (productionDeployedActually) {
454
+ writeHintBlock({
455
+ headline: 'Deployed to production. Generate test traffic first:',
456
+ lines: [
457
+ { label: 'Test:', command: `lua chat -e production -m "your test message"` },
458
+ { label: 'Inspect:', command: buildLogsCommand({ primitiveType: selectedType }) },
459
+ ],
460
+ when: 'success',
461
+ });
462
+ }
463
+ else {
464
+ const deployHint = getDeployHint(selectedType);
465
+ if (personaAutoDeployRanAndFailed) {
466
+ const lines = [];
467
+ if (deployHint) {
468
+ lines.push(deployHint);
469
+ }
470
+ else if (selectedType === 'mcp') {
471
+ lines.push({
472
+ label: 'Activate:',
473
+ command: 'use the Lua dashboard or: lua push mcp --force --auto-deploy (requires --name when multiple MCP servers)',
474
+ });
475
+ }
476
+ lines.push({
477
+ label: 'Or re-push:',
478
+ command: selectedType === 'mcp'
479
+ ? 'lua push mcp --force --auto-deploy'
480
+ : `lua push ${selectedType} --force --auto-deploy`,
481
+ });
482
+ writeHintBlock({
483
+ headline: 'Push completed — production persona deploy did not succeed. Try:',
484
+ lines,
485
+ when: 'partial',
486
+ });
487
+ }
488
+ else if (selectedType === 'backup') {
489
+ // Backup is not a "live" primitive; skip staged-vs-live framing.
490
+ }
491
+ else if (deployHint) {
492
+ writeHintBlock({
493
+ headline: 'Staged but NOT live yet. To make it active:',
494
+ lines: [deployHint, { label: 'Or re-push:', command: `lua push ${selectedType} --force --auto-deploy` }],
495
+ when: 'success',
496
+ });
497
+ }
498
+ else {
499
+ writeNextStep({
500
+ command: selectedType === 'mcp'
501
+ ? 'lua push mcp --force --auto-deploy'
502
+ : `lua push ${selectedType} --force --auto-deploy`,
503
+ rationale: 'to re-push with auto-activation',
504
+ when: 'success',
505
+ });
506
+ }
507
+ }
508
+ }, 'push');
385
509
  }
386
510
  /**
387
511
  * Push agent configuration (persona, model/modelResolver) to the server.
@@ -408,13 +532,13 @@ async function pushAgentVersion(options = {}) {
408
532
  const model = agent?.model;
409
533
  const hasModelResolver = agent?.hasModelResolver;
410
534
  if (!persona?.trim() && !model && !hasModelResolver) {
411
- throw new Error("No agent configuration to push (no persona or model found).");
535
+ throw new Error('No agent configuration to push (no persona or model found).');
412
536
  }
413
537
  writeInfo(`šŸ“¦ Pushing agent config for: ${agentId}`);
414
538
  // Show preview
415
539
  if (persona) {
416
540
  const preview = persona.length > 200 ? persona.substring(0, 200) + '...' : persona;
417
- console.log("\nPersona preview:");
541
+ console.log('\nPersona preview:');
418
542
  console.log(preview);
419
543
  }
420
544
  if (model) {
@@ -428,28 +552,36 @@ async function pushAgentVersion(options = {}) {
428
552
  type: 'confirm',
429
553
  name: 'confirm',
430
554
  message: 'Push agent configuration to server?',
431
- default: true
432
- }
555
+ default: true,
556
+ },
433
557
  ]);
434
558
  if (!confirmAnswer || !confirmAnswer.confirm) {
435
- console.log("\nāŒ Push cancelled.\n");
436
- return;
559
+ console.log('\nāŒ Push cancelled.\n');
560
+ return { cancelled: true };
437
561
  }
438
562
  }
439
563
  // Authenticate
440
564
  const apiKey = await authenticateOrFail();
441
- writeProgress("āœ… Authenticated");
565
+ writeProgress('āœ… Authenticated');
442
566
  // Push via agentHandler
443
567
  const result = await agentHandler.pushAgentConfig(apiKey, agentId, manifest);
444
- // Deploy persona if requested and was pushed
445
- if (result.persona?.success && result.persona.version) {
446
- if (await shouldDeployAfterPush(options)) {
447
- await deployPersonaVersionAfterPush(apiKey, agentId, result.persona.version, options.autoDeploy || false);
568
+ let productionDeployedWithAutoDeploy = false;
569
+ let personaDeployWasAttempted = false;
570
+ const personaDeployEligible = !!(result.persona?.success && result.persona.version);
571
+ // B4: only ask about deploy when a persona was actually pushed — avoid the prompt
572
+ // when push failed or was a model-only push with no persona version created.
573
+ if (personaDeployEligible) {
574
+ const shouldDeploy = await shouldDeployAfterPush(options);
575
+ if (shouldDeploy) {
576
+ personaDeployWasAttempted = true;
577
+ productionDeployedWithAutoDeploy = await deployPersonaVersionAfterPush(apiKey, agentId, result.persona.version, options.autoDeploy || false);
448
578
  }
449
579
  else {
450
- writeInfo("šŸ’” You can deploy the persona version later using: lua deploy");
580
+ writeInfo('šŸ’” You can deploy the persona version later using: lua deploy');
451
581
  }
452
582
  }
583
+ const personaAutoDeployFailed = Boolean(options.autoDeploy && personaDeployEligible && personaDeployWasAttempted && !productionDeployedWithAutoDeploy);
584
+ return { cancelled: false, productionDeployedWithAutoDeploy, personaAutoDeployFailed };
453
585
  }
454
586
  /**
455
587
  * Deploy a persona version immediately after pushing
@@ -459,34 +591,38 @@ async function deployPersonaVersionAfterPush(apiKey, agentId, versionNum, skipCo
459
591
  // Skip confirmation when called from auto-deploy with --force
460
592
  if (!skipConfirmation) {
461
593
  // Show warning
462
- console.log("\nāš ļø WARNING: You are about to deploy to PRODUCTION!");
463
- console.log("āš ļø This will affect ALL users immediately.\n");
594
+ console.log('\nāš ļø WARNING: You are about to deploy to PRODUCTION!');
595
+ console.log('āš ļø This will affect ALL users immediately.\n');
464
596
  const confirmAnswer = await safePrompt([
465
597
  {
466
598
  type: 'confirm',
467
599
  name: 'confirm',
468
600
  message: 'Are you absolutely sure you want to deploy this persona version?',
469
- default: false
470
- }
601
+ default: false,
602
+ },
471
603
  ]);
472
604
  if (!confirmAnswer || !confirmAnswer.confirm) {
473
- console.log("\nāŒ Deployment cancelled. Persona version created but not deployed.\n");
474
- return;
605
+ console.log('\nāŒ Deployment cancelled. Persona version created but not deployed.\n');
606
+ return false;
475
607
  }
476
608
  }
477
- writeProgress("šŸ”„ Deploying persona version...");
609
+ writeProgress('šŸ”„ Deploying persona version...');
478
610
  const personaApi = new PersonaApi(BASE_URLS.API, apiKey, agentId);
479
611
  const deployResult = await personaApi.deployVersion(versionNum);
480
612
  if (!deployResult.success) {
481
613
  console.error(`\nāŒ Deploy Error: ${deployResult.error?.message || 'Unknown error'}\n`);
614
+ // Persona deploy is a management operation — no execution logs exist.
615
+ writeTip('Retry with: lua push agent');
482
616
  throw new Error(deployResult.error?.message || 'Failed to deploy persona version');
483
617
  }
484
618
  writeSuccess(`\nāœ… Persona version ${versionNum} deployed successfully to production\n`);
485
- writeInfo("šŸ’” The new persona is now active for all users.");
619
+ writeInfo('šŸ’” The new persona is now active for all users.');
620
+ return true;
486
621
  }
487
622
  catch (error) {
488
623
  console.error('\nāŒ Error deploying persona version:', error);
489
- console.log('šŸ’” You can deploy later using: lua persona\n');
624
+ writeTip('Retry with: lua push agent');
625
+ return false;
490
626
  }
491
627
  }
492
628
  /**
@@ -496,11 +632,11 @@ async function deployPersonaVersionAfterPush(apiKey, agentId, versionNum, skipCo
496
632
  */
497
633
  async function pushMCPServer(options = {}) {
498
634
  try {
499
- writeProgress("šŸ“¦ Compiling project...");
635
+ writeProgress('šŸ“¦ Compiling project...');
500
636
  await compileCommand();
501
- writeSuccess("āœ… Compilation complete");
637
+ writeSuccess('āœ… Compilation complete');
502
638
  const apiKey = await authenticateOrFail();
503
- writeSuccess("āœ… Authentication verified");
639
+ writeSuccess('āœ… Authentication verified');
504
640
  const config = readYamlConfig();
505
641
  if (!config?.agent?.agentId) {
506
642
  throw new Error("No agent ID found. Run 'lua init' first.");
@@ -509,7 +645,7 @@ async function pushMCPServer(options = {}) {
509
645
  const { mcpServerHandler } = await import('../primitives/mcp-server.handler.js');
510
646
  const bundledServers = mcpServerHandler.loadBundledItems();
511
647
  if (bundledServers.length === 0) {
512
- throw new Error("No MCP servers found in compiled output.");
648
+ throw new Error('No MCP servers found in compiled output.');
513
649
  }
514
650
  const selectedServer = await selectEntityOrFail(bundledServers, options, {
515
651
  entityType: 'MCP server',
@@ -520,19 +656,25 @@ async function pushMCPServer(options = {}) {
520
656
  // upsertOnServer persists the returned id into lua.skill.yaml on success.
521
657
  const result = await mcpServerHandler.upsertOnServer(apiKey, agentId, selectedServer);
522
658
  if (!result.success) {
659
+ // Push rejected — reason already on screen; no execution logs exist for a failed push.
523
660
  throw new Error(`Failed: ${result.error}`);
524
661
  }
525
662
  writeSuccess(`\nāœ… MCP server "${selectedServer.name}" pushed successfully\n`);
526
- if (result.id && await shouldDeployAfterPush(options)) {
527
- writeProgress("šŸ”„ Activating MCP server...");
663
+ let activated = false;
664
+ if (result.id && (await shouldDeployAfterPush(options))) {
665
+ writeProgress('šŸ”„ Activating MCP server...');
528
666
  const activateResult = await mcpServerHandler.activate(apiKey, agentId, result.id);
529
- if (activateResult.success)
667
+ if (activateResult.success) {
530
668
  writeSuccess(`āœ… MCP server activated\n`);
669
+ activated = true;
670
+ }
531
671
  }
672
+ return activated;
532
673
  }
533
674
  catch (error) {
534
675
  throw error;
535
676
  }
677
+ return false; // unreachable — catch always rethrows
536
678
  }
537
679
  /**
538
680
  * Push all command - Pushes all components (skills, webhooks, jobs, processors) without prompts
@@ -547,12 +689,12 @@ async function pushMCPServer(options = {}) {
547
689
  * @param options - Command options (force is required, autoDeploy is optional)
548
690
  */
549
691
  async function pushAllCommand(options) {
550
- writeProgress("šŸš€ Push All - Pushing all components to server...\n");
692
+ writeProgress('šŸš€ Push All - Pushing all components to server...\n');
551
693
  if (options.autoDeploy) {
552
- writeInfo("šŸš€ Auto-deploy to production is ENABLED\n");
694
+ writeInfo('šŸš€ Auto-deploy to production is ENABLED\n');
553
695
  }
554
696
  // Step 1: Compile first
555
- writeProgress("šŸ“¦ Compiling project...");
697
+ writeProgress('šŸ“¦ Compiling project...');
556
698
  await compileCommand();
557
699
  // Step 2: Load configuration and API key
558
700
  const config = readYamlConfig();
@@ -572,22 +714,44 @@ async function pushAllCommand(options) {
572
714
  // Track results and deploy queue per handler
573
715
  const allResults = [];
574
716
  const toDeploy = [];
717
+ // Per-item failures collected across all push surfaces (versioned
718
+ // primitives + MCP). Drives the post-run aggregate `āš ļø N component(s)
719
+ // failed` block and the final partial/error writeNextStep variant.
720
+ const failedItems = [];
721
+ let deployFailedCount = 0;
575
722
  let personaPushResult = null;
576
723
  let backupSuccess = false;
724
+ // BAC-196: aggregate bundle-upload stats across all primitives in the run.
725
+ const bundleStatsAggregate = { total: 0, uploaded: 0, existed: 0 };
577
726
  // Icons per kind for display
578
727
  const kindIcons = {
579
- skill: 'šŸ“¦', webhook: 'šŸŖ', job: 'ā°', preprocessor: 'šŸ“„', postprocessor: 'šŸ“¤', device: 'šŸ“”',
728
+ skill: 'šŸ“¦',
729
+ webhook: 'šŸŖ',
730
+ job: 'ā°',
731
+ preprocessor: 'šŸ“„',
732
+ postprocessor: 'šŸ“¤',
733
+ device: 'šŸ“”',
580
734
  };
581
735
  // Step 4: Pre-fetch highest versions in parallel (one HTTP call per handler type)
582
- const handlers = [skillH, webhookH, jobH, preprocessorH, postprocessorH, deviceH, deviceTriggerH];
736
+ const handlers = [
737
+ skillH,
738
+ webhookH,
739
+ jobH,
740
+ preprocessorH,
741
+ postprocessorH,
742
+ deviceH,
743
+ deviceTriggerH,
744
+ ];
583
745
  // Collect entity IDs per handler and batch-fetch versions in parallel
584
- const handlerItems = handlers.map(handler => ({
746
+ const handlerItems = handlers
747
+ .map((handler) => ({
585
748
  handler,
586
749
  items: handler.getFromYaml(config).filter((item) => {
587
750
  const entityId = item[handler.yamlConfig.idField];
588
751
  return entityId && item.version;
589
752
  }),
590
- })).filter(h => h.items.length > 0);
753
+ }))
754
+ .filter((h) => h.items.length > 0);
591
755
  const versionMaps = await Promise.all(handlerItems.map(async ({ handler, items }) => {
592
756
  const entityIds = items.map((item) => item[handler.yamlConfig.idField]);
593
757
  const versions = await handler.batchGetHighestVersions(apiKey, agentId, entityIds);
@@ -607,11 +771,18 @@ async function pushAllCommand(options) {
607
771
  const handlerVersions = versionLookup.get(handler);
608
772
  for (const item of items) {
609
773
  try {
610
- const pushData = handler.prepareForPush(manifest, item.name);
774
+ const bundleAccumulator = new Map();
775
+ const pushData = handler.prepareForPush(manifest, item.name, undefined, bundleAccumulator);
611
776
  if (!pushData) {
612
777
  console.warn(`āš ļø ${handler.displayName} "${item.name}" not found in compiled output, skipping`);
613
778
  continue;
614
779
  }
780
+ if (bundleAccumulator.size > 0) {
781
+ const stats = await ensureBundlesUploaded(apiKey, agentId, bundleAccumulator);
782
+ bundleStatsAggregate.total += stats.total;
783
+ bundleStatsAggregate.uploaded += stats.uploaded;
784
+ bundleStatsAggregate.existed += stats.alreadyExisted;
785
+ }
615
786
  const entityId = item[handler.yamlConfig.idField];
616
787
  if (!entityId) {
617
788
  console.warn(`āš ļø ${handler.displayName} "${item.name}" has no server ID, skipping. Run 'lua compile' first.`);
@@ -624,12 +795,29 @@ async function pushAllCommand(options) {
624
795
  // Auto-bump version (use pre-fetched server version to avoid conflicts)
625
796
  const serverHighest = handlerVersions?.get(entityId) ?? null;
626
797
  const baseVersion = serverHighest ? maxSemver(item.version, serverHighest) : item.version;
627
- const newVersion = incrementPatchVersion(baseVersion);
798
+ let newVersion = incrementPatchVersion(baseVersion);
628
799
  writeInfo(` šŸ“ ${item.name}: ${item.version} → ${newVersion}`);
629
800
  // Push
630
- const result = await handler.pushToServer(apiKey, agentId, entityId, { ...pushData, version: newVersion });
801
+ let result = await handler.pushToServer(apiKey, agentId, entityId, { ...pushData, version: newVersion });
802
+ // On version collision, re-fetch the server's current highest version
803
+ // and try once more. The pre-fetch in step 4 is racey against
804
+ // concurrent pushes by the same/another user; a single re-bump
805
+ // resolves the dominant collision pattern observed in production.
806
+ if (!result.success && result.error?.toLowerCase().includes('already exists')) {
807
+ console.log(` āš ļø Version collision on ${item.name}, refetching server state and retrying...`);
808
+ const freshHighest = await handler.getHighestServerVersion(apiKey, agentId, entityId);
809
+ if (freshHighest) {
810
+ const retryVersion = incrementPatchVersion(freshHighest);
811
+ writeInfo(` šŸ“ ${item.name}: re-bumped ${newVersion} → ${retryVersion} after collision`);
812
+ result = await handler.pushToServer(apiKey, agentId, entityId, { ...pushData, version: retryVersion });
813
+ if (result.success) {
814
+ newVersion = retryVersion;
815
+ }
816
+ }
817
+ }
631
818
  if (!result.success) {
632
819
  console.error(` āŒ Failed to push ${item.name}: ${result.error}`);
820
+ failedItems.push({ kind: handler.kind, name: item.name, error: result.error || 'Unknown error' });
633
821
  continue;
634
822
  }
635
823
  handler.updateVersionInYaml(item.name, newVersion, { silent: true });
@@ -640,7 +828,14 @@ async function pushAllCommand(options) {
640
828
  }
641
829
  }
642
830
  catch (error) {
831
+ // Auth errors must propagate so withErrorHandling treats them as
832
+ // fatal, otherwise the loop continues against a known-broken auth
833
+ // state. Matches the re-throw pattern in batchGetHighestVersions /
834
+ // getHighestServerVersion.
835
+ if (AuthenticationError.isAuthenticationError(error))
836
+ throw error;
643
837
  console.error(` āŒ Failed to push ${item.name}: ${error.message}`);
838
+ failedItems.push({ kind: handler.kind, name: item.name, error: error.message || 'Unknown error' });
644
839
  }
645
840
  }
646
841
  }
@@ -650,9 +845,11 @@ async function pushAllCommand(options) {
650
845
  // when --auto-deploy is set. Here we only print the summary.
651
846
  const { mcpServerHandler: mcpH } = await import('../primitives/mcp-server.handler.js');
652
847
  const bundledMcp = mcpH.loadBundledItems();
848
+ let mcpPushedCount = 0; // tracks actual successes, not just attempts (B2)
653
849
  if (bundledMcp.length > 0) {
654
850
  writeProgress(`\nšŸ”Œ Pushing ${bundledMcp.length} MCP server(s)...`);
655
851
  const mcpResult = await mcpH.pushAll(bundledMcp, apiKey, agentId, { autoDeploy: options.autoDeploy });
852
+ mcpPushedCount = mcpResult.pushed.length;
656
853
  for (const name of mcpResult.pushed) {
657
854
  writeSuccess(` āœ… ${name}`);
658
855
  if (mcpResult.activated.includes(name))
@@ -660,8 +857,17 @@ async function pushAllCommand(options) {
660
857
  }
661
858
  for (const { name, error } of mcpResult.failed) {
662
859
  console.error(` āŒ Failed to push ${name}: ${error}`);
860
+ failedItems.push({ kind: 'mcp', name, error: error || 'Unknown error' });
663
861
  }
664
862
  }
863
+ // Aggregate failure block: emit a single grouped summary with a per-item
864
+ // `lua logs` diagnose hint so users can jump straight to the failing
865
+ // component's logs without scrolling back through interleaved push output.
866
+ // Printed before agent config push so the user sees component failures
867
+ // alongside the persona/backup status that follows.
868
+ if (failedItems.length > 0) {
869
+ console.error(formatPushFailureSummary(failedItems));
870
+ }
665
871
  // Step 6.5: Push agent config (persona, model/modelResolver)
666
872
  const agentPushResult = await agentHandler.pushAgentConfig(apiKey, agentId, manifest);
667
873
  if (agentPushResult.persona?.success) {
@@ -679,7 +885,7 @@ async function pushAllCommand(options) {
679
885
  if (options.autoDeploy && toDeploy.length > 0) {
680
886
  writeProgress('\nšŸš€ Deploying all pushed versions to production...');
681
887
  writeInfo('ā±ļø Waiting for server to process versions (5 seconds)...\n');
682
- await new Promise(resolve => setTimeout(resolve, 5000));
888
+ await new Promise((resolve) => setTimeout(resolve, 5000));
683
889
  for (const item of toDeploy) {
684
890
  const deployed = await retryDeploy(async () => {
685
891
  const result = await item.handler.publishVersion(apiKey, agentId, item.entityId, item.version);
@@ -691,6 +897,7 @@ async function pushAllCommand(options) {
691
897
  }
692
898
  else {
693
899
  console.warn(` āš ļø ${item.name} deployment failed`);
900
+ deployFailedCount++;
694
901
  }
695
902
  }
696
903
  }
@@ -707,6 +914,7 @@ async function pushAllCommand(options) {
707
914
  }
708
915
  else {
709
916
  console.warn(` āš ļø Persona deployment failed`);
917
+ deployFailedCount++;
710
918
  }
711
919
  }
712
920
  // Step 7.5: Push source backup (independent storage concern)
@@ -730,12 +938,16 @@ async function pushAllCommand(options) {
730
938
  byKind.get(kind).push(r);
731
939
  }
732
940
  const summaryIcons = {
733
- skills: 'šŸ› ļø ', webhooks: 'šŸŖ', jobs: 'ā°', preprocessors: 'šŸ“„', postprocessors: 'šŸ“¤',
941
+ skills: 'šŸ› ļø ',
942
+ webhooks: 'šŸŖ',
943
+ jobs: 'ā°',
944
+ preprocessors: 'šŸ“„',
945
+ postprocessors: 'šŸ“¤',
734
946
  };
735
947
  for (const [kind, items] of byKind) {
736
948
  const icon = summaryIcons[kind] || 'šŸ“¦';
737
949
  console.log(`${icon} ${kind.charAt(0).toUpperCase() + kind.slice(1)} (${items.length}):`);
738
- items.forEach(i => console.log(` • ${i.name} v${i.version}`));
950
+ items.forEach((i) => console.log(` • ${i.name} v${i.version}`));
739
951
  }
740
952
  if (personaPushResult) {
741
953
  console.log(`šŸŒ™ Persona:`);
@@ -758,11 +970,63 @@ async function pushAllCommand(options) {
758
970
  auto_deploy: options.autoDeploy || false,
759
971
  primitives_pushed_count: allResults.length,
760
972
  primitives_by_kind: kindCounts,
761
- mcp_servers_pushed: bundledMcp.length,
973
+ mcp_servers_pushed: mcpPushedCount,
762
974
  persona_pushed: !!personaPushResult,
763
975
  backup_pushed: backupSuccess,
976
+ // BAC-196 presigned-upload telemetry, summed across every primitive
977
+ // pushed in this run. `bundles_existed` measures delta-upload hit rate.
978
+ bundles_total: bundleStatsAggregate.total,
979
+ bundles_uploaded: bundleStatsAggregate.uploaded,
980
+ bundles_existed: bundleStatsAggregate.existed,
981
+ });
982
+ // B2: use actual successful MCP pushes, not attempt count, to determine pushedSomething.
983
+ const pushedSomething = allResults.length > 0 || mcpPushedCount > 0 || !!personaPushResult || backupSuccess;
984
+ // Pick the right hint variant based on the run outcome. We deliberately
985
+ // ungate the tip from `pushedSomething` for the all-failed case so a
986
+ // 100%-failed `lua push all --force` still surfaces a `lua logs` nudge
987
+ // (previously it was silent, leaving users to guess what to do next).
988
+ const variant = pickPushAllNextStepVariant({
989
+ pushedSomething,
990
+ failedCount: failedItems.length + deployFailedCount,
764
991
  });
765
- console.log('');
992
+ if (variant === 'success') {
993
+ console.log('');
994
+ if (options.autoDeploy) {
995
+ writeHintBlock({
996
+ headline: 'All deployed. Generate test traffic first, then inspect:',
997
+ lines: [
998
+ { label: 'Test:', command: 'lua chat -e production -m "your test message"' },
999
+ { label: 'Inspect:', command: buildLogsCommand({ limit: 10 }) },
1000
+ ],
1001
+ when: 'success',
1002
+ });
1003
+ }
1004
+ else {
1005
+ writeHintBlock({
1006
+ headline: 'Code staged but NOT live. Make it active:',
1007
+ lines: [
1008
+ { label: 'Deploy all:', command: 'lua deploy all --force' },
1009
+ { label: 'Or re-push:', command: 'lua push all --force --auto-deploy' },
1010
+ ],
1011
+ when: 'success',
1012
+ });
1013
+ }
1014
+ }
1015
+ else if (variant === 'partial') {
1016
+ console.log('');
1017
+ // Some components pushed, some failed. Suggest re-pushing the failures.
1018
+ // No lua logs hint: failed pushes produce no execution logs.
1019
+ writeNextStep({
1020
+ command: 'lua push all --force',
1021
+ rationale: 'to re-attempt the failed components',
1022
+ when: 'partial',
1023
+ });
1024
+ }
1025
+ else if (variant === 'error') {
1026
+ console.log('');
1027
+ // Total failure — nothing pushed, no execution logs exist.
1028
+ // No hint: the errors are already shown above.
1029
+ }
766
1030
  }
767
1031
  /**
768
1032
  * Retry deployment with exponential backoff
@@ -774,7 +1038,7 @@ async function retryDeploy(deployFn, _componentName, _version, maxRetries = 3) {
774
1038
  // Only delay on retry attempts (not first attempt)
775
1039
  if (attempt > 1) {
776
1040
  const delay = attempt * 2000; // 2s on 2nd attempt, 4s on 3rd, etc.
777
- await new Promise(resolve => setTimeout(resolve, delay));
1041
+ await new Promise((resolve) => setTimeout(resolve, delay));
778
1042
  }
779
1043
  await deployFn();
780
1044
  // Show success message if succeeded after retrying