@miosa/cli 1.3.4 → 2.1.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 (489) hide show
  1. package/README.md +20 -835
  2. package/bin/miosa.js +75 -0
  3. package/lib/archive.js +88 -0
  4. package/lib/checksums.js +29 -0
  5. package/lib/platforms.js +31 -0
  6. package/lib/resolve.js +47 -0
  7. package/package.json +26 -41
  8. package/scripts/postinstall.js +68 -0
  9. package/CHANGELOG.md +0 -110
  10. package/dist/action-authority.d.ts +0 -106
  11. package/dist/action-authority.d.ts.map +0 -1
  12. package/dist/action-authority.js +0 -116
  13. package/dist/action-authority.js.map +0 -1
  14. package/dist/app-advisor.d.ts +0 -80
  15. package/dist/app-advisor.d.ts.map +0 -1
  16. package/dist/app-advisor.js +0 -486
  17. package/dist/app-advisor.js.map +0 -1
  18. package/dist/app-contract.d.ts +0 -92
  19. package/dist/app-contract.d.ts.map +0 -1
  20. package/dist/app-contract.js +0 -218
  21. package/dist/app-contract.js.map +0 -1
  22. package/dist/app-document.d.ts +0 -23
  23. package/dist/app-document.d.ts.map +0 -1
  24. package/dist/app-document.js +0 -180
  25. package/dist/app-document.js.map +0 -1
  26. package/dist/app-manifest.d.ts +0 -140
  27. package/dist/app-manifest.d.ts.map +0 -1
  28. package/dist/app-manifest.js +0 -377
  29. package/dist/app-manifest.js.map +0 -1
  30. package/dist/app-operation.d.ts +0 -23
  31. package/dist/app-operation.d.ts.map +0 -1
  32. package/dist/app-operation.js +0 -49
  33. package/dist/app-operation.js.map +0 -1
  34. package/dist/app-release.d.ts +0 -132
  35. package/dist/app-release.d.ts.map +0 -1
  36. package/dist/app-release.js +0 -294
  37. package/dist/app-release.js.map +0 -1
  38. package/dist/bin/miosa.d.ts +0 -3
  39. package/dist/bin/miosa.d.ts.map +0 -1
  40. package/dist/bin/miosa.js +0 -288
  41. package/dist/bin/miosa.js.map +0 -1
  42. package/dist/cli-env.d.ts +0 -12
  43. package/dist/cli-env.d.ts.map +0 -1
  44. package/dist/cli-env.js +0 -34
  45. package/dist/cli-env.js.map +0 -1
  46. package/dist/client.d.ts +0 -155
  47. package/dist/client.d.ts.map +0 -1
  48. package/dist/client.js +0 -865
  49. package/dist/client.js.map +0 -1
  50. package/dist/commands/actions.d.ts +0 -3
  51. package/dist/commands/actions.d.ts.map +0 -1
  52. package/dist/commands/actions.js +0 -222
  53. package/dist/commands/actions.js.map +0 -1
  54. package/dist/commands/agent-runtime-profiles.d.ts +0 -3
  55. package/dist/commands/agent-runtime-profiles.d.ts.map +0 -1
  56. package/dist/commands/agent-runtime-profiles.js +0 -198
  57. package/dist/commands/agent-runtime-profiles.js.map +0 -1
  58. package/dist/commands/agent.d.ts +0 -18
  59. package/dist/commands/agent.d.ts.map +0 -1
  60. package/dist/commands/agent.js +0 -737
  61. package/dist/commands/agent.js.map +0 -1
  62. package/dist/commands/alerts.d.ts +0 -3
  63. package/dist/commands/alerts.d.ts.map +0 -1
  64. package/dist/commands/alerts.js +0 -41
  65. package/dist/commands/alerts.js.map +0 -1
  66. package/dist/commands/api-keys.d.ts +0 -3
  67. package/dist/commands/api-keys.d.ts.map +0 -1
  68. package/dist/commands/api-keys.js +0 -160
  69. package/dist/commands/api-keys.js.map +0 -1
  70. package/dist/commands/api-resource.d.ts +0 -20
  71. package/dist/commands/api-resource.d.ts.map +0 -1
  72. package/dist/commands/api-resource.js +0 -120
  73. package/dist/commands/api-resource.js.map +0 -1
  74. package/dist/commands/app.d.ts +0 -38
  75. package/dist/commands/app.d.ts.map +0 -1
  76. package/dist/commands/app.js +0 -1182
  77. package/dist/commands/app.js.map +0 -1
  78. package/dist/commands/apps.d.ts +0 -3
  79. package/dist/commands/apps.d.ts.map +0 -1
  80. package/dist/commands/apps.js +0 -218
  81. package/dist/commands/apps.js.map +0 -1
  82. package/dist/commands/audit.d.ts +0 -3
  83. package/dist/commands/audit.d.ts.map +0 -1
  84. package/dist/commands/audit.js +0 -25
  85. package/dist/commands/audit.js.map +0 -1
  86. package/dist/commands/auth.d.ts +0 -3
  87. package/dist/commands/auth.d.ts.map +0 -1
  88. package/dist/commands/auth.js +0 -282
  89. package/dist/commands/auth.js.map +0 -1
  90. package/dist/commands/backups.d.ts +0 -3
  91. package/dist/commands/backups.d.ts.map +0 -1
  92. package/dist/commands/backups.js +0 -23
  93. package/dist/commands/backups.js.map +0 -1
  94. package/dist/commands/billing.d.ts +0 -3
  95. package/dist/commands/billing.d.ts.map +0 -1
  96. package/dist/commands/billing.js +0 -208
  97. package/dist/commands/billing.js.map +0 -1
  98. package/dist/commands/builds.d.ts +0 -3
  99. package/dist/commands/builds.d.ts.map +0 -1
  100. package/dist/commands/builds.js +0 -198
  101. package/dist/commands/builds.js.map +0 -1
  102. package/dist/commands/capabilities.d.ts +0 -3
  103. package/dist/commands/capabilities.d.ts.map +0 -1
  104. package/dist/commands/capabilities.js +0 -1002
  105. package/dist/commands/capabilities.js.map +0 -1
  106. package/dist/commands/checkpoints.d.ts +0 -3
  107. package/dist/commands/checkpoints.d.ts.map +0 -1
  108. package/dist/commands/checkpoints.js +0 -193
  109. package/dist/commands/checkpoints.js.map +0 -1
  110. package/dist/commands/cleanup.d.ts +0 -3
  111. package/dist/commands/cleanup.d.ts.map +0 -1
  112. package/dist/commands/cleanup.js +0 -65
  113. package/dist/commands/cleanup.js.map +0 -1
  114. package/dist/commands/cloud.d.ts +0 -3
  115. package/dist/commands/cloud.d.ts.map +0 -1
  116. package/dist/commands/cloud.js +0 -192
  117. package/dist/commands/cloud.js.map +0 -1
  118. package/dist/commands/command-overview.d.ts +0 -13
  119. package/dist/commands/command-overview.d.ts.map +0 -1
  120. package/dist/commands/command-overview.js +0 -50
  121. package/dist/commands/command-overview.js.map +0 -1
  122. package/dist/commands/completion.d.ts +0 -3
  123. package/dist/commands/completion.d.ts.map +0 -1
  124. package/dist/commands/completion.js +0 -183
  125. package/dist/commands/completion.js.map +0 -1
  126. package/dist/commands/computers.d.ts +0 -3
  127. package/dist/commands/computers.d.ts.map +0 -1
  128. package/dist/commands/computers.js +0 -706
  129. package/dist/commands/computers.js.map +0 -1
  130. package/dist/commands/config.d.ts +0 -3
  131. package/dist/commands/config.d.ts.map +0 -1
  132. package/dist/commands/config.js +0 -114
  133. package/dist/commands/config.js.map +0 -1
  134. package/dist/commands/connect.d.ts +0 -6
  135. package/dist/commands/connect.d.ts.map +0 -1
  136. package/dist/commands/connect.js +0 -127
  137. package/dist/commands/connect.js.map +0 -1
  138. package/dist/commands/connectors.d.ts +0 -3
  139. package/dist/commands/connectors.d.ts.map +0 -1
  140. package/dist/commands/connectors.js +0 -172
  141. package/dist/commands/connectors.js.map +0 -1
  142. package/dist/commands/containers.d.ts +0 -3
  143. package/dist/commands/containers.d.ts.map +0 -1
  144. package/dist/commands/containers.js +0 -20
  145. package/dist/commands/containers.js.map +0 -1
  146. package/dist/commands/context.d.ts +0 -3
  147. package/dist/commands/context.d.ts.map +0 -1
  148. package/dist/commands/context.js +0 -233
  149. package/dist/commands/context.js.map +0 -1
  150. package/dist/commands/cp.d.ts +0 -3
  151. package/dist/commands/cp.d.ts.map +0 -1
  152. package/dist/commands/cp.js +0 -319
  153. package/dist/commands/cp.js.map +0 -1
  154. package/dist/commands/cron.d.ts +0 -3
  155. package/dist/commands/cron.d.ts.map +0 -1
  156. package/dist/commands/cron.js +0 -65
  157. package/dist/commands/cron.js.map +0 -1
  158. package/dist/commands/dashboard.d.ts +0 -13
  159. package/dist/commands/dashboard.d.ts.map +0 -1
  160. package/dist/commands/dashboard.js +0 -54
  161. package/dist/commands/dashboard.js.map +0 -1
  162. package/dist/commands/databases.d.ts +0 -3
  163. package/dist/commands/databases.d.ts.map +0 -1
  164. package/dist/commands/databases.js +0 -714
  165. package/dist/commands/databases.js.map +0 -1
  166. package/dist/commands/db.d.ts +0 -3
  167. package/dist/commands/db.d.ts.map +0 -1
  168. package/dist/commands/db.js +0 -385
  169. package/dist/commands/db.js.map +0 -1
  170. package/dist/commands/deploy.d.ts +0 -3
  171. package/dist/commands/deploy.d.ts.map +0 -1
  172. package/dist/commands/deploy.js +0 -1234
  173. package/dist/commands/deploy.js.map +0 -1
  174. package/dist/commands/desktop.d.ts +0 -3
  175. package/dist/commands/desktop.d.ts.map +0 -1
  176. package/dist/commands/desktop.js +0 -277
  177. package/dist/commands/desktop.js.map +0 -1
  178. package/dist/commands/dev.d.ts +0 -3
  179. package/dist/commands/dev.d.ts.map +0 -1
  180. package/dist/commands/dev.js +0 -245
  181. package/dist/commands/dev.js.map +0 -1
  182. package/dist/commands/devices.d.ts +0 -3
  183. package/dist/commands/devices.d.ts.map +0 -1
  184. package/dist/commands/devices.js +0 -279
  185. package/dist/commands/devices.js.map +0 -1
  186. package/dist/commands/docker-deploy.d.ts +0 -3
  187. package/dist/commands/docker-deploy.d.ts.map +0 -1
  188. package/dist/commands/docker-deploy.js +0 -659
  189. package/dist/commands/docker-deploy.js.map +0 -1
  190. package/dist/commands/doctor.d.ts +0 -69
  191. package/dist/commands/doctor.d.ts.map +0 -1
  192. package/dist/commands/doctor.js +0 -596
  193. package/dist/commands/doctor.js.map +0 -1
  194. package/dist/commands/domains.d.ts +0 -3
  195. package/dist/commands/domains.d.ts.map +0 -1
  196. package/dist/commands/domains.js +0 -307
  197. package/dist/commands/domains.js.map +0 -1
  198. package/dist/commands/enterprise-util.d.ts +0 -39
  199. package/dist/commands/enterprise-util.d.ts.map +0 -1
  200. package/dist/commands/enterprise-util.js +0 -217
  201. package/dist/commands/enterprise-util.js.map +0 -1
  202. package/dist/commands/env-input.d.ts +0 -26
  203. package/dist/commands/env-input.d.ts.map +0 -1
  204. package/dist/commands/env-input.js +0 -68
  205. package/dist/commands/env-input.js.map +0 -1
  206. package/dist/commands/env.d.ts +0 -3
  207. package/dist/commands/env.d.ts.map +0 -1
  208. package/dist/commands/env.js +0 -189
  209. package/dist/commands/env.js.map +0 -1
  210. package/dist/commands/exec.d.ts +0 -3
  211. package/dist/commands/exec.d.ts.map +0 -1
  212. package/dist/commands/exec.js +0 -110
  213. package/dist/commands/exec.js.map +0 -1
  214. package/dist/commands/forge.d.ts +0 -3
  215. package/dist/commands/forge.d.ts.map +0 -1
  216. package/dist/commands/forge.js +0 -254
  217. package/dist/commands/forge.js.map +0 -1
  218. package/dist/commands/functions.d.ts +0 -3
  219. package/dist/commands/functions.d.ts.map +0 -1
  220. package/dist/commands/functions.js +0 -47
  221. package/dist/commands/functions.js.map +0 -1
  222. package/dist/commands/gha-runners.d.ts +0 -3
  223. package/dist/commands/gha-runners.d.ts.map +0 -1
  224. package/dist/commands/gha-runners.js +0 -33
  225. package/dist/commands/gha-runners.js.map +0 -1
  226. package/dist/commands/groups.d.ts +0 -3
  227. package/dist/commands/groups.d.ts.map +0 -1
  228. package/dist/commands/groups.js +0 -38
  229. package/dist/commands/groups.js.map +0 -1
  230. package/dist/commands/host.d.ts +0 -3
  231. package/dist/commands/host.d.ts.map +0 -1
  232. package/dist/commands/host.js +0 -74
  233. package/dist/commands/host.js.map +0 -1
  234. package/dist/commands/hosts.d.ts +0 -7
  235. package/dist/commands/hosts.d.ts.map +0 -1
  236. package/dist/commands/hosts.js +0 -91
  237. package/dist/commands/hosts.js.map +0 -1
  238. package/dist/commands/link.d.ts +0 -8
  239. package/dist/commands/link.d.ts.map +0 -1
  240. package/dist/commands/link.js +0 -124
  241. package/dist/commands/link.js.map +0 -1
  242. package/dist/commands/login.d.ts +0 -10
  243. package/dist/commands/login.d.ts.map +0 -1
  244. package/dist/commands/login.js +0 -263
  245. package/dist/commands/login.js.map +0 -1
  246. package/dist/commands/logout.d.ts +0 -3
  247. package/dist/commands/logout.d.ts.map +0 -1
  248. package/dist/commands/logout.js +0 -43
  249. package/dist/commands/logout.js.map +0 -1
  250. package/dist/commands/logs.d.ts +0 -3
  251. package/dist/commands/logs.d.ts.map +0 -1
  252. package/dist/commands/logs.js +0 -401
  253. package/dist/commands/logs.js.map +0 -1
  254. package/dist/commands/ls.d.ts +0 -3
  255. package/dist/commands/ls.d.ts.map +0 -1
  256. package/dist/commands/ls.js +0 -121
  257. package/dist/commands/ls.js.map +0 -1
  258. package/dist/commands/mcp.d.ts +0 -46
  259. package/dist/commands/mcp.d.ts.map +0 -1
  260. package/dist/commands/mcp.js +0 -3413
  261. package/dist/commands/mcp.js.map +0 -1
  262. package/dist/commands/menu.d.ts +0 -29
  263. package/dist/commands/menu.d.ts.map +0 -1
  264. package/dist/commands/menu.js +0 -147
  265. package/dist/commands/menu.js.map +0 -1
  266. package/dist/commands/meshes.d.ts +0 -3
  267. package/dist/commands/meshes.d.ts.map +0 -1
  268. package/dist/commands/meshes.js +0 -27
  269. package/dist/commands/meshes.js.map +0 -1
  270. package/dist/commands/network-policy.d.ts +0 -3
  271. package/dist/commands/network-policy.d.ts.map +0 -1
  272. package/dist/commands/network-policy.js +0 -155
  273. package/dist/commands/network-policy.js.map +0 -1
  274. package/dist/commands/new.d.ts +0 -3
  275. package/dist/commands/new.d.ts.map +0 -1
  276. package/dist/commands/new.js +0 -296
  277. package/dist/commands/new.js.map +0 -1
  278. package/dist/commands/opencomputers.d.ts +0 -10
  279. package/dist/commands/opencomputers.d.ts.map +0 -1
  280. package/dist/commands/opencomputers.js +0 -25
  281. package/dist/commands/opencomputers.js.map +0 -1
  282. package/dist/commands/operating-contract.d.ts +0 -3
  283. package/dist/commands/operating-contract.d.ts.map +0 -1
  284. package/dist/commands/operating-contract.js +0 -651
  285. package/dist/commands/operating-contract.js.map +0 -1
  286. package/dist/commands/project.d.ts +0 -4
  287. package/dist/commands/project.d.ts.map +0 -1
  288. package/dist/commands/project.js +0 -25
  289. package/dist/commands/project.js.map +0 -1
  290. package/dist/commands/pull.d.ts +0 -14
  291. package/dist/commands/pull.d.ts.map +0 -1
  292. package/dist/commands/pull.js +0 -156
  293. package/dist/commands/pull.js.map +0 -1
  294. package/dist/commands/regions.d.ts +0 -3
  295. package/dist/commands/regions.d.ts.map +0 -1
  296. package/dist/commands/regions.js +0 -103
  297. package/dist/commands/regions.js.map +0 -1
  298. package/dist/commands/releases.d.ts +0 -3
  299. package/dist/commands/releases.d.ts.map +0 -1
  300. package/dist/commands/releases.js +0 -365
  301. package/dist/commands/releases.js.map +0 -1
  302. package/dist/commands/rm.d.ts +0 -3
  303. package/dist/commands/rm.d.ts.map +0 -1
  304. package/dist/commands/rm.js +0 -42
  305. package/dist/commands/rm.js.map +0 -1
  306. package/dist/commands/rollback.d.ts +0 -3
  307. package/dist/commands/rollback.d.ts.map +0 -1
  308. package/dist/commands/rollback.js +0 -62
  309. package/dist/commands/rollback.js.map +0 -1
  310. package/dist/commands/run-groups.d.ts +0 -3
  311. package/dist/commands/run-groups.d.ts.map +0 -1
  312. package/dist/commands/run-groups.js +0 -364
  313. package/dist/commands/run-groups.js.map +0 -1
  314. package/dist/commands/run.d.ts +0 -3
  315. package/dist/commands/run.d.ts.map +0 -1
  316. package/dist/commands/run.js +0 -130
  317. package/dist/commands/run.js.map +0 -1
  318. package/dist/commands/runs.d.ts +0 -3
  319. package/dist/commands/runs.d.ts.map +0 -1
  320. package/dist/commands/runs.js +0 -365
  321. package/dist/commands/runs.js.map +0 -1
  322. package/dist/commands/runtime-env.d.ts +0 -3
  323. package/dist/commands/runtime-env.d.ts.map +0 -1
  324. package/dist/commands/runtime-env.js +0 -114
  325. package/dist/commands/runtime-env.js.map +0 -1
  326. package/dist/commands/sandbox-delete-guard.d.ts +0 -4
  327. package/dist/commands/sandbox-delete-guard.d.ts.map +0 -1
  328. package/dist/commands/sandbox-delete-guard.js +0 -32
  329. package/dist/commands/sandbox-delete-guard.js.map +0 -1
  330. package/dist/commands/sandbox-dev.d.ts +0 -20
  331. package/dist/commands/sandbox-dev.d.ts.map +0 -1
  332. package/dist/commands/sandbox-dev.js +0 -583
  333. package/dist/commands/sandbox-dev.js.map +0 -1
  334. package/dist/commands/sandbox.d.ts +0 -36
  335. package/dist/commands/sandbox.d.ts.map +0 -1
  336. package/dist/commands/sandbox.js +0 -3796
  337. package/dist/commands/sandbox.js.map +0 -1
  338. package/dist/commands/scale.d.ts +0 -3
  339. package/dist/commands/scale.d.ts.map +0 -1
  340. package/dist/commands/scale.js +0 -61
  341. package/dist/commands/scale.js.map +0 -1
  342. package/dist/commands/schedules.d.ts +0 -3
  343. package/dist/commands/schedules.d.ts.map +0 -1
  344. package/dist/commands/schedules.js +0 -37
  345. package/dist/commands/schedules.js.map +0 -1
  346. package/dist/commands/secrets.d.ts +0 -3
  347. package/dist/commands/secrets.d.ts.map +0 -1
  348. package/dist/commands/secrets.js +0 -200
  349. package/dist/commands/secrets.js.map +0 -1
  350. package/dist/commands/services.d.ts +0 -3
  351. package/dist/commands/services.d.ts.map +0 -1
  352. package/dist/commands/services.js +0 -70
  353. package/dist/commands/services.js.map +0 -1
  354. package/dist/commands/shell.d.ts +0 -16
  355. package/dist/commands/shell.d.ts.map +0 -1
  356. package/dist/commands/shell.js +0 -555
  357. package/dist/commands/shell.js.map +0 -1
  358. package/dist/commands/snapshot.d.ts +0 -10
  359. package/dist/commands/snapshot.d.ts.map +0 -1
  360. package/dist/commands/snapshot.js +0 -181
  361. package/dist/commands/snapshot.js.map +0 -1
  362. package/dist/commands/ssh.d.ts +0 -3
  363. package/dist/commands/ssh.d.ts.map +0 -1
  364. package/dist/commands/ssh.js +0 -93
  365. package/dist/commands/ssh.js.map +0 -1
  366. package/dist/commands/status.d.ts +0 -3
  367. package/dist/commands/status.d.ts.map +0 -1
  368. package/dist/commands/status.js +0 -302
  369. package/dist/commands/status.js.map +0 -1
  370. package/dist/commands/storage.d.ts +0 -3
  371. package/dist/commands/storage.d.ts.map +0 -1
  372. package/dist/commands/storage.js +0 -456
  373. package/dist/commands/storage.js.map +0 -1
  374. package/dist/commands/teams.d.ts +0 -3
  375. package/dist/commands/teams.d.ts.map +0 -1
  376. package/dist/commands/teams.js +0 -169
  377. package/dist/commands/teams.js.map +0 -1
  378. package/dist/commands/templates.d.ts +0 -3
  379. package/dist/commands/templates.d.ts.map +0 -1
  380. package/dist/commands/templates.js +0 -690
  381. package/dist/commands/templates.js.map +0 -1
  382. package/dist/commands/tenant.d.ts +0 -3
  383. package/dist/commands/tenant.d.ts.map +0 -1
  384. package/dist/commands/tenant.js +0 -95
  385. package/dist/commands/tenant.js.map +0 -1
  386. package/dist/commands/tunnel.d.ts +0 -3
  387. package/dist/commands/tunnel.d.ts.map +0 -1
  388. package/dist/commands/tunnel.js +0 -418
  389. package/dist/commands/tunnel.js.map +0 -1
  390. package/dist/commands/up.d.ts +0 -14
  391. package/dist/commands/up.d.ts.map +0 -1
  392. package/dist/commands/up.js +0 -720
  393. package/dist/commands/up.js.map +0 -1
  394. package/dist/commands/update.d.ts +0 -3
  395. package/dist/commands/update.d.ts.map +0 -1
  396. package/dist/commands/update.js +0 -166
  397. package/dist/commands/update.js.map +0 -1
  398. package/dist/commands/util.d.ts +0 -25
  399. package/dist/commands/util.d.ts.map +0 -1
  400. package/dist/commands/util.js +0 -199
  401. package/dist/commands/util.js.map +0 -1
  402. package/dist/commands/volumes.d.ts +0 -3
  403. package/dist/commands/volumes.d.ts.map +0 -1
  404. package/dist/commands/volumes.js +0 -196
  405. package/dist/commands/volumes.js.map +0 -1
  406. package/dist/commands/watch.d.ts +0 -6
  407. package/dist/commands/watch.d.ts.map +0 -1
  408. package/dist/commands/watch.js +0 -414
  409. package/dist/commands/watch.js.map +0 -1
  410. package/dist/commands/webhooks.d.ts +0 -3
  411. package/dist/commands/webhooks.d.ts.map +0 -1
  412. package/dist/commands/webhooks.js +0 -23
  413. package/dist/commands/webhooks.js.map +0 -1
  414. package/dist/commands/whoami.d.ts +0 -3
  415. package/dist/commands/whoami.d.ts.map +0 -1
  416. package/dist/commands/whoami.js +0 -156
  417. package/dist/commands/whoami.js.map +0 -1
  418. package/dist/commands/workspaces.d.ts +0 -3
  419. package/dist/commands/workspaces.d.ts.map +0 -1
  420. package/dist/commands/workspaces.js +0 -147
  421. package/dist/commands/workspaces.js.map +0 -1
  422. package/dist/config.d.ts +0 -54
  423. package/dist/config.d.ts.map +0 -1
  424. package/dist/config.js +0 -275
  425. package/dist/config.js.map +0 -1
  426. package/dist/errors.d.ts +0 -30
  427. package/dist/errors.d.ts.map +0 -1
  428. package/dist/errors.js +0 -92
  429. package/dist/errors.js.map +0 -1
  430. package/dist/framework-detector.d.ts +0 -22
  431. package/dist/framework-detector.d.ts.map +0 -1
  432. package/dist/framework-detector.js +0 -373
  433. package/dist/framework-detector.js.map +0 -1
  434. package/dist/generated/action-capabilities.d.ts +0 -826
  435. package/dist/generated/action-capabilities.d.ts.map +0 -1
  436. package/dist/generated/action-capabilities.js +0 -1035
  437. package/dist/generated/action-capabilities.js.map +0 -1
  438. package/dist/net-diagnosis.d.ts +0 -87
  439. package/dist/net-diagnosis.d.ts.map +0 -1
  440. package/dist/net-diagnosis.js +0 -408
  441. package/dist/net-diagnosis.js.map +0 -1
  442. package/dist/pty/raw-mode.d.ts +0 -7
  443. package/dist/pty/raw-mode.d.ts.map +0 -1
  444. package/dist/pty/raw-mode.js +0 -22
  445. package/dist/pty/raw-mode.js.map +0 -1
  446. package/dist/pty/ws-pty-client.d.ts +0 -13
  447. package/dist/pty/ws-pty-client.d.ts.map +0 -1
  448. package/dist/pty/ws-pty-client.js +0 -73
  449. package/dist/pty/ws-pty-client.js.map +0 -1
  450. package/dist/tui/dashboard.d.ts +0 -35
  451. package/dist/tui/dashboard.d.ts.map +0 -1
  452. package/dist/tui/dashboard.js +0 -191
  453. package/dist/tui/dashboard.js.map +0 -1
  454. package/dist/tui/logs.d.ts +0 -26
  455. package/dist/tui/logs.d.ts.map +0 -1
  456. package/dist/tui/logs.js +0 -276
  457. package/dist/tui/logs.js.map +0 -1
  458. package/dist/types.d.ts +0 -362
  459. package/dist/types.d.ts.map +0 -1
  460. package/dist/types.js +0 -16
  461. package/dist/types.js.map +0 -1
  462. package/dist/ui/picker.d.ts +0 -41
  463. package/dist/ui/picker.d.ts.map +0 -1
  464. package/dist/ui/picker.js +0 -77
  465. package/dist/ui/picker.js.map +0 -1
  466. package/dist/ui/progress.d.ts +0 -10
  467. package/dist/ui/progress.d.ts.map +0 -1
  468. package/dist/ui/progress.js +0 -36
  469. package/dist/ui/progress.js.map +0 -1
  470. package/dist/ui/render.d.ts +0 -91
  471. package/dist/ui/render.d.ts.map +0 -1
  472. package/dist/ui/render.js +0 -138
  473. package/dist/ui/render.js.map +0 -1
  474. package/dist/ui/spinner.d.ts +0 -4
  475. package/dist/ui/spinner.d.ts.map +0 -1
  476. package/dist/ui/spinner.js +0 -7
  477. package/dist/ui/spinner.js.map +0 -1
  478. package/dist/ui/table.d.ts +0 -8
  479. package/dist/ui/table.d.ts.map +0 -1
  480. package/dist/ui/table.js +0 -46
  481. package/dist/ui/table.js.map +0 -1
  482. package/dist/update-check.d.ts +0 -13
  483. package/dist/update-check.d.ts.map +0 -1
  484. package/dist/update-check.js +0 -94
  485. package/dist/update-check.js.map +0 -1
  486. package/dist/version.d.ts +0 -3
  487. package/dist/version.d.ts.map +0 -1
  488. package/dist/version.js +0 -5
  489. package/dist/version.js.map +0 -1
@@ -1,1182 +0,0 @@
1
- import chalk from "chalk";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- import { request } from "undici";
5
- import { inspectApp, planApp } from "../app-advisor.js";
6
- import { MiosaClient } from "../client.js";
7
- import { loadConfig } from "../config.js";
8
- import { UserError } from "../errors.js";
9
- import { deploySandbox } from "./sandbox.js";
10
- import { ensureGitignored, fetchSecretValues, toDotenv } from "./pull.js";
11
- import { loadLocalLink } from "./link.js";
12
- import { loadAcceptanceContract, saveReleaseReceipt, verifyApplicationRelease, } from "../app-release.js";
13
- import { applicationIdempotencyKey, createApplicationOperation, loadApplicationOperation, updateApplicationOperation, } from "../app-operation.js";
14
- import { handleError, isJsonMode, printJson } from "./util.js";
15
- import { diagnoseAppDocument } from "../app-document.js";
16
- export function requireApplicationLink(dir) {
17
- const link = loadLocalLink(dir);
18
- if (!link?.deploymentId || !link.name) {
19
- throw new UserError("This directory is not linked to a MIOSA application.", "Run `miosa app link --app <deployment-id>` first.");
20
- }
21
- return {
22
- version: 2,
23
- deploymentId: link.deploymentId,
24
- name: link.name,
25
- environment: link.environment,
26
- workspaceId: link.workspaceId,
27
- projectId: link.projectId,
28
- organizationId: link.organizationId,
29
- };
30
- }
31
- function record(value) {
32
- return value !== null && typeof value === "object" && !Array.isArray(value)
33
- ? value
34
- : {};
35
- }
36
- function stringValue(value, key) {
37
- const found = record(value)[key];
38
- return typeof found === "string" && found.trim() ? found.trim() : undefined;
39
- }
40
- function deploymentPayload(value) {
41
- const outer = record(value);
42
- const data = record(outer["data"]);
43
- return Object.keys(data).length > 0 ? data : outer;
44
- }
45
- function boolValue(value, key) {
46
- const found = record(value)[key];
47
- return typeof found === "boolean" ? found : undefined;
48
- }
49
- function parseJsonObject(value, option) {
50
- if (!value)
51
- return {};
52
- let parsed;
53
- try {
54
- parsed = JSON.parse(value);
55
- }
56
- catch {
57
- throw new UserError(`${option} must be valid JSON.`, `Pass a JSON object, for example ${option} '{"enabled":true}'.`);
58
- }
59
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
60
- throw new UserError(`${option} must be a JSON object.`, `Pass an object, not ${Array.isArray(parsed) ? "an array" : typeof parsed}.`);
61
- }
62
- return parsed;
63
- }
64
- function parseNonNegativeInteger(value, option) {
65
- const parsed = Number(value);
66
- if (!Number.isSafeInteger(parsed) || parsed < 0) {
67
- throw new UserError(`${option} must be a non-negative integer.`, `Received ${JSON.stringify(value)}.`);
68
- }
69
- return parsed;
70
- }
71
- export async function getRelease(client, deploymentId, releaseId) {
72
- const raw = await client.apiGet(`/api/v1/deployments/${encodeURIComponent(deploymentId)}/releases/${encodeURIComponent(releaseId)}`);
73
- return deploymentPayload(raw);
74
- }
75
- function releaseVersionId(release) {
76
- return (stringValue(release, "deployment_version_id") ??
77
- stringValue(release, "version_id") ??
78
- stringValue(release, "id"));
79
- }
80
- export async function inspectLinkedRelease(client, deploymentId, releaseId, contract) {
81
- const [rawDeployment, release, env] = await Promise.all([
82
- client.apiGet(`/api/v1/deployments/${encodeURIComponent(deploymentId)}`),
83
- getRelease(client, deploymentId, releaseId),
84
- client.apiGet(`/api/v1/deployments/${encodeURIComponent(deploymentId)}/env`),
85
- ]);
86
- const deployment = deploymentPayload(rawDeployment);
87
- const dockerApp = record(deployment["docker_deploy_app"]);
88
- const metadata = record(deployment["metadata"]);
89
- const releaseMetadata = record(release["metadata"]);
90
- const versionId = releaseVersionId(release);
91
- if (!versionId) {
92
- throw new UserError(`Release ${releaseId} has no immutable version ID.`, "The publish operation did not create a promotable immutable version.");
93
- }
94
- const envNames = (env.data ?? [])
95
- .map((item) => item.name)
96
- .filter((name) => typeof name === "string");
97
- const hostId = stringValue(deployment, "docker_deploy_host_id") ??
98
- stringValue(dockerApp, "docker_deploy_host_id");
99
- const product = stringValue(deployment, "deployment_product") ?? "miosa_deploy";
100
- const activeVersion = stringValue(deployment, "active_version_id") ??
101
- stringValue(dockerApp, "deployment_version_id");
102
- const activeRelease = stringValue(deployment, "active_release_id") ??
103
- stringValue(metadata, "active_release_id") ??
104
- (activeVersion === versionId ? releaseId : undefined);
105
- const expectedDigest = stringValue(release, "artifact_sha256") ??
106
- stringValue(release, "archive_sha256") ??
107
- stringValue(releaseMetadata, "artifact_sha256");
108
- const runningDigest = stringValue(deployment, "running_artifact_sha256") ??
109
- stringValue(dockerApp, "artifact_sha256") ??
110
- stringValue(metadata, "running_artifact_sha256") ??
111
- (activeVersion === versionId
112
- ? stringValue(metadata, "artifact_sha256")
113
- : undefined);
114
- const publicUrl = stringValue(deployment, "public_url") ??
115
- stringValue(dockerApp, "public_url") ??
116
- stringValue(deployment, "auto_subdomain");
117
- const host = hostId && product === "docker_deploy"
118
- ? deploymentPayload(await client
119
- .apiGet(`/api/v1/docker-deploy/hosts/${encodeURIComponent(hostId)}`)
120
- .catch(() => ({})))
121
- : {};
122
- const healthyConnectorIds = (await Promise.all((contract.connectors ?? []).map(async (connector) => {
123
- const response = deploymentPayload(await client
124
- .apiPost(`/api/v1/deployments/${encodeURIComponent(deploymentId)}/connectors/preflight`, { connector: connector.id })
125
- .catch(() => ({})));
126
- const connectorStatus = record(response["status"]);
127
- return boolValue(connectorStatus, "bound") ? connector.id : null;
128
- }))).filter((id) => Boolean(id));
129
- const declaredJobIds = new Set((contract.scheduled_jobs ?? []).map((job) => job.id));
130
- const healthyScheduledJobIds = [
131
- deployment["scheduled_jobs"],
132
- metadata["scheduled_jobs"],
133
- dockerApp["scheduled_jobs"],
134
- ]
135
- .flatMap((value) => (Array.isArray(value) ? value : []))
136
- .map((value) => record(value))
137
- .map((job) => {
138
- const id = stringValue(job, "id") ?? stringValue(job, "name");
139
- if (!id || !declaredJobIds.has(id))
140
- return null;
141
- const healthy = boolValue(job, "enabled") !== false &&
142
- boolValue(job, "paused") !== true &&
143
- (stringValue(job, "status") ??
144
- stringValue(job, "state") ??
145
- "active") !== "failed" &&
146
- (stringValue(job, "last_run_status") ?? "ok") !== "failed";
147
- return healthy ? id : null;
148
- })
149
- .filter((id) => Boolean(id))
150
- .filter((id, index, all) => all.indexOf(id) === index);
151
- return {
152
- versionId,
153
- inspection: {
154
- deployment_id: stringValue(deployment, "id") ?? deploymentId,
155
- deployment_name: stringValue(deployment, "name") ?? deploymentId,
156
- tenant_id: stringValue(deployment, "tenant_id") ?? null,
157
- workspace_id: stringValue(deployment, "workspace_id") ?? null,
158
- deployment_state: stringValue(deployment, "state") ?? "unknown",
159
- deployment_product: product,
160
- public_url: publicUrl ?? null,
161
- active_version_id: activeVersion ?? null,
162
- active_release_id: activeRelease ?? null,
163
- running_artifact_sha256: runningDigest ?? null,
164
- expected_artifact_sha256: expectedDigest ?? null,
165
- host_id: hostId ?? null,
166
- host_status: stringValue(host, "status") ??
167
- stringValue(metadata, "docker_deploy_host_status") ??
168
- (hostId ? "unknown" : null),
169
- appliance_status: stringValue(host, "appliance_status") ??
170
- stringValue(dockerApp, "last_health_status") ??
171
- stringValue(dockerApp, "status") ??
172
- null,
173
- database_attached: envNames.includes("DATABASE_URL") ||
174
- Boolean(stringValue(deployment, "database_id") ??
175
- stringValue(deployment, "linked_database_id") ??
176
- stringValue(metadata, "database_id") ??
177
- boolValue(metadata, "database_attached")),
178
- effective_env_names: envNames,
179
- healthy_connector_ids: healthyConnectorIds,
180
- healthy_scheduled_job_ids: healthyScheduledJobIds,
181
- migration_verified: boolValue(releaseMetadata, "migration_verified") === true ||
182
- stringValue(releaseMetadata, "migration_status") === "succeeded",
183
- policy_verified: boolValue(releaseMetadata, "policy_verified") === true ||
184
- stringValue(releaseMetadata, "policy_status") === "passed",
185
- },
186
- };
187
- }
188
- async function verifyLinkedRelease(client, dir, link, releaseId, contractPath, rollbackVersionId, verificationEvidence) {
189
- const contract = loadAcceptanceContract(dir, contractPath);
190
- const { inspection, versionId } = await inspectLinkedRelease(client, link.deploymentId, releaseId, contract);
191
- inspection.migration_verified =
192
- inspection.migration_verified ||
193
- verificationEvidence?.migration_verified === true;
194
- inspection.policy_verified =
195
- inspection.policy_verified ||
196
- verificationEvidence?.policy_verified === true;
197
- const receipt = await verifyApplicationRelease({
198
- application: link.name,
199
- environment: link.environment,
200
- expected_release_id: releaseId,
201
- expected_version_id: versionId,
202
- expected_workspace_id: link.workspaceId,
203
- expected_organization_id: link.organizationId,
204
- rollback_version_id: rollbackVersionId,
205
- contract,
206
- }, {
207
- inspect: async () => inspection,
208
- probe: async (baseUrl, routePath) => {
209
- const started = Date.now();
210
- const url = new URL(routePath, baseUrl);
211
- const response = await request(url, {
212
- method: "GET",
213
- headersTimeout: 15_000,
214
- bodyTimeout: 15_000,
215
- maxRedirections: 0,
216
- });
217
- return {
218
- status: response.statusCode,
219
- body: await response.body.text(),
220
- content_type: typeof response.headers["content-type"] === "string"
221
- ? response.headers["content-type"]
222
- : null,
223
- latency_ms: Date.now() - started,
224
- };
225
- },
226
- });
227
- return { receipt, receiptPath: saveReleaseReceipt(dir, receipt) };
228
- }
229
- async function waitForActiveVersion(client, deploymentId, versionId, timeoutSeconds) {
230
- const deadline = Date.now() + timeoutSeconds * 1_000;
231
- do {
232
- const deployment = deploymentPayload(await client.apiGet(`/api/v1/deployments/${encodeURIComponent(deploymentId)}`));
233
- const dockerApp = record(deployment["docker_deploy_app"]);
234
- const active = stringValue(deployment, "active_version_id") ??
235
- stringValue(dockerApp, "deployment_version_id");
236
- if (active === versionId &&
237
- stringValue(deployment, "state") === "running") {
238
- return;
239
- }
240
- await new Promise((resolve) => setTimeout(resolve, 2_000));
241
- } while (Date.now() < deadline);
242
- throw new UserError(`Timed out waiting for immutable version ${versionId} to become active.`, "Run `miosa app recover <operation-id>` to inspect and resume safely.");
243
- }
244
- function releaseArtifactDigest(release) {
245
- const metadata = record(release["metadata"]);
246
- return (stringValue(release, "artifact_sha256") ??
247
- stringValue(release, "archive_sha256") ??
248
- stringValue(metadata, "artifact_sha256"));
249
- }
250
- export async function activateLinkedRelease(input) {
251
- const client = new MiosaClient(loadConfig());
252
- const release = await getRelease(client, input.link.deploymentId, input.releaseId);
253
- const state = stringValue(release, "state");
254
- if (input.action === "promote" && state !== "ready" && state !== "active") {
255
- throw new UserError(`Release ${input.releaseId} is ${state ?? "unknown"}, expected ready.`, "Only a complete immutable release can be promoted.");
256
- }
257
- const versionId = releaseVersionId(release);
258
- if (!versionId) {
259
- throw new UserError(`Release ${input.releaseId} has no immutable version ID.`);
260
- }
261
- if (!releaseArtifactDigest(release)) {
262
- throw new UserError(`Release ${input.releaseId} has no artifact digest.`, "Publish must record artifact_sha256 before promotion is safe.");
263
- }
264
- const current = deploymentPayload(await client.apiGet(`/api/v1/deployments/${encodeURIComponent(input.link.deploymentId)}`));
265
- const idempotencyKey = input.idempotencyKey ??
266
- applicationIdempotencyKey(input.action, input.link.deploymentId, input.releaseId, versionId);
267
- let operation = createApplicationOperation(input.dir, {
268
- idempotency_key: idempotencyKey,
269
- action: input.action,
270
- deployment_id: input.link.deploymentId,
271
- release_id: input.releaseId,
272
- previous_version_id: stringValue(current, "active_version_id") ?? null,
273
- target_version_id: versionId,
274
- state: "pending",
275
- });
276
- try {
277
- const endpoint = input.action === "promote"
278
- ? `/api/v1/deployments/${encodeURIComponent(input.link.deploymentId)}/releases/${encodeURIComponent(input.releaseId)}/promote`
279
- : `/api/v1/deployments/${encodeURIComponent(input.link.deploymentId)}/rollback`;
280
- const activationResponse = record(await client.apiPost(endpoint, input.action === "rollback" ? { version_id: versionId } : undefined, { "Idempotency-Key": idempotencyKey }));
281
- const serverOperationId = stringValue(activationResponse, "operation_id") ??
282
- stringValue(record(activationResponse["operation"]), "id");
283
- if (serverOperationId) {
284
- operation = updateApplicationOperation(input.dir, operation, {
285
- server_operation_id: serverOperationId,
286
- });
287
- }
288
- await waitForActiveVersion(client, input.link.deploymentId, versionId, input.timeout);
289
- const { receipt, receiptPath } = await verifyLinkedRelease(client, input.dir, input.link, input.releaseId, input.contractPath, operation.previous_version_id, input.verificationEvidence);
290
- let rollbackPerformed = false;
291
- let rollbackConfirmed = false;
292
- if (receipt.result === "blocked" &&
293
- operation.previous_version_id &&
294
- operation.previous_version_id !== operation.target_version_id) {
295
- await client.apiPost(`/api/v1/deployments/${encodeURIComponent(input.link.deploymentId)}/rollback`, { version_id: operation.previous_version_id }, {
296
- "Idempotency-Key": applicationIdempotencyKey("rollback", input.link.deploymentId, input.releaseId, operation.previous_version_id),
297
- });
298
- rollbackPerformed = true;
299
- try {
300
- await waitForActiveVersion(client, input.link.deploymentId, operation.previous_version_id, input.timeout);
301
- rollbackConfirmed = true;
302
- }
303
- catch {
304
- rollbackConfirmed = false;
305
- }
306
- }
307
- const blockedError = rollbackConfirmed
308
- ? "The activated release failed acceptance and production was restored to the previous version."
309
- : rollbackPerformed
310
- ? "The activated release failed acceptance; restoration of the previous version was requested but did not become active within the timeout. Production may require manual recovery."
311
- : "The activated release failed acceptance and no previous version was available for automatic restoration.";
312
- operation = updateApplicationOperation(input.dir, operation, {
313
- state: receipt.result === "verified" ? "succeeded" : "blocked",
314
- receipt_id: receipt.receipt_id,
315
- ...(receipt.result === "blocked" ? { error: blockedError } : {}),
316
- });
317
- return { operation, receipt, receiptPath };
318
- }
319
- catch (error) {
320
- updateApplicationOperation(input.dir, operation, {
321
- state: "failed",
322
- error: error instanceof Error ? error.message : String(error),
323
- });
324
- throw error;
325
- }
326
- }
327
- function saveApplicationLink(dir, link) {
328
- fs.writeFileSync(path.join(dir, ".miosa.json"), `${JSON.stringify(link, null, 2)}\n`, { mode: 0o600 });
329
- }
330
- function validGoal(value) {
331
- if (value === "preview" || value === "deploy" || value === "docker-deploy") {
332
- return value;
333
- }
334
- throw new Error("Invalid goal. Expected preview, deploy, or docker-deploy.");
335
- }
336
- function printInspectHuman(result) {
337
- console.log();
338
- console.log(chalk.bold("MIOSA app inspection"));
339
- console.log();
340
- console.log(` Path: ${result.path}`);
341
- console.log(` Framework: ${result.framework.label} (${result.framework.confidence}%)`);
342
- console.log(` Template: ${result.recommendation.template}`);
343
- console.log(` Deployment: ${result.recommendation.deployment}`);
344
- console.log(` Port: ${result.runtime.port ?? "unknown"}`);
345
- console.log(` Probe path: ${result.runtime.probe_path}`);
346
- console.log(` Build: ${result.commands.build ?? "unknown"}`);
347
- console.log(` Start: ${result.commands.start ?? "unknown"}`);
348
- console.log(` Env keys: ${result.runtime.env_keys.join(", ") || "none"}`);
349
- if (result.manifest)
350
- console.log(` Manifest: ${result.manifest.path}`);
351
- if (result.dockerfile)
352
- console.log(` Dockerfile: ${result.dockerfile}`);
353
- console.log();
354
- console.log(chalk.bold("Recommendation"));
355
- console.log(` ${result.recommendation.reason}`);
356
- if (result.risks.length > 0) {
357
- console.log();
358
- console.log(chalk.bold("Risks"));
359
- for (const risk of result.risks)
360
- console.log(` - ${risk}`);
361
- }
362
- console.log();
363
- console.log(chalk.dim("Machine-readable form: miosa app inspect . --json"));
364
- console.log(chalk.dim("Next: miosa app plan . --goal deploy --json"));
365
- console.log();
366
- }
367
- function printPlanHuman(result) {
368
- console.log();
369
- console.log(chalk.bold("MIOSA app plan"));
370
- console.log();
371
- console.log(` Goal: ${result.goal}`);
372
- console.log(` Deploy: ${result.recommended_deploy}`);
373
- console.log(` Template: ${result.template}`);
374
- console.log(` Port: ${result.port ?? "unknown"}`);
375
- console.log(` Probe path: ${result.probe_path}`);
376
- console.log();
377
- for (const [index, step] of result.steps.entries()) {
378
- console.log(`${index + 1}. ${chalk.cyan(step.id)}`);
379
- console.log(` ${step.purpose}`);
380
- console.log(` ${chalk.dim(step.command)}`);
381
- }
382
- console.log();
383
- console.log(chalk.dim("Machine-readable form: miosa app plan . --json"));
384
- console.log();
385
- }
386
- export function register(program) {
387
- const app = program
388
- .command("app")
389
- .description("Inspect local apps and generate agent-safe MIOSA plans");
390
- app
391
- .command("inspect")
392
- .argument("[path]", "Local app directory", ".")
393
- .description("Detect framework, commands, ports, env needs, and recommended MIOSA deployment path")
394
- .option("--json", "Output compact machine-readable JSON")
395
- .action((dir, opts) => {
396
- try {
397
- const result = inspectApp(dir);
398
- if (isJsonMode(opts)) {
399
- printJson({ ok: true, data: result, error: null });
400
- return;
401
- }
402
- printInspectHuman(result);
403
- }
404
- catch (err) {
405
- handleError(err);
406
- }
407
- });
408
- app
409
- .command("plan")
410
- .argument("[path]", "Local app directory", ".")
411
- .description("Generate the exact MIOSA command sequence for an app")
412
- .option("--goal <goal>", "Plan goal: preview, deploy, or docker-deploy", validGoal, "deploy")
413
- .option("--slug <slug>", "Production app slug placeholder/value")
414
- .option("--workspace <id>", "Workspace ID for scoped create commands")
415
- .option("--docker-deploy", "Force App Engine production path")
416
- .option("--no-docker-deploy", "Prefer standard MIOSA Deploy path")
417
- .option("--json", "Output compact machine-readable JSON")
418
- .action((dir, opts) => {
419
- try {
420
- const result = planApp(dir, {
421
- goal: opts.goal,
422
- slug: opts.slug,
423
- workspace: opts.workspace,
424
- preferDockerDeploy: opts.dockerDeploy || opts.goal === "docker-deploy"
425
- ? true
426
- : opts.noDockerDeploy
427
- ? false
428
- : undefined,
429
- });
430
- if (isJsonMode(opts)) {
431
- printJson({ ok: true, data: result, error: null });
432
- return;
433
- }
434
- printPlanHuman(result);
435
- }
436
- catch (err) {
437
- handleError(err);
438
- }
439
- });
440
- app
441
- .command("link")
442
- .argument("[path]", "Local app directory", ".")
443
- .description("Bind this source directory to one exact MIOSA application")
444
- .requiredOption("--app <id>", "Deployment/application ID")
445
- .option("--environment <environment>", "Linked environment label", "production")
446
- .option("--json", "Output compact machine-readable JSON")
447
- .action(async (inputPath, opts) => {
448
- try {
449
- const dir = path.resolve(inputPath);
450
- if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
451
- throw new UserError(`Local app directory not found: ${dir}`);
452
- }
453
- const client = new MiosaClient(loadConfig());
454
- const raw = await client.apiGet(`/api/v1/deployments/${encodeURIComponent(opts.app)}`);
455
- const deployment = deploymentPayload(raw);
456
- const id = stringValue(deployment, "id");
457
- const name = stringValue(deployment, "name");
458
- if (!id || !name) {
459
- throw new UserError("MIOSA returned an invalid deployment while linking the app.");
460
- }
461
- const link = {
462
- version: 2,
463
- deploymentId: id,
464
- name,
465
- environment: opts.environment,
466
- ...(stringValue(deployment, "workspace_id")
467
- ? { workspaceId: stringValue(deployment, "workspace_id") }
468
- : {}),
469
- ...(stringValue(deployment, "project_id")
470
- ? { projectId: stringValue(deployment, "project_id") }
471
- : {}),
472
- ...(stringValue(deployment, "tenant_id")
473
- ? { organizationId: stringValue(deployment, "tenant_id") }
474
- : {}),
475
- };
476
- saveApplicationLink(dir, link);
477
- const result = {
478
- path: dir,
479
- deployment_id: id,
480
- application: name,
481
- environment: opts.environment,
482
- workspace_id: link.workspaceId ?? null,
483
- project_id: link.projectId ?? null,
484
- organization_id: link.organizationId ?? null,
485
- config: path.join(dir, ".miosa.json"),
486
- };
487
- if (isJsonMode(opts)) {
488
- printJson({ ok: true, data: result, error: null });
489
- return;
490
- }
491
- console.log(chalk.green(`Linked ${name} to ${dir}.`));
492
- console.log(chalk.dim(`Deployment: ${id}`));
493
- console.log(chalk.dim(`Environment: ${opts.environment}`));
494
- }
495
- catch (err) {
496
- handleError(err);
497
- }
498
- });
499
- const documents = app
500
- .command("documents")
501
- .description("Inspect durable generated App Documents");
502
- documents
503
- .command("list")
504
- .description("List durable apps in the selected workspace")
505
- .option("--workspace <id>", "Workspace ID")
506
- .option("--json", "Output machine-readable App Documents")
507
- .action(async (opts) => {
508
- try {
509
- const config = loadConfig();
510
- const workspaceId = opts.workspace ?? config.workspace;
511
- if (!workspaceId) {
512
- throw new UserError("A workspace is required to list App Documents.", "Pass --workspace <id> or select a CLI workspace context.");
513
- }
514
- const query = new URLSearchParams({ workspace_id: workspaceId });
515
- const payload = await new MiosaClient(config).apiGet(`/api/v1/builder/apps?${query.toString()}`);
516
- if (isJsonMode(opts)) {
517
- printJson({ ok: true, data: payload, error: null });
518
- return;
519
- }
520
- console.log(JSON.stringify(payload, null, 2));
521
- }
522
- catch (err) {
523
- handleError(err);
524
- }
525
- });
526
- documents
527
- .command("show <id>")
528
- .description("Show one durable App Document")
529
- .option("--json", "Output machine-readable App Document")
530
- .action(async (id, opts) => {
531
- try {
532
- const payload = await new MiosaClient(loadConfig()).apiGet(`/api/v1/builder/apps/${encodeURIComponent(id)}`);
533
- if (isJsonMode(opts)) {
534
- printJson({ ok: true, data: payload, error: null });
535
- return;
536
- }
537
- console.log(JSON.stringify(payload, null, 2));
538
- }
539
- catch (err) {
540
- handleError(err);
541
- }
542
- });
543
- documents
544
- .command("doctor <id>")
545
- .description("Verify workspace, venue, declarations, and exact approval")
546
- .option("--workspace <id>", "Expected workspace ID")
547
- .option("--json", "Output a stable diagnostic contract")
548
- .action(async (id, opts) => {
549
- try {
550
- const config = loadConfig();
551
- const client = new MiosaClient(config);
552
- const [payload, platformDiagnostics] = await Promise.all([
553
- client.apiGet(`/api/v1/builder/apps/${encodeURIComponent(id)}`),
554
- client.apiGet(`/api/v1/builder/apps/${encodeURIComponent(id)}/diagnostics`),
555
- ]);
556
- const result = diagnoseAppDocument(payload, opts.workspace ?? config.workspace, platformDiagnostics);
557
- if (isJsonMode(opts)) {
558
- printJson({
559
- ok: result.ok,
560
- data: result,
561
- error: result.ok
562
- ? null
563
- : {
564
- code: "APP_DOCUMENT_DIAGNOSTIC_FAILED",
565
- message: "One or more App Document checks failed.",
566
- },
567
- });
568
- }
569
- else {
570
- console.log(JSON.stringify(result, null, 2));
571
- }
572
- if (!result.ok)
573
- process.exitCode = 1;
574
- }
575
- catch (err) {
576
- handleError(err);
577
- }
578
- });
579
- documents
580
- .command("approve <id>")
581
- .description("Approve the current exact app version for release publishing")
582
- .requiredOption("--release <id>", "Immutable candidate release ID")
583
- .option("--reason <reason>", "Review reason")
584
- .option("--json", "Output the exact approval")
585
- .action(async (id, opts) => {
586
- try {
587
- const payload = await new MiosaClient(loadConfig()).apiPost(`/api/v1/builder/apps/${encodeURIComponent(id)}/approvals`, { reason: opts.reason, release_id: opts.release });
588
- if (isJsonMode(opts)) {
589
- printJson({ ok: true, data: payload, error: null });
590
- return;
591
- }
592
- console.log(JSON.stringify(payload, null, 2));
593
- }
594
- catch (err) {
595
- handleError(err);
596
- }
597
- });
598
- documents
599
- .command("revoke <id>")
600
- .description("Revoke one exact-version review approval")
601
- .requiredOption("--approval <id>", "Approval ID")
602
- .option("--json", "Output machine-readable result")
603
- .action(async (id, opts) => {
604
- try {
605
- await new MiosaClient(loadConfig()).apiPost(`/api/v1/builder/apps/${encodeURIComponent(id)}/approvals/${encodeURIComponent(opts.approval)}/revoke`, {});
606
- const result = {
607
- app_document_id: id,
608
- approval_id: opts.approval,
609
- revoked: true,
610
- };
611
- if (isJsonMode(opts)) {
612
- printJson({ ok: true, data: result, error: null });
613
- return;
614
- }
615
- console.log(JSON.stringify(result, null, 2));
616
- }
617
- catch (err) {
618
- handleError(err);
619
- }
620
- });
621
- const data = documents
622
- .command("data")
623
- .description("Read and write declared durable app collections");
624
- data
625
- .command("list <id> <collection>")
626
- .description("List records in one declared app collection")
627
- .option("--limit <count>", "Maximum records", "100")
628
- .option("--json", "Output machine-readable records")
629
- .action(async (id, collection, opts) => {
630
- try {
631
- const limit = parseNonNegativeInteger(opts.limit, "--limit");
632
- const payload = await new MiosaClient(loadConfig()).apiGet(`/api/v1/builder/apps/${encodeURIComponent(id)}/data/${encodeURIComponent(collection)}?limit=${limit}`);
633
- if (isJsonMode(opts)) {
634
- printJson({ ok: true, data: payload, error: null });
635
- return;
636
- }
637
- console.log(JSON.stringify(payload, null, 2));
638
- }
639
- catch (err) {
640
- handleError(err);
641
- }
642
- });
643
- data
644
- .command("get <id> <collection> <key>")
645
- .description("Read one exact app collection record")
646
- .option("--json", "Output a machine-readable record")
647
- .action(async (id, collection, key, opts) => {
648
- try {
649
- const payload = await new MiosaClient(loadConfig()).apiGet(`/api/v1/builder/apps/${encodeURIComponent(id)}/data/${encodeURIComponent(collection)}/${encodeURIComponent(key)}`);
650
- if (isJsonMode(opts)) {
651
- printJson({ ok: true, data: payload, error: null });
652
- return;
653
- }
654
- console.log(JSON.stringify(payload, null, 2));
655
- }
656
- catch (err) {
657
- handleError(err);
658
- }
659
- });
660
- data
661
- .command("put <id> <collection> <key>")
662
- .description("Create or update one app collection record")
663
- .requiredOption("--value <json>", "JSON object value")
664
- .option("--expected-version <number>", "Exact current version")
665
- .option("--json", "Output the stored record")
666
- .action(async (id, collection, key, opts) => {
667
- try {
668
- const body = {
669
- value: parseJsonObject(opts.value, "--value"),
670
- };
671
- if (opts.expectedVersion !== undefined) {
672
- body["expected_version"] = parseNonNegativeInteger(opts.expectedVersion, "--expected-version");
673
- }
674
- const payload = await new MiosaClient(loadConfig()).apiPut(`/api/v1/builder/apps/${encodeURIComponent(id)}/data/${encodeURIComponent(collection)}/${encodeURIComponent(key)}`, body);
675
- if (isJsonMode(opts)) {
676
- printJson({ ok: true, data: payload, error: null });
677
- return;
678
- }
679
- console.log(JSON.stringify(payload, null, 2));
680
- }
681
- catch (err) {
682
- handleError(err);
683
- }
684
- });
685
- data
686
- .command("delete <id> <collection> <key>")
687
- .description("Delete one exact app collection record")
688
- .option("--expected-version <number>", "Exact current version")
689
- .option("--json", "Output machine-readable result")
690
- .action(async (id, collection, key, opts) => {
691
- try {
692
- const query = opts.expectedVersion === undefined
693
- ? ""
694
- : `?expected_version=${parseNonNegativeInteger(opts.expectedVersion, "--expected-version")}`;
695
- await new MiosaClient(loadConfig()).apiDelete(`/api/v1/builder/apps/${encodeURIComponent(id)}/data/${encodeURIComponent(collection)}/${encodeURIComponent(key)}${query}`);
696
- const result = {
697
- app_document_id: id,
698
- collection,
699
- key,
700
- deleted: true,
701
- };
702
- if (isJsonMode(opts)) {
703
- printJson({ ok: true, data: result, error: null });
704
- return;
705
- }
706
- console.log(JSON.stringify(result, null, 2));
707
- }
708
- catch (err) {
709
- handleError(err);
710
- }
711
- });
712
- const automations = documents
713
- .command("automations")
714
- .description("Operate durable, authority-governed app automation runs");
715
- automations
716
- .command("list <id>")
717
- .description("List automation runs for one app")
718
- .option("--limit <count>", "Maximum runs", "100")
719
- .option("--json", "Output machine-readable runs")
720
- .action(async (id, opts) => {
721
- try {
722
- const limit = parseNonNegativeInteger(opts.limit, "--limit");
723
- const payload = await new MiosaClient(loadConfig()).apiGet(`/api/v1/builder/apps/${encodeURIComponent(id)}/automation-runs?limit=${limit}`);
724
- if (isJsonMode(opts)) {
725
- printJson({ ok: true, data: payload, error: null });
726
- return;
727
- }
728
- console.log(JSON.stringify(payload, null, 2));
729
- }
730
- catch (err) {
731
- handleError(err);
732
- }
733
- });
734
- automations
735
- .command("start <id> <automation>")
736
- .description("Start one reviewed automation")
737
- .option("--trigger <json>", "Trigger metadata JSON", "{}")
738
- .option("--json", "Output the durable run")
739
- .action(async (id, automation, opts) => {
740
- try {
741
- const payload = await new MiosaClient(loadConfig()).apiPost(`/api/v1/builder/apps/${encodeURIComponent(id)}/automations/${encodeURIComponent(automation)}/runs`, { trigger: parseJsonObject(opts.trigger, "--trigger") });
742
- if (isJsonMode(opts)) {
743
- printJson({ ok: true, data: payload, error: null });
744
- return;
745
- }
746
- console.log(JSON.stringify(payload, null, 2));
747
- }
748
- catch (err) {
749
- handleError(err);
750
- }
751
- });
752
- automations
753
- .command("claim <id> <run>")
754
- .description("Claim or resume the current automation step")
755
- .option("--json", "Output the exact authority-bound claim")
756
- .action(async (id, run, opts) => {
757
- try {
758
- const payload = await new MiosaClient(loadConfig()).apiPost(`/api/v1/builder/apps/${encodeURIComponent(id)}/automation-runs/${encodeURIComponent(run)}/claim`, {});
759
- if (isJsonMode(opts)) {
760
- printJson({ ok: true, data: payload, error: null });
761
- return;
762
- }
763
- console.log(JSON.stringify(payload, null, 2));
764
- }
765
- catch (err) {
766
- handleError(err);
767
- }
768
- });
769
- automations
770
- .command("complete <id> <run>")
771
- .description("Complete the exact claimed automation step")
772
- .requiredOption("--cursor <number>", "Claimed step cursor")
773
- .requiredOption("--idempotency-key <key>", "Claimed idempotency key")
774
- .option("--output <json>", "Step output JSON object", "{}")
775
- .option("--json", "Output the updated run")
776
- .action(async (id, run, opts) => {
777
- try {
778
- const payload = await new MiosaClient(loadConfig()).apiPost(`/api/v1/builder/apps/${encodeURIComponent(id)}/automation-runs/${encodeURIComponent(run)}/complete`, {
779
- cursor: parseNonNegativeInteger(opts.cursor, "--cursor"),
780
- idempotency_key: opts.idempotencyKey,
781
- output: parseJsonObject(opts.output, "--output"),
782
- });
783
- if (isJsonMode(opts)) {
784
- printJson({ ok: true, data: payload, error: null });
785
- return;
786
- }
787
- console.log(JSON.stringify(payload, null, 2));
788
- }
789
- catch (err) {
790
- handleError(err);
791
- }
792
- });
793
- automations
794
- .command("fail <id> <run>")
795
- .description("Fail the exact claimed automation step")
796
- .requiredOption("--cursor <number>", "Claimed step cursor")
797
- .requiredOption("--idempotency-key <key>", "Claimed idempotency key")
798
- .requiredOption("--reason <reason>", "Failure reason")
799
- .option("--json", "Output the updated run")
800
- .action(async (id, run, opts) => {
801
- try {
802
- const payload = await new MiosaClient(loadConfig()).apiPost(`/api/v1/builder/apps/${encodeURIComponent(id)}/automation-runs/${encodeURIComponent(run)}/fail`, {
803
- cursor: parseNonNegativeInteger(opts.cursor, "--cursor"),
804
- idempotency_key: opts.idempotencyKey,
805
- reason: opts.reason,
806
- });
807
- if (isJsonMode(opts)) {
808
- printJson({ ok: true, data: payload, error: null });
809
- return;
810
- }
811
- console.log(JSON.stringify(payload, null, 2));
812
- }
813
- catch (err) {
814
- handleError(err);
815
- }
816
- });
817
- app
818
- .command("pull")
819
- .argument("[path]", "Local app directory", ".")
820
- .description("Pull the linked application's configuration for local use")
821
- .option("--output <file>", "Output file relative to the app", ".env.local")
822
- .option("--overwrite", "Replace an existing output file")
823
- .option("--json", "Output configuration as JSON without writing a file")
824
- .action(async (inputPath, opts) => {
825
- try {
826
- const dir = path.resolve(inputPath);
827
- const link = requireApplicationLink(dir);
828
- const secrets = await fetchSecretValues(new MiosaClient(loadConfig()), link.deploymentId);
829
- if (isJsonMode(opts)) {
830
- printJson({
831
- ok: true,
832
- data: {
833
- application: link.name,
834
- deployment_id: link.deploymentId,
835
- environment: link.environment,
836
- configuration: Object.fromEntries(secrets.map(({ name, value }) => [name, value])),
837
- },
838
- error: null,
839
- });
840
- return;
841
- }
842
- const output = path.resolve(dir, opts.output);
843
- if (fs.existsSync(output) && !opts.overwrite) {
844
- throw new UserError(`${opts.output} already exists.`, "Pass --overwrite to replace it.");
845
- }
846
- fs.writeFileSync(output, toDotenv(secrets), { mode: 0o600 });
847
- fs.chmodSync(output, 0o600);
848
- ensureGitignored(dir, path.relative(dir, output));
849
- console.log(chalk.green(`Pulled ${secrets.length} configuration values to ${path.relative(dir, output)}.`));
850
- }
851
- catch (err) {
852
- handleError(err);
853
- }
854
- });
855
- app
856
- .command("preview")
857
- .argument("[path]", "Local app directory", ".")
858
- .description("Create a disposable preview from the current source")
859
- .option("--sandbox <id>", "Reuse an existing healthy sandbox")
860
- .option("--template <template>", "Sandbox template")
861
- .option("--name <name>", "Preview sandbox name")
862
- .option("--port <port>", "Application port", (value) => Number(value))
863
- .option("--start <command>", "Application start command")
864
- .option("--install-command <command>", "Dependency install command")
865
- .option("--no-install", "Skip dependency installation")
866
- .option("--timeout <seconds>", "Readiness timeout", (value) => Number(value), 600)
867
- .option("--probe-path <path>", "Readiness probe path", "/")
868
- .option("--json", "Output compact machine-readable JSON")
869
- .action(async (inputPath, opts) => {
870
- try {
871
- const dir = path.resolve(inputPath);
872
- const link = loadLocalLink(dir);
873
- const result = await deploySandbox(dir, {
874
- ...opts,
875
- wait: true,
876
- });
877
- const candidate = link && result.preview_ready
878
- ? deploymentPayload(await new MiosaClient(loadConfig()).apiPost(`/api/v1/deployments/${encodeURIComponent(link.deploymentId)}/publish`, {
879
- source_sandbox_id: result.sandbox_id,
880
- output_path: "/workspace",
881
- kind: "dynamic",
882
- start_command: opts.start,
883
- port: result.port,
884
- health_check_path: opts.probePath,
885
- promote: false,
886
- }, {
887
- "Idempotency-Key": `preview:${link.deploymentId}:${result.sandbox_id}`,
888
- }))
889
- : {};
890
- const release = record(candidate["release"]);
891
- const version = record(candidate["version"]);
892
- const payload = {
893
- schema_version: 1,
894
- application: link?.name ?? path.basename(dir),
895
- environment: "preview",
896
- sandbox_id: result.sandbox_id,
897
- release_id: stringValue(release, "id") ?? null,
898
- version_id: stringValue(version, "id") ?? null,
899
- artifact_sha256: stringValue(release, "artifact_sha256") ??
900
- stringValue(version, "artifact_sha256") ??
901
- null,
902
- url: result.preview_url,
903
- status: result.preview_ready ? "ready" : "blocked",
904
- promotion_allowed: false,
905
- next_actions: result.preview_ready
906
- ? stringValue(release, "id")
907
- ? [
908
- `miosa app promote ${stringValue(release, "id")} . --yes --json`,
909
- ]
910
- : [
911
- "Run `miosa app link --app <deployment-id>` to create an immutable candidate release.",
912
- ]
913
- : [
914
- `miosa sandbox doctor ${result.sandbox_id} --port ${result.port} --json`,
915
- ],
916
- };
917
- if (isJsonMode(opts)) {
918
- printJson({ ok: result.preview_ready, data: payload, error: null });
919
- return;
920
- }
921
- console.log(result.preview_ready
922
- ? chalk.green(`Preview ready: ${result.preview_url}`)
923
- : chalk.yellow(`Preview is not ready: ${result.preview_url}`));
924
- }
925
- catch (err) {
926
- handleError(err);
927
- }
928
- });
929
- app
930
- .command("verify <release-id>")
931
- .argument("[path]", "Local app directory", ".")
932
- .description("Prove that one exact immutable release and its declared capabilities are live")
933
- .option("--contract <file>", "Acceptance contract JSON path")
934
- .option("--json", "Output the stable release receipt as JSON")
935
- .action(async (releaseId, inputPath, opts) => {
936
- try {
937
- const dir = path.resolve(inputPath);
938
- const link = requireApplicationLink(dir);
939
- const { receipt, receiptPath } = await verifyLinkedRelease(new MiosaClient(loadConfig()), dir, link, releaseId, opts.contract);
940
- if (isJsonMode(opts)) {
941
- printJson({
942
- ok: receipt.result === "verified",
943
- data: { ...receipt, receipt_path: receiptPath },
944
- error: receipt.result === "verified"
945
- ? null
946
- : {
947
- code: "RELEASE_ACCEPTANCE_BLOCKED",
948
- message: "The exact release did not satisfy its acceptance contract.",
949
- },
950
- });
951
- return;
952
- }
953
- console.log();
954
- console.log(receipt.result === "verified"
955
- ? chalk.green.bold("Release verified")
956
- : chalk.red.bold("Release blocked"));
957
- for (const item of receipt.checks) {
958
- const marker = item.status === "pass"
959
- ? chalk.green("PASS")
960
- : item.status === "warning"
961
- ? chalk.yellow("WARN")
962
- : chalk.red("FAIL");
963
- console.log(` ${marker} ${item.id}: ${item.message}`);
964
- }
965
- console.log(chalk.dim(`Receipt: ${receiptPath}`));
966
- if (receipt.result !== "verified")
967
- process.exitCode = 1;
968
- }
969
- catch (err) {
970
- handleError(err);
971
- }
972
- });
973
- app
974
- .command("promote <release-id>")
975
- .argument("[path]", "Local app directory", ".")
976
- .description("Atomically promote one exact immutable release and verify it end to end")
977
- .option("--contract <file>", "Acceptance contract JSON path")
978
- .option("--timeout <seconds>", "Activation timeout", (value) => Number(value), 600)
979
- .option("--idempotency-key <key>", "Reuse an operation idempotency key")
980
- .option("-y, --yes", "Skip confirmation")
981
- .option("--json", "Output the stable operation and release receipt")
982
- .action(async (releaseId, inputPath, opts) => {
983
- try {
984
- const dir = path.resolve(inputPath);
985
- const link = requireApplicationLink(dir);
986
- if (!opts.yes) {
987
- const { default: inquirer } = await import("inquirer");
988
- const { ok } = await inquirer.prompt([
989
- {
990
- type: "confirm",
991
- name: "ok",
992
- message: `Promote exact release ${releaseId} to ${link.name} (${link.environment})?`,
993
- default: false,
994
- },
995
- ]);
996
- if (!ok)
997
- return;
998
- }
999
- const result = await activateLinkedRelease({
1000
- action: "promote",
1001
- dir,
1002
- link,
1003
- releaseId,
1004
- contractPath: opts.contract,
1005
- timeout: opts.timeout,
1006
- idempotencyKey: opts.idempotencyKey,
1007
- });
1008
- if (isJsonMode(opts)) {
1009
- printJson({
1010
- ok: result.receipt.result === "verified",
1011
- data: {
1012
- operation: result.operation,
1013
- receipt: result.receipt,
1014
- receipt_path: result.receiptPath,
1015
- },
1016
- error: result.receipt.result === "verified"
1017
- ? null
1018
- : {
1019
- code: "RELEASE_ACCEPTANCE_BLOCKED",
1020
- message: "Promotion completed but acceptance was blocked.",
1021
- },
1022
- });
1023
- return;
1024
- }
1025
- console.log(result.receipt.result === "verified"
1026
- ? chalk.green.bold(`Release ${releaseId} is active and verified.`)
1027
- : chalk.red.bold(`Release ${releaseId} activated but failed acceptance.`));
1028
- console.log(chalk.dim(`Operation: ${result.operation.operation_id}`));
1029
- console.log(chalk.dim(`Receipt: ${result.receiptPath}`));
1030
- if (result.receipt.result !== "verified")
1031
- process.exitCode = 1;
1032
- }
1033
- catch (err) {
1034
- handleError(err);
1035
- }
1036
- });
1037
- app
1038
- .command("rollback <release-id>")
1039
- .argument("[path]", "Local app directory", ".")
1040
- .description("Rollback code to one exact immutable release and verify it")
1041
- .option("--contract <file>", "Acceptance contract JSON path")
1042
- .option("--timeout <seconds>", "Activation timeout", (value) => Number(value), 600)
1043
- .option("--idempotency-key <key>", "Reuse an operation idempotency key")
1044
- .option("--acknowledge-data-risk", "Acknowledge that code rollback does not reverse database migrations")
1045
- .option("-y, --yes", "Skip confirmation")
1046
- .option("--json", "Output the stable operation and release receipt")
1047
- .action(async (releaseId, inputPath, opts) => {
1048
- try {
1049
- const dir = path.resolve(inputPath);
1050
- const link = requireApplicationLink(dir);
1051
- const client = new MiosaClient(loadConfig());
1052
- const release = await getRelease(client, link.deploymentId, releaseId);
1053
- const migrationCompatibility = stringValue(release, "migration_compatibility") ??
1054
- stringValue(record(release["metadata"]), "migration_compatibility");
1055
- if (migrationCompatibility === "incompatible" &&
1056
- !opts.acknowledgeDataRisk) {
1057
- throw new UserError("Rollback is blocked because this release declares incompatible database migrations.", "Restore or migrate the database first, or pass --acknowledge-data-risk after reviewing the impact.");
1058
- }
1059
- if (!opts.yes) {
1060
- const { default: inquirer } = await import("inquirer");
1061
- const { ok } = await inquirer.prompt([
1062
- {
1063
- type: "confirm",
1064
- name: "ok",
1065
- message: `Rollback ${link.name} to exact release ${releaseId}? Database migrations are not reversed.`,
1066
- default: false,
1067
- },
1068
- ]);
1069
- if (!ok)
1070
- return;
1071
- }
1072
- const result = await activateLinkedRelease({
1073
- action: "rollback",
1074
- dir,
1075
- link,
1076
- releaseId,
1077
- contractPath: opts.contract,
1078
- timeout: opts.timeout,
1079
- idempotencyKey: opts.idempotencyKey,
1080
- });
1081
- if (isJsonMode(opts)) {
1082
- printJson({
1083
- ok: result.receipt.result === "verified",
1084
- data: {
1085
- operation: result.operation,
1086
- receipt: result.receipt,
1087
- receipt_path: result.receiptPath,
1088
- },
1089
- error: result.receipt.result === "verified"
1090
- ? null
1091
- : {
1092
- code: "ROLLBACK_ACCEPTANCE_BLOCKED",
1093
- message: "Rollback completed but acceptance was blocked.",
1094
- },
1095
- });
1096
- return;
1097
- }
1098
- console.log(chalk.green.bold(`Rollback to ${releaseId} is active and verified.`));
1099
- console.log(chalk.dim(`Operation: ${result.operation.operation_id}`));
1100
- console.log(chalk.dim(`Receipt: ${result.receiptPath}`));
1101
- }
1102
- catch (err) {
1103
- handleError(err);
1104
- }
1105
- });
1106
- app
1107
- .command("status <operation-id>")
1108
- .description("Read durable deployment operation status from MIOSA")
1109
- .option("--json", "Output machine-readable operation state")
1110
- .action(async (operationId, opts) => {
1111
- try {
1112
- const payload = deploymentPayload(await new MiosaClient(loadConfig()).apiGet(`/api/v1/operations/${encodeURIComponent(operationId)}`));
1113
- if (isJsonMode(opts)) {
1114
- printJson({ ok: true, data: payload, error: null });
1115
- return;
1116
- }
1117
- console.log(JSON.stringify(payload, null, 2));
1118
- }
1119
- catch (err) {
1120
- handleError(err);
1121
- }
1122
- });
1123
- app
1124
- .command("recover <operation-id>")
1125
- .argument("[path]", "Local app directory", ".")
1126
- .description("Inspect or safely resume an interrupted app operation")
1127
- .option("--resume", "Retry the operation with its original idempotency key")
1128
- .option("--contract <file>", "Acceptance contract JSON path")
1129
- .option("--timeout <seconds>", "Activation timeout", (value) => Number(value), 600)
1130
- .option("--json", "Output machine-readable operation state")
1131
- .action(async (operationId, inputPath, opts) => {
1132
- try {
1133
- const dir = path.resolve(inputPath);
1134
- const existing = loadApplicationOperation(dir, operationId);
1135
- if (!existing) {
1136
- throw new UserError(`Application operation not found: ${operationId}`);
1137
- }
1138
- if (existing.server_operation_id && !opts.resume) {
1139
- const remote = deploymentPayload(await new MiosaClient(loadConfig()).apiGet(`/api/v1/operations/${encodeURIComponent(existing.server_operation_id)}`));
1140
- if (isJsonMode(opts)) {
1141
- printJson({
1142
- ok: true,
1143
- data: { local: existing, remote },
1144
- error: null,
1145
- });
1146
- }
1147
- else {
1148
- console.log(JSON.stringify({ local: existing, remote }, null, 2));
1149
- }
1150
- return;
1151
- }
1152
- if (!opts.resume || existing.state === "succeeded") {
1153
- if (isJsonMode(opts)) {
1154
- printJson({ ok: true, data: existing, error: null });
1155
- }
1156
- else {
1157
- console.log(JSON.stringify(existing, null, 2));
1158
- }
1159
- return;
1160
- }
1161
- const result = await activateLinkedRelease({
1162
- action: existing.action,
1163
- dir,
1164
- link: requireApplicationLink(dir),
1165
- releaseId: existing.release_id,
1166
- contractPath: opts.contract,
1167
- timeout: opts.timeout,
1168
- idempotencyKey: existing.idempotency_key,
1169
- });
1170
- if (isJsonMode(opts)) {
1171
- printJson({ ok: true, data: result, error: null });
1172
- }
1173
- else {
1174
- console.log(chalk.green(`Operation resumed and ${result.receipt.result}.`));
1175
- }
1176
- }
1177
- catch (err) {
1178
- handleError(err);
1179
- }
1180
- });
1181
- }
1182
- //# sourceMappingURL=app.js.map