@xano/sdk 1.0.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 (336) hide show
  1. package/CHANGELOG.md +788 -0
  2. package/LICENSE +21 -0
  3. package/README.md +541 -0
  4. package/dist/.build-fingerprint +1 -0
  5. package/dist/agent-file-refresh-ZEMK33AX.js +38 -0
  6. package/dist/answer-shape-K67TAAPY.js +33 -0
  7. package/dist/backend-dir-2U53CIAL.js +39 -0
  8. package/dist/backend-slot-7QXW2QYC.js +28 -0
  9. package/dist/bin.d.ts +1 -0
  10. package/dist/bin.js +255 -0
  11. package/dist/branch-NCRNWQBQ.js +61 -0
  12. package/dist/branch-commands-ACIRCEQJ.js +79 -0
  13. package/dist/bundle.d.ts +223 -0
  14. package/dist/bundle.js +153 -0
  15. package/dist/capture-WAXPD7DR.js +41 -0
  16. package/dist/chunk-27GWNP2I.js +23 -0
  17. package/dist/chunk-2CMJZDCL.js +177 -0
  18. package/dist/chunk-2EZ3ZJZZ.js +302 -0
  19. package/dist/chunk-2GNFDZA2.js +390 -0
  20. package/dist/chunk-2MNLRIOX.js +11 -0
  21. package/dist/chunk-2TFRR6JV.js +104 -0
  22. package/dist/chunk-2ZUEE4EK.js +408 -0
  23. package/dist/chunk-36JUQZVQ.js +22 -0
  24. package/dist/chunk-3DRXWLJ5.js +83 -0
  25. package/dist/chunk-3JDU4VRL.js +137 -0
  26. package/dist/chunk-3KZCLN4Z.js +241 -0
  27. package/dist/chunk-3LDULPRE.js +168 -0
  28. package/dist/chunk-3M4LFYNQ.js +111 -0
  29. package/dist/chunk-3XI5CTUE.js +22 -0
  30. package/dist/chunk-3YW23UFH.js +50 -0
  31. package/dist/chunk-45UIT5T2.js +862 -0
  32. package/dist/chunk-4BW2SG2N.js +46 -0
  33. package/dist/chunk-4KHEMC32.js +79 -0
  34. package/dist/chunk-4POWHT2K.js +321 -0
  35. package/dist/chunk-4Q2GN7NW.js +192 -0
  36. package/dist/chunk-5A2PLKZB.js +70 -0
  37. package/dist/chunk-5FBYXK5P.js +159 -0
  38. package/dist/chunk-5HVXPTU4.js +323 -0
  39. package/dist/chunk-5QU2P5CA.js +304 -0
  40. package/dist/chunk-5V5XU32D.js +191 -0
  41. package/dist/chunk-5ZSO4T2G.js +10 -0
  42. package/dist/chunk-622HUCZT.js +10 -0
  43. package/dist/chunk-65HWOMGV.js +177 -0
  44. package/dist/chunk-6ELFRN3P.js +365 -0
  45. package/dist/chunk-6HO3NCSJ.js +1055 -0
  46. package/dist/chunk-6IUMKYWI.js +457 -0
  47. package/dist/chunk-6KEB3C3U.js +65 -0
  48. package/dist/chunk-6MR5TI5V.js +987 -0
  49. package/dist/chunk-6NNTNXN7.js +157 -0
  50. package/dist/chunk-6PBR37LN.js +97 -0
  51. package/dist/chunk-6QXLMMT3.js +155 -0
  52. package/dist/chunk-6ZGJCBZS.js +224 -0
  53. package/dist/chunk-73IVBKMA.js +250 -0
  54. package/dist/chunk-7G3CTU7I.js +286 -0
  55. package/dist/chunk-A3UDOZB6.js +222 -0
  56. package/dist/chunk-A6E77GDW.js +85 -0
  57. package/dist/chunk-AHJWCYQO.js +660 -0
  58. package/dist/chunk-AKNCFVKZ.js +36 -0
  59. package/dist/chunk-AM4FKL4J.js +237 -0
  60. package/dist/chunk-AN6BL47T.js +26 -0
  61. package/dist/chunk-AOSYVMUS.js +147 -0
  62. package/dist/chunk-APWXY5SL.js +182 -0
  63. package/dist/chunk-AWEIIR2U.js +218 -0
  64. package/dist/chunk-AWQ7BQTQ.js +73 -0
  65. package/dist/chunk-BAUZOWGX.js +393 -0
  66. package/dist/chunk-BHACRS6R.js +940 -0
  67. package/dist/chunk-BWPNT55T.js +680 -0
  68. package/dist/chunk-C6RIMRU4.js +187 -0
  69. package/dist/chunk-CGVQZXYG.js +263 -0
  70. package/dist/chunk-CIMQZRRE.js +162 -0
  71. package/dist/chunk-CJHQKJU4.js +113 -0
  72. package/dist/chunk-CTMO46PK.js +1897 -0
  73. package/dist/chunk-D53J55C5.js +106 -0
  74. package/dist/chunk-D7VGG3WS.js +90 -0
  75. package/dist/chunk-DAD3ONIS.js +245 -0
  76. package/dist/chunk-DGWHAVRG.js +162 -0
  77. package/dist/chunk-DX4QR4B2.js +483 -0
  78. package/dist/chunk-EHP3WPEG.js +21 -0
  79. package/dist/chunk-ELP2HMXC.js +432 -0
  80. package/dist/chunk-ERVIASGL.js +21 -0
  81. package/dist/chunk-ET4Y4XCB.js +865 -0
  82. package/dist/chunk-ETO6LGLD.js +4750 -0
  83. package/dist/chunk-EUUUMY7J.js +24 -0
  84. package/dist/chunk-FQJ2TTHP.js +218 -0
  85. package/dist/chunk-FQOF7E2E.js +133 -0
  86. package/dist/chunk-FWD7AL6N.js +21 -0
  87. package/dist/chunk-FXFV3KU6.js +138 -0
  88. package/dist/chunk-FXRQOWTE.js +171 -0
  89. package/dist/chunk-G554NZNI.js +210 -0
  90. package/dist/chunk-GSGDWJB5.js +13 -0
  91. package/dist/chunk-H2V3N23D.js +66 -0
  92. package/dist/chunk-H5C7MBCR.js +159 -0
  93. package/dist/chunk-HHN734BU.js +371 -0
  94. package/dist/chunk-HRVBLCVJ.js +243 -0
  95. package/dist/chunk-HVRUQXGD.js +1264 -0
  96. package/dist/chunk-I4F5TCJH.js +130 -0
  97. package/dist/chunk-IDOTCMDV.js +57 -0
  98. package/dist/chunk-IGOLHKWF.js +427 -0
  99. package/dist/chunk-JGE7CAWB.js +148 -0
  100. package/dist/chunk-JTUKLCXS.js +92 -0
  101. package/dist/chunk-JZGVVJSI.js +66 -0
  102. package/dist/chunk-K4WX6UUU.js +923 -0
  103. package/dist/chunk-K5BBGTYZ.js +217 -0
  104. package/dist/chunk-K6RXBGUB.js +427 -0
  105. package/dist/chunk-KTSDSD36.js +165 -0
  106. package/dist/chunk-L5JYN3NM.js +1038 -0
  107. package/dist/chunk-LIEOKXKD.js +354 -0
  108. package/dist/chunk-LLNZGEFK.js +51 -0
  109. package/dist/chunk-LPECSJ2J.js +55 -0
  110. package/dist/chunk-LQCMKAJ7.js +413 -0
  111. package/dist/chunk-LRN4ZJCQ.js +1145 -0
  112. package/dist/chunk-MJ4ZVHKN.js +17 -0
  113. package/dist/chunk-MXHSQOC4.js +3061 -0
  114. package/dist/chunk-N5GKCWE5.js +367 -0
  115. package/dist/chunk-NA3PXMEF.js +10 -0
  116. package/dist/chunk-NAQDMEHV.js +76 -0
  117. package/dist/chunk-NWKXM5RD.js +109 -0
  118. package/dist/chunk-NZOWWHU5.js +196 -0
  119. package/dist/chunk-OHX6MIUZ.js +184 -0
  120. package/dist/chunk-OOXWYAA4.js +15 -0
  121. package/dist/chunk-OPHB5ORL.js +1990 -0
  122. package/dist/chunk-OXA6PSZT.js +1725 -0
  123. package/dist/chunk-P2HAGF6H.js +73 -0
  124. package/dist/chunk-PTHVMXZI.js +3036 -0
  125. package/dist/chunk-PZ5AY32C.js +10 -0
  126. package/dist/chunk-Q325JKYB.js +189 -0
  127. package/dist/chunk-Q7DGTQ5G.js +255 -0
  128. package/dist/chunk-QCNYHBL7.js +601 -0
  129. package/dist/chunk-QO6BVGS5.js +145 -0
  130. package/dist/chunk-QXTKSOFI.js +76 -0
  131. package/dist/chunk-ROY4YAEQ.js +66 -0
  132. package/dist/chunk-RTJRZFFY.js +447 -0
  133. package/dist/chunk-SAVJUS2X.js +128 -0
  134. package/dist/chunk-SFLHVCKX.js +173 -0
  135. package/dist/chunk-STSFNCY4.js +127 -0
  136. package/dist/chunk-SWBF2LTK.js +170 -0
  137. package/dist/chunk-T5KELPAR.js +109 -0
  138. package/dist/chunk-TFFGOFVZ.js +1481 -0
  139. package/dist/chunk-TLHIFK4M.js +256 -0
  140. package/dist/chunk-TLQE7ZN3.js +156 -0
  141. package/dist/chunk-TPHWJ7UG.js +1981 -0
  142. package/dist/chunk-TRJCALW3.js +291 -0
  143. package/dist/chunk-TTEIYD5P.js +133 -0
  144. package/dist/chunk-U64O2MXY.js +407 -0
  145. package/dist/chunk-UCQ2VUTG.js +630 -0
  146. package/dist/chunk-UTI5G6OJ.js +44 -0
  147. package/dist/chunk-UVHDMMIP.js +188 -0
  148. package/dist/chunk-UZ6QQWJT.js +120 -0
  149. package/dist/chunk-VAX3UZOY.js +686 -0
  150. package/dist/chunk-W3HBUKFO.js +57 -0
  151. package/dist/chunk-WKQLGKCL.js +2823 -0
  152. package/dist/chunk-WQFNASK4.js +560 -0
  153. package/dist/chunk-WRBKLYSJ.js +224 -0
  154. package/dist/chunk-WTPZRR4I.js +17 -0
  155. package/dist/chunk-WZDJ2LLX.js +2385 -0
  156. package/dist/chunk-X2NL4KUO.js +14 -0
  157. package/dist/chunk-X4DVXBFY.js +38 -0
  158. package/dist/chunk-X677DMZM.js +7050 -0
  159. package/dist/chunk-XBKMWY7F.js +612 -0
  160. package/dist/chunk-XNCP4KYO.js +78 -0
  161. package/dist/chunk-XVBGLISP.js +35 -0
  162. package/dist/chunk-XW6KISBB.js +1192 -0
  163. package/dist/chunk-YGZHHAAB.js +8156 -0
  164. package/dist/chunk-YHEFQUQB.js +186 -0
  165. package/dist/chunk-YLDALTWZ.js +653 -0
  166. package/dist/chunk-YU4HSQW7.js +229 -0
  167. package/dist/chunk-ZDPP6RKB.js +27 -0
  168. package/dist/chunk-ZFDZKNGG.js +194 -0
  169. package/dist/chunk-ZIY7RNUT.js +49 -0
  170. package/dist/chunk-ZYJP6BOO.js +30 -0
  171. package/dist/cli.d.ts +1111 -0
  172. package/dist/cli.js +165 -0
  173. package/dist/codegen-command-VR2GWR6C.js +173 -0
  174. package/dist/codegen.d.ts +115 -0
  175. package/dist/codegen.js +19 -0
  176. package/dist/commands-GJMJ4XYZ.js +76 -0
  177. package/dist/completion-ZQLO6PB6.js +738 -0
  178. package/dist/config-MBYGCAFK.js +136 -0
  179. package/dist/deploy-command-JVZPWHMK.js +180 -0
  180. package/dist/deploy-source-3W45CXMP.js +81 -0
  181. package/dist/dev-env-sync-HN44K4D5.js +188 -0
  182. package/dist/diagnostics-UEAAHWVF.js +30 -0
  183. package/dist/display-name-hint-ABBPVQIR.js +46 -0
  184. package/dist/emit-CyhBDxli.d.ts +7007 -0
  185. package/dist/env-example-refresh-ET5HMMDW.js +126 -0
  186. package/dist/env-pull-command-TNMNB3CV.js +323 -0
  187. package/dist/env-target-O4HRKTGZ.js +40 -0
  188. package/dist/env-var-command-ZIRDCAZA.js +427 -0
  189. package/dist/ephemeral-P7F3PMAD.js +54 -0
  190. package/dist/ephemeral-command-CLJJKOFT.js +592 -0
  191. package/dist/ephemeral-state-PYCBSOGX.js +61 -0
  192. package/dist/file-lock-PT74GWYW.js +10 -0
  193. package/dist/generate-command-AYEOLA26.js +510 -0
  194. package/dist/gitignore-3SJ3WNRG.js +51 -0
  195. package/dist/guards-4EBNCZDC.js +162 -0
  196. package/dist/hosted-file-PSHJB3HX.js +28 -0
  197. package/dist/impersonate-command-5JAS3WSV.js +152 -0
  198. package/dist/import-EQSFU6JC.js +19 -0
  199. package/dist/index.d.ts +5470 -0
  200. package/dist/index.js +371 -0
  201. package/dist/init-command-X2FR4UAK.js +125 -0
  202. package/dist/init-modules-RY7UHAOL.js +50 -0
  203. package/dist/init-web-M4YZSZK6.js +42 -0
  204. package/dist/internal.d.ts +179 -0
  205. package/dist/internal.js +2634 -0
  206. package/dist/io-RC56QSN5.js +26 -0
  207. package/dist/keep-data-merge-7MPLVAVI.js +1119 -0
  208. package/dist/lambda-config-reconcile-OUZ4OYAB.js +116 -0
  209. package/dist/landed-753YLJ5H.js +40 -0
  210. package/dist/landing-record-SU52SKXU.js +61 -0
  211. package/dist/live-diff-YONW2VI3.js +65 -0
  212. package/dist/local-engine-choice-CH5X3W7E.js +79 -0
  213. package/dist/local-engine-command-Z3OL7VOD.js +766 -0
  214. package/dist/local-engine-config-5U3SC434.js +39 -0
  215. package/dist/local-engine-deploy-PCQ4SNPB.js +39 -0
  216. package/dist/local-engine-process-EHTE5LLU.js +63 -0
  217. package/dist/local-engine-state-A4FTRFAF.js +32 -0
  218. package/dist/local-engine-update-check-6L645VBL.js +162 -0
  219. package/dist/lock-MRRHW5GS.js +87 -0
  220. package/dist/lock-commands-2QG25HL7.js +963 -0
  221. package/dist/login-command-QPYRWOXZ.js +538 -0
  222. package/dist/logout-command-WOIQLDP6.js +56 -0
  223. package/dist/loop-ALIZLOSX.js +191 -0
  224. package/dist/marketplace-command-K5YL42NO.js +977 -0
  225. package/dist/marketplace-resolve-LY32JES5.js +40 -0
  226. package/dist/meta-client-YXGPW53C.js +244 -0
  227. package/dist/module-manifest-JFGHU2TC.js +38 -0
  228. package/dist/near-key.d.ts +13 -0
  229. package/dist/near-key.js +8 -0
  230. package/dist/node.d.ts +95 -0
  231. package/dist/node.js +969 -0
  232. package/dist/operation-outcome-TZSESNC7.js +51 -0
  233. package/dist/output-target-AL3I44GG.js +47 -0
  234. package/dist/package-manager-PRAHUSCN.js +34 -0
  235. package/dist/plan-disclosure-6G4MLZKD.js +114 -0
  236. package/dist/plugin-contributions-WRNY5ABG.js +28 -0
  237. package/dist/plugin-prompt-4VA3B4FF.js +20 -0
  238. package/dist/plugin-questions-JTSYA74Q.js +24 -0
  239. package/dist/plugin.d.ts +396 -0
  240. package/dist/plugin.js +1 -0
  241. package/dist/preflight-command-2T5Z36MI.js +321 -0
  242. package/dist/profile-command-AH3PIM4X.js +800 -0
  243. package/dist/profile-pointer-GRWJU3YD.js +31 -0
  244. package/dist/profile-select-74TRDEPD.js +23 -0
  245. package/dist/project-dependency-KSH63ODT.js +35 -0
  246. package/dist/project-sdk-REPPOIBD.js +24 -0
  247. package/dist/promote-command-PCWT5N6S.js +140 -0
  248. package/dist/prompt-II3F3LND.js +27 -0
  249. package/dist/publish-command-TTDUUJI5.js +414 -0
  250. package/dist/pull-command-VBO7C4S3.js +161 -0
  251. package/dist/pull-superseded-GJWLG7XO.js +20 -0
  252. package/dist/release-command-N4ZPKMHR.js +146 -0
  253. package/dist/release-ns-command-3KFDMZ6G.js +1745 -0
  254. package/dist/response-HlXahv4K.d.ts +925 -0
  255. package/dist/retry-command-AS5EVREX.js +34 -0
  256. package/dist/routes-manifest-SNWUVBT6.js +43 -0
  257. package/dist/runtime-XETHVF33.js +14 -0
  258. package/dist/scaffold.d.ts +1911 -0
  259. package/dist/scaffold.js +107 -0
  260. package/dist/secrets-file-LVZD6IIM.js +56 -0
  261. package/dist/secrets-fill-command-TTCPSVXN.js +218 -0
  262. package/dist/seed-VU7C3QYS.js +46 -0
  263. package/dist/sent-writes-N7X4OVXT.js +22 -0
  264. package/dist/source-resolve-S2XA3XZF.js +83 -0
  265. package/dist/static-host-B2Y6AG3W.js +352 -0
  266. package/dist/status-command-RUDXTF7I.js +554 -0
  267. package/dist/store-6VNCD4D7.js +20 -0
  268. package/dist/store-ARM6VMO5.js +98 -0
  269. package/dist/store-DuYfzKlW.d.ts +3144 -0
  270. package/dist/suggest-6FOOYKHG.js +12 -0
  271. package/dist/sveltekit.d.ts +154 -0
  272. package/dist/sveltekit.js +109 -0
  273. package/dist/sync-contributions-UCEROO26.js +415 -0
  274. package/dist/table-ENAVMITR.js +42 -0
  275. package/dist/tables-command-GUPXXSB5.js +156 -0
  276. package/dist/tenant-IIHPOHGP.js +42 -0
  277. package/dist/tenant-command-D5HGI2X4.js +965 -0
  278. package/dist/test-command-TIKZMDPZ.js +476 -0
  279. package/dist/tests-BGGIOK3L.js +26 -0
  280. package/dist/token-NICJUTMT.js +72 -0
  281. package/dist/toolchain-hooks-GHKLUJOH.js +96 -0
  282. package/dist/toolchain-modules-5EAZUONB.js +24 -0
  283. package/dist/tracked-backend-EIBUMDZA.js +80 -0
  284. package/dist/update-check-2W2NLDTC.js +136 -0
  285. package/dist/upgrade-command-QHNFWM7O.js +531 -0
  286. package/dist/verify-rollout-DRCK5TDD.js +61 -0
  287. package/dist/whoami-command-STGINTXH.js +51 -0
  288. package/dist/workspace-2CLHU2LK.js +93 -0
  289. package/dist/workspace-binding-56PIIPCP.js +54 -0
  290. package/dist/workspace-command-JEXQETJD.js +535 -0
  291. package/dist/workspace-env-F2RFMSC5.js +70 -0
  292. package/dist/workspace-export-OJSH2HIW.js +21 -0
  293. package/dist/writable-VA7OISSK.js +25 -0
  294. package/dist/xano-ICFUSPFR.js +42 -0
  295. package/dist/xanosdk-import-GN42TO2B.js +56 -0
  296. package/dist/xanosdk-project-S6DXJONQ.js +41 -0
  297. package/dist/xdo-CxDr2Q1C.d.ts +1371 -0
  298. package/guides/README.md +33 -0
  299. package/guides/authoring.md +921 -0
  300. package/guides/cli.md +401 -0
  301. package/guides/codegen.md +177 -0
  302. package/guides/codes.md +404 -0
  303. package/guides/coverage.md +74 -0
  304. package/guides/deploying.md +1525 -0
  305. package/guides/environment.md +400 -0
  306. package/guides/marketplace.md +415 -0
  307. package/guides/module-contract.md +558 -0
  308. package/guides/object-kinds.md +433 -0
  309. package/guides/project-structure.md +43 -0
  310. package/guides/scaffold.md +351 -0
  311. package/guides/typed-frontend.md +242 -0
  312. package/llms/client.md +63 -0
  313. package/llms/errors.md +56 -0
  314. package/llms/fields.md +176 -0
  315. package/llms/filters.md +183 -0
  316. package/llms/kinds-agent-mcp.md +30 -0
  317. package/llms/kinds-core.md +100 -0
  318. package/llms/kinds-knowledge.md +20 -0
  319. package/llms/kinds-realtime.md +76 -0
  320. package/llms/lambda.md +94 -0
  321. package/llms/legacy.md +44 -0
  322. package/llms/lock.md +40 -0
  323. package/llms/object-kinds.md +34 -0
  324. package/llms/statements-calls.md +62 -0
  325. package/llms/statements-catalog.md +320 -0
  326. package/llms/statements-data.md +66 -0
  327. package/llms/statements-runtime.md +68 -0
  328. package/llms/tests.md +59 -0
  329. package/llms/toolchain.md +16 -0
  330. package/llms/triggers.md +36 -0
  331. package/llms/values.md +29 -0
  332. package/llms-full.txt +2085 -0
  333. package/llms.txt +493 -0
  334. package/manifest.json +11224 -0
  335. package/package.json +162 -0
  336. package/types/lambda-globals.d.ts +129 -0
@@ -0,0 +1,3036 @@
1
+ import {
2
+ suggest
3
+ } from "./chunk-UTI5G6OJ.js";
4
+ import {
5
+ setDiagnosticSink
6
+ } from "./chunk-2EZ3ZJZZ.js";
7
+ import {
8
+ shellQuote
9
+ } from "./chunk-5ZSO4T2G.js";
10
+ import {
11
+ fontIdsFor
12
+ } from "./chunk-TFFGOFVZ.js";
13
+ import {
14
+ withArticle
15
+ } from "./chunk-36JUQZVQ.js";
16
+
17
+ // src/emit/ui.ts
18
+ import { randomBytes } from "crypto";
19
+
20
+ // src/emit/output.ts
21
+ import { AsyncLocalStorage } from "async_hooks";
22
+
23
+ // src/emit/json-target.ts
24
+ var BACKEND_KINDS = /* @__PURE__ */ new Set(["workspace", "ephemeral", "tenant", "local-engine"]);
25
+ var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
26
+ var text = (v) => typeof v === "string" && v !== "" ? v : void 0;
27
+ function backendSelector(kind, name) {
28
+ if (typeof kind !== "string" || !BACKEND_KINDS.has(kind)) return void 0;
29
+ if (kind === "workspace") return "workspace";
30
+ const n = text(name);
31
+ if (n !== void 0) return n.startsWith(`${kind}:`) ? n : `${kind}:${n}`;
32
+ return kind === "tenant" ? void 0 : kind;
33
+ }
34
+ function derive(doc) {
35
+ const out = {};
36
+ const destination = doc.destination;
37
+ if (isObject(destination)) {
38
+ out.selector = backendSelector(destination.kind, destination.label);
39
+ if (typeof destination.workspaceId === "number") out.workspaceId = destination.workspaceId;
40
+ } else if (typeof doc.kind === "string" && BACKEND_KINDS.has(doc.kind) && "name" in doc) {
41
+ out.selector = backendSelector(doc.kind, doc.name);
42
+ } else if (isObject(doc.deployed) && "environment" in doc) {
43
+ const kind = doc.deployed.kind;
44
+ const env = isObject(doc.environment) ? doc.environment.name : void 0;
45
+ if (kind === "ephemeral" && text(env) !== void 0) out.selector = `ephemeral:${env}`;
46
+ else if (kind === "local-engine") out.selector = "local-engine";
47
+ }
48
+ if (out.workspaceId === void 0 && isObject(doc.workspace) && typeof doc.workspace.id === "number") {
49
+ out.workspaceId = doc.workspace.id;
50
+ }
51
+ return out;
52
+ }
53
+ function withBackendFields(value) {
54
+ if (!isObject(value) || "error" in value) return value;
55
+ const { selector, workspaceId } = derive(value);
56
+ return {
57
+ ...value,
58
+ ...selector !== void 0 && !("selector" in value) ? { selector } : {},
59
+ ...workspaceId !== void 0 && !("workspaceId" in value) ? { workspaceId } : {}
60
+ };
61
+ }
62
+
63
+ // src/emit/invocation.ts
64
+ import { existsSync, readFileSync, realpathSync, statSync } from "fs";
65
+ import { basename, dirname, isAbsolute as isAbsolute3, join, relative as relative3, resolve as resolve3, sep as sep3 } from "path";
66
+ import { homedir } from "os";
67
+
68
+ // src/emit/typed-cwd.ts
69
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
70
+
71
+ // src/util/rel-path.ts
72
+ import { isAbsolute, relative, resolve, sep } from "path";
73
+ function relForwardSlash(root, target) {
74
+ const rel = relative(root, target);
75
+ return rel === "" || rel.startsWith("..") ? "" : rel.split(sep).join("/");
76
+ }
77
+ var typedFrom;
78
+ function setPathsShownFrom(dir) {
79
+ typedFrom = dir;
80
+ }
81
+ function pathsShownFrom() {
82
+ return typedFrom;
83
+ }
84
+ function displayPath(target, root) {
85
+ if (root === void 0 && typedFrom !== void 0) {
86
+ const abs = resolve(target);
87
+ const fromTyped = relative(typedFrom, abs).split(sep).join("/");
88
+ if (fromTyped === "") return ".";
89
+ if (!fromTyped.startsWith("..") && !isAbsolute(fromTyped)) return fromTyped;
90
+ return relForwardSlash(process.cwd(), abs) !== "" ? fromTyped : abs;
91
+ }
92
+ return relForwardSlash(root ?? process.cwd(), target) || target;
93
+ }
94
+
95
+ // src/emit/typed-cwd.ts
96
+ var base;
97
+ function setTypedCwdBase(dir) {
98
+ base = dir;
99
+ setPathsShownFrom(dir);
100
+ }
101
+ function setTypedCwd(dir) {
102
+ setPathsShownFrom(dir ?? base);
103
+ }
104
+ function pastePath(path) {
105
+ const typed = pathsShownFrom();
106
+ if (typed === void 0 || isAbsolute2(path)) return path;
107
+ return relative2(typed, resolve2(path)).split(sep2).join("/") || ".";
108
+ }
109
+
110
+ // src/emit/invocation.ts
111
+ var GLOBAL_STORES = [
112
+ `${sep3}lib${sep3}node_modules${sep3}`,
113
+ `${sep3}npm${sep3}node_modules${sep3}`,
114
+ `${sep3}pnpm${sep3}global${sep3}`,
115
+ `${sep3}yarn${sep3}global${sep3}`
116
+ ];
117
+ function launcherFor(facts) {
118
+ const bin = facts.binPath;
119
+ const marker = `${sep3}node_modules${sep3}`;
120
+ const at = bin.lastIndexOf(marker);
121
+ if (at === -1) return "path";
122
+ if (bin.includes(`${sep3}_npx${sep3}`) || facts.env.npm_command === "exec") return "npx";
123
+ const installRoot = bin.slice(0, at);
124
+ const cwd = facts.cwd;
125
+ if (cwd === installRoot || cwd.startsWith(installRoot + sep3)) return "npx";
126
+ const store = bin.slice(0, at + marker.length);
127
+ if (GLOBAL_STORES.some((s) => store.endsWith(s) || bin.includes(s))) return "path";
128
+ return "npx";
129
+ }
130
+ function typedDirFor(cwd, env) {
131
+ const init = env.INIT_CWD;
132
+ if (init === void 0 || init === "" || env.npm_lifecycle_event === void 0) return cwd;
133
+ if (env.npm_package_json === void 0 || resolve3(env.npm_package_json) !== resolve3(cwd, "package.json")) return cwd;
134
+ const rel = relative3(cwd, init);
135
+ return rel === "" || !rel.startsWith("..") && !isAbsolute3(rel) ? resolve3(init) : cwd;
136
+ }
137
+ var installedCache = /* @__PURE__ */ new Map();
138
+ function binDirAbove(from) {
139
+ for (let d = from; ; d = dirname(d)) {
140
+ const bin = join(d, "node_modules", ".bin");
141
+ if (existsSync(join(bin, "xanosdk")) || existsSync(join(bin, "xanosdk.cmd"))) return bin;
142
+ if (dirname(d) === d) return void 0;
143
+ }
144
+ }
145
+ function readManifest(dir) {
146
+ try {
147
+ return JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
148
+ } catch {
149
+ return void 0;
150
+ }
151
+ }
152
+ function isDir(path) {
153
+ try {
154
+ return statSync(path).isDirectory();
155
+ } catch {
156
+ return false;
157
+ }
158
+ }
159
+ function workspaceGlob(glob) {
160
+ const segs = glob.replace(/^\.\//, "").replace(/\/+$/, "").split("/");
161
+ const source = segs.map(
162
+ (seg, i) => seg === "**" ? i === segs.length - 1 ? ".*" : "(?:[^/]+/)*" : seg.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]") + (i === segs.length - 1 ? "" : "/")
163
+ ).join("");
164
+ return new RegExp(`^${source}$`);
165
+ }
166
+ function listsWorkspace(root, workspaces, member) {
167
+ const list = Array.isArray(workspaces) ? workspaces : workspaces?.packages;
168
+ if (!Array.isArray(list)) return false;
169
+ const rel = relative3(root, member).split(sep3).join("/");
170
+ const globs = list.filter((g) => typeof g === "string");
171
+ const hit = (g) => workspaceGlob(g).test(rel);
172
+ return globs.some((g) => !g.startsWith("!") && hit(g)) && !globs.some((g) => g.startsWith("!") && hit(g.slice(1)));
173
+ }
174
+ function npxBinDir(from) {
175
+ let prefix;
176
+ for (let d = from; prefix === void 0; d = dirname(d)) {
177
+ if (existsSync(join(d, "package.json")) || isDir(join(d, "node_modules"))) prefix = d;
178
+ else if (dirname(d) === d) break;
179
+ }
180
+ if (prefix === void 0) return binDirAbove(from);
181
+ const root = listingWorkspaceRoot(prefix);
182
+ if (root === void 0) return binDirAbove(prefix);
183
+ const name = readManifest(prefix)?.name;
184
+ return binDirAbove(join(root, "node_modules", typeof name === "string" && name !== "" ? name : basename(prefix)));
185
+ }
186
+ function listingWorkspaceRoot(prefix) {
187
+ for (let d = dirname(prefix); ; d = dirname(d)) {
188
+ if (existsSync(join(d, "package.json"))) {
189
+ const manifest = readManifest(d);
190
+ if (manifest?.workspaces !== void 0 && listsWorkspace(d, manifest.workspaces, prefix)) return d;
191
+ }
192
+ if (dirname(d) === d) return void 0;
193
+ }
194
+ }
195
+ function projectFileCli(dir, manager) {
196
+ if (manager === "npm" || manager === "yarn") return "npx xanosdk";
197
+ return listingWorkspaceRoot(resolve3(dir)) === void 0 ? "npx xanosdk" : "npx --workspaces=false xanosdk";
198
+ }
199
+ function spellProjectCli(text2, cli) {
200
+ return cli === void 0 || cli === "npx xanosdk" ? text2 : text2.replace(/\bnpx xanosdk(?=[\s`'")\]]|$)/g, cli);
201
+ }
202
+ var PROJECT_SDK_DIR = "node_modules/@xano/sdk";
203
+ function projectSdkDir(dir, manager) {
204
+ const project = resolve3(dir);
205
+ if (existsSync(join(project, PROJECT_SDK_DIR, "package.json"))) return PROJECT_SDK_DIR;
206
+ if (manager !== "npm" && manager !== "yarn") return PROJECT_SDK_DIR;
207
+ const root = listingWorkspaceRoot(project);
208
+ if (root === void 0) return PROJECT_SDK_DIR;
209
+ return `${relative3(project, root).split(sep3).join("/")}/${PROJECT_SDK_DIR}`;
210
+ }
211
+ function spellProjectSdkDir(text2, sdkDir) {
212
+ if (sdkDir === void 0 || sdkDir === PROJECT_SDK_DIR) return text2;
213
+ return text2.replace(/(?<![\w./-])node_modules\/@xano\/sdk(?=\/)/g, sdkDir);
214
+ }
215
+ function installedCliAt(dir) {
216
+ return sdkInstalledAt(dir) === "member-only" ? "npx --workspaces=false xanosdk" : "npx xanosdk";
217
+ }
218
+ function sameDir(a, b) {
219
+ try {
220
+ return realpathSync(a) === realpathSync(b);
221
+ } catch {
222
+ return false;
223
+ }
224
+ }
225
+ function sdkInstalledAt(dir) {
226
+ const start = resolve3(dir);
227
+ const cached = installedCache.get(start);
228
+ if (cached !== void 0) return cached;
229
+ const own = binDirAbove(start);
230
+ if (own === void 0) return false;
231
+ const npx = npxBinDir(start);
232
+ const found = npx !== void 0 && sameDir(npx, own) ? true : "member-only";
233
+ installedCache.set(start, found);
234
+ return found;
235
+ }
236
+ var state;
237
+ function setCliLauncher(launcher, typedDir, installedAt = sdkInstalledAt) {
238
+ state = launcher === "path" ? void 0 : { launcher, typedDir: typedDir ?? process.cwd(), installedAt };
239
+ }
240
+ function cliPrefixAt(dir, s = state) {
241
+ if (s === void 0) return "xanosdk";
242
+ const installed = s.installedAt(resolve3(s.typedDir, dir ?? "."));
243
+ return installed === true ? "npx xanosdk" : installed === "member-only" ? "npx --workspaces=false xanosdk" : "npx @xano/sdk";
244
+ }
245
+ var pattern;
246
+ function commandPattern() {
247
+ if (pattern !== void 0) return pattern;
248
+ const names = Object.keys(COMMANDS).sort((a, b) => b.length - a.length).map((n) => n.replace(/[-]/g, "\\-"));
249
+ pattern = new RegExp(
250
+ `(^|\\n|\`|&& |\\|\\| |\\| |; |\\$\\(|\\( ?|\\{ |(?<![\\w-])(?:do|then|else|!) |\\w: |\\x1b\\[[0-9;]*m)([ \\t]*(?:\\$ )?(?:env (?:(?:-u |--unset[= ])[A-Za-z_][A-Za-z0-9_]* )*)?(?:[A-Za-z_][A-Za-z0-9_]*=(?:'[^'\\n]*'|"[^"\\n]*"|[^\\s\`'"]*) )*)xanosdk (?=(?:${names.join("|")})\\b|--?[a-z]|<[a-z][a-z-]*>)`,
251
+ "g"
252
+ );
253
+ return pattern;
254
+ }
255
+ function cdTarget(text2, at) {
256
+ const from = Math.max(text2.lastIndexOf("`", at - 1), text2.lastIndexOf("\n", at - 1)) + 1;
257
+ const m = [...text2.slice(from, at).matchAll(/(?:^|\s)cd ('(?:[^']|'\\'')*'|"(?:[^"\\]|\\.)*"|[^\s`'"]+) && /g)].at(-1);
258
+ if (m === void 0) return void 0;
259
+ const word = m[1];
260
+ if (word.startsWith("'")) return word.slice(1, -1).replace(/'\\''/g, "'");
261
+ if (word.startsWith('"')) return word.slice(1, -1).replace(/\\(.)/g, "$1");
262
+ return word.startsWith("~/") ? join(homedir(), word.slice(2)) : word;
263
+ }
264
+ function withCliPrefix(text2, s = state) {
265
+ if (s === void 0 || !text2.includes("xanosdk ")) return text2;
266
+ return text2.replace(commandPattern(), (_whole, boundary, indent, offset) => {
267
+ const dir = boundary === "`" || boundary === "\n" ? void 0 : cdTarget(text2, offset + boundary.length);
268
+ return `${boundary}${indent}${cliPrefixAt(dir, s)} `;
269
+ });
270
+ }
271
+ function withCliPrefixDeep(value, s = state) {
272
+ if (s === void 0) return value;
273
+ const walk = (v) => {
274
+ if (typeof v === "string") return withCliPrefix(v, s);
275
+ if (Array.isArray(v)) return v.map(walk);
276
+ if (v !== null && typeof v === "object") {
277
+ const out = {};
278
+ for (const [k, inner] of Object.entries(v)) out[k] = walk(inner);
279
+ return out;
280
+ }
281
+ return v;
282
+ };
283
+ return walk(value);
284
+ }
285
+ function installCliPrefix(binPath) {
286
+ const cwd = process.cwd();
287
+ const launcher = launcherFor({ binPath, cwd, env: process.env });
288
+ const typed = typedDirFor(cwd, process.env);
289
+ if (typed !== cwd) setTypedCwdBase(typed);
290
+ setCliLauncher(launcher, typed);
291
+ if (launcher === "path") return;
292
+ const wrap = (stream) => {
293
+ const write = stream.write;
294
+ stream.write = function(chunk, ...rest) {
295
+ const text2 = typeof chunk === "string" ? withCliPrefix(chunk) : chunk;
296
+ return write.call(stream, text2, ...rest);
297
+ };
298
+ };
299
+ wrap(process.stderr);
300
+ if (process.stdout.isTTY === true) wrap(process.stdout);
301
+ }
302
+
303
+ // src/emit/output.ts
304
+ function isMachineOutput(args) {
305
+ return args.json === true || process.stdout.isTTY !== true;
306
+ }
307
+ function jsonWarning(w) {
308
+ return { code: w.code, message: w.message, ...w.subject === void 0 ? {} : { subject: w.subject } };
309
+ }
310
+ function isJsonWarnings(value) {
311
+ return Array.isArray(value) && value.every(
312
+ (w) => typeof w === "object" && w !== null && typeof w.code === "string" && typeof w.message === "string"
313
+ );
314
+ }
315
+ function mergeJsonWarnings(own, extra) {
316
+ if (own !== void 0 && !isJsonWarnings(own)) return void 0;
317
+ const merged = [...own ?? []];
318
+ for (const w of extra) {
319
+ const at = merged.findIndex((m) => m.code === w.code && m.message === w.message);
320
+ if (at === -1) merged.push(jsonWarning(w));
321
+ else if (merged[at].subject === void 0 && w.subject !== void 0) merged[at] = jsonWarning(w);
322
+ }
323
+ return merged;
324
+ }
325
+ var runScope = new AsyncLocalStorage();
326
+ var unscoped = { written: false };
327
+ var currentState = () => runScope.getStore() ?? unscoped;
328
+ var thrownAfterDocument = /* @__PURE__ */ new WeakSet();
329
+ var liveRun;
330
+ var signalState = () => runScope.getStore() ?? liveRun ?? unscoped;
331
+ var runFinished = false;
332
+ function interruptedRunFinished() {
333
+ return runFinished && liveRun === void 0;
334
+ }
335
+ function documentText(value, state2) {
336
+ const document = withCliPrefixDeep(withRunWarnings(withBackendFields(value), state2.warnings ?? [], state2.accepted ?? []));
337
+ return JSON.stringify(document, (_key, v) => typeof v === "string" ? plainText(v) : v, 2) + "\n";
338
+ }
339
+ function writeJson(value) {
340
+ const state2 = currentState();
341
+ state2.written = true;
342
+ state2.writtenExitCode = documentExitCode(value);
343
+ process.stdout.write(documentText(value, state2));
344
+ }
345
+ function interruptDocumentText(value) {
346
+ return documentText(value, signalState());
347
+ }
348
+ function interruptedRunWroteDocument() {
349
+ return signalState().written;
350
+ }
351
+ function interruptedRunDocumentExitCode() {
352
+ const state2 = signalState();
353
+ return state2 !== unscoped && state2.written ? state2.writtenExitCode : void 0;
354
+ }
355
+ function documentExitCode(value) {
356
+ if (typeof value !== "object" || value === null || value.ok !== false) return 0;
357
+ const code = value.error?.exitCode;
358
+ return typeof code === "number" && Number.isInteger(code) ? code : 1;
359
+ }
360
+ function noteRunWarning(code, message, subject) {
361
+ const state2 = runScope.getStore();
362
+ if (state2 === void 0) return;
363
+ state2.warnings = mergeJsonWarnings(state2.warnings, [{ code, message, subject }]);
364
+ }
365
+ function runWarnings() {
366
+ return runScope.getStore()?.warnings ?? [];
367
+ }
368
+ function noteRunAccepted(accepted) {
369
+ const state2 = runScope.getStore();
370
+ if (state2 === void 0 || accepted.length === 0) return;
371
+ state2.accepted = mergeJsonWarnings(state2.accepted, accepted);
372
+ }
373
+ function runAccepted() {
374
+ return runScope.getStore()?.accepted ?? [];
375
+ }
376
+ function setRunFailureExplainer(explain) {
377
+ const state2 = runScope.getStore();
378
+ if (state2 !== void 0) state2.explain = explain;
379
+ }
380
+ async function explainRunFailure(err) {
381
+ const explain = runScope.getStore()?.explain;
382
+ return explain === void 0 ? err : explain(err);
383
+ }
384
+ function withRunWarnings(value, warnings, accepted) {
385
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return value;
386
+ let out = value;
387
+ for (const [key, extra] of [["warnings", warnings], ["accepted", accepted]]) {
388
+ if (extra.length === 0) continue;
389
+ const merged = mergeJsonWarnings(value[key], extra);
390
+ if (merged !== void 0) out = { ...out, [key]: merged };
391
+ }
392
+ return out;
393
+ }
394
+ async function inJsonDocumentScope(fn) {
395
+ const state2 = { written: false };
396
+ const outer = liveRun;
397
+ liveRun = state2;
398
+ runFinished = false;
399
+ try {
400
+ return await runScope.run(state2, fn);
401
+ } catch (err) {
402
+ if (state2.written && typeof err === "object" && err !== null) thrownAfterDocument.add(err);
403
+ throw err;
404
+ } finally {
405
+ liveRun = outer;
406
+ if (outer === void 0) runFinished = true;
407
+ }
408
+ }
409
+ function jsonDocumentWritten(failure) {
410
+ if (typeof failure === "object" && failure !== null && thrownAfterDocument.has(failure)) return true;
411
+ return currentState().written;
412
+ }
413
+ function installStdoutPipeGuard(stream = process.stdout) {
414
+ stream.on("error", (err) => {
415
+ if (err.code === "EPIPE" || err.code === "ERR_STREAM_DESTROYED") return;
416
+ throw err;
417
+ });
418
+ }
419
+
420
+ // src/emit/ui.ts
421
+ function resolveColor(isTTY) {
422
+ return process.env.FORCE_COLOR ? process.env.FORCE_COLOR !== "0" : !process.env.NO_COLOR && isTTY === true && !dumbTerminal();
423
+ }
424
+ function dumbTerminal() {
425
+ return process.env.TERM === "dumb";
426
+ }
427
+ var MARK_OPEN = "\uE000";
428
+ var MARK_CLOSE = "\uE001";
429
+ var NONCE = Array.from(randomBytes(8), (b) => String.fromCharCode(57600 + b)).join("");
430
+ var mark = (code) => `${MARK_OPEN}${NONCE}${code}${MARK_CLOSE}`;
431
+ var TOKEN = `${MARK_OPEN}${NONCE}([0-9;]+)${MARK_CLOSE}`;
432
+ function makePalette(on) {
433
+ const paint = (code, s) => on ? `${mark(code)}${s}${mark("0")}` : s;
434
+ return {
435
+ bold: (s) => paint("1", s),
436
+ dim: (s) => paint("2", s),
437
+ green: (s) => paint("32", s),
438
+ red: (s) => paint("31", s),
439
+ yellow: (s) => paint("33", s),
440
+ cyan: (s) => paint("36", s)
441
+ };
442
+ }
443
+ var style = makePalette(resolveColor(process.stderr.isTTY));
444
+ function stderrStyle() {
445
+ return makePalette(resolveColor(process.stderr.isTTY));
446
+ }
447
+ function stdoutStyle() {
448
+ return makePalette(resolveColor(process.stdout.isTTY));
449
+ }
450
+ var SAFE_TEXT = new RegExp(`(${TOKEN})|[\\x00-\\x1f\\x7f-\\x9f\\u202a-\\u202e\\u2066-\\u2069\\ue000\\ue001]`, "g");
451
+ var TERMINAL_TEXT = new RegExp(`${TOKEN}|[\\x00-\\x08\\x0b-\\x1f\\x7f-\\x9f\\u202a-\\u202e\\u2066-\\u2069\\ue000\\ue001]`, "g");
452
+ var TOKENS = new RegExp(TOKEN, "g");
453
+ var NAMED_ESCAPES = { "\n": "\\n", "\r": "\\r", " ": "\\t" };
454
+ function visibleEscape(c) {
455
+ const named = NAMED_ESCAPES[c];
456
+ if (named !== void 0) return named;
457
+ const code = c.charCodeAt(0);
458
+ return code < 256 ? `\\x${code.toString(16).padStart(2, "0")}` : `\\u${code.toString(16).padStart(4, "0")}`;
459
+ }
460
+ function safeText(value) {
461
+ return value.replace(SAFE_TEXT, (match, token) => token ?? visibleEscape(match));
462
+ }
463
+ function quotedNames(names) {
464
+ return names.map((n) => `"${safeText(n)}"`).join(", ");
465
+ }
466
+ function withoutUrls(message) {
467
+ return message.replace(/\bhttps?:\/\/\S+?(?=[.,:;!?)\]'"]*(?:\s|$))/gi, "<url>");
468
+ }
469
+ function plainText(text2) {
470
+ return text2.replace(TOKENS, "");
471
+ }
472
+ function terminalText(text2) {
473
+ return text2.replace(
474
+ TERMINAL_TEXT,
475
+ (match, code) => code !== void 0 ? `\x1B[${code}m` : visibleEscape(match)
476
+ );
477
+ }
478
+ function printHuman(text2) {
479
+ process.stdout.write(terminalText(text2));
480
+ }
481
+ function formatTableListing(rows, indent = "") {
482
+ if (rows.length === 0) return "";
483
+ const idWidth = Math.max(...rows.map((r) => String(r.id).length));
484
+ const guidWidth = Math.max(...rows.map((r) => r.guid.length));
485
+ return rows.map(
486
+ (r) => `${indent}${String(r.id).padStart(idWidth)} ${r.guid.padEnd(guidWidth)} ${safeText(JSON.stringify(r.name))}`
487
+ ).join("\n");
488
+ }
489
+ function formatFields(rows) {
490
+ const s = stdoutStyle();
491
+ const width = Math.max(0, ...rows.map(([label]) => label.length));
492
+ return rows.map(([label, value]) => ` ${s.dim(safeText(label).padEnd(width))} ${safeText(value)}`).join("\n") + "\n";
493
+ }
494
+ function step(msg) {
495
+ process.stderr.write(terminalText(`${style.cyan("\u2192")} ${msg}
496
+ `));
497
+ }
498
+ function success(msg) {
499
+ process.stderr.write(terminalText(`${style.green("\u2713")} ${msg}
500
+ `));
501
+ }
502
+ function error(msg) {
503
+ process.stderr.write(terminalText(`${stderrStyle().red("\u2717")} ${msg}
504
+ `));
505
+ }
506
+ function continued(msg, pad) {
507
+ const [head, ...rest] = msg.split("\n");
508
+ if (rest.length === 0) return msg;
509
+ const text2 = rest.filter((line) => line.trim() !== "");
510
+ if (text2.length > 0 && text2.every((line) => /^\s/.test(line))) return msg;
511
+ return [head, ...rest.map((line) => line.trim() === "" ? "" : `${pad}${line}`)].join("\n");
512
+ }
513
+ function warn(msg, code, remedies = [], machine) {
514
+ process.stderr.write(terminalText(`${style.yellow("!")} ${continued(msg, " ")}
515
+ `));
516
+ for (const line of remedies) detail(line);
517
+ noteRunWarning(code, machine ?? [msg, ...remedies].join("\n"));
518
+ }
519
+ function info(msg) {
520
+ process.stderr.write(terminalText(`${style.cyan("i")} ${msg}
521
+ `));
522
+ }
523
+ function detail(msg) {
524
+ process.stderr.write(terminalText(` ${style.dim(continued(msg, " "))}
525
+ `));
526
+ }
527
+ function link(url) {
528
+ process.stderr.write(terminalText(` ${style.bold(style.cyan(url))}
529
+ `));
530
+ }
531
+ function blank() {
532
+ process.stderr.write("\n");
533
+ }
534
+ function formatDuration(ms) {
535
+ const safe = Math.max(0, ms);
536
+ if (safe < 1e3) return `${Math.round(safe)}ms`;
537
+ if (safe < 6e4) return `${(safe / 1e3).toFixed(1)}s`;
538
+ const minutes = Math.floor(safe / 6e4);
539
+ const seconds = Math.round(safe % 6e4 / 1e3);
540
+ return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
541
+ }
542
+ function elapsedSuffix(startedAt, now = Date.now()) {
543
+ return ` ${style.dim(`(${formatDuration(now - startedAt)})`)}`;
544
+ }
545
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
546
+ var SPINNER_FRAME_MS = 80;
547
+ function spinner(msg) {
548
+ let text2 = msg;
549
+ if (process.stderr.isTTY !== true || dumbTerminal()) {
550
+ detail(msg);
551
+ return { update: () => {
552
+ }, stop: () => {
553
+ } };
554
+ }
555
+ const start = Date.now();
556
+ let frame = 0;
557
+ let live = true;
558
+ const clear = () => process.stderr.write("\r\x1B[2K");
559
+ const render = () => {
560
+ const secs = Math.round((Date.now() - start) / 1e3);
561
+ const suffix = secs >= 1 ? ` ${style.dim(`(${secs}s)`)}` : "";
562
+ clear();
563
+ process.stderr.write(terminalText(`${style.cyan(SPINNER_FRAMES[frame % SPINNER_FRAMES.length])} ${style.dim(text2)}${suffix}`));
564
+ frame += 1;
565
+ };
566
+ render();
567
+ const timer = setInterval(render, SPINNER_FRAME_MS);
568
+ timer.unref();
569
+ const self = {
570
+ update(next) {
571
+ text2 = next;
572
+ },
573
+ stop() {
574
+ if (!live) return;
575
+ live = false;
576
+ liveSpinners.delete(self);
577
+ clearInterval(timer);
578
+ clear();
579
+ }
580
+ };
581
+ liveSpinners.add(self);
582
+ return self;
583
+ }
584
+ var liveSpinners = /* @__PURE__ */ new Set();
585
+ function clearProgress() {
586
+ for (const spin of [...liveSpinners]) spin.stop();
587
+ }
588
+ async function withSpinner(msg, work) {
589
+ const spin = spinner(msg);
590
+ try {
591
+ return await work();
592
+ } finally {
593
+ spin.stop();
594
+ }
595
+ }
596
+ function formatExpiration(expiresAt) {
597
+ if (expiresAt === void 0 || expiresAt === null || expiresAt === "") return "\u2014";
598
+ const ms = typeof expiresAt === "number" ? expiresAt * 1e3 : Date.parse(String(expiresAt).replace(" ", "T"));
599
+ if (Number.isNaN(ms)) return String(expiresAt);
600
+ const diff = (ms - Date.now()) / 1e3;
601
+ if (diff <= 0) return "expired";
602
+ const hours = Math.floor(diff / 3600);
603
+ const minutes = Math.floor(diff % 3600 / 60);
604
+ return `in ${hours}h ${minutes}m`;
605
+ }
606
+ function isLocalEngine(target) {
607
+ return "kind" in target && target.kind === "local-engine";
608
+ }
609
+ function describeWriteTarget(target) {
610
+ if (isLocalEngine(target)) {
611
+ return `local engine \xB7 ${hostLabel(target.url)} \xB7 workspace ${target.workspaceId}`;
612
+ }
613
+ const where = `${hostLabel(target.base)} \xB7 workspace ${target.workspaceId}`;
614
+ return target.label === void 0 || target.label === "" ? where : `${target.label} \u2014 ${where}`;
615
+ }
616
+ function discloseWriteTarget(target) {
617
+ detail(`on ${describeWriteTarget(target)}`);
618
+ }
619
+ function credentialWriteTarget(binding) {
620
+ return { base: binding.instance, workspaceId: binding.workspaceId, kind: "workspace" };
621
+ }
622
+ function writeTargetPayload(target) {
623
+ if (isLocalEngine(target)) {
624
+ return { instance: target.url, workspaceId: target.workspaceId, kind: "local-engine", local: true };
625
+ }
626
+ return {
627
+ instance: target.base,
628
+ workspaceId: target.workspaceId,
629
+ ...target.label === void 0 || target.label === "" ? {} : { label: target.label },
630
+ ...target.kind === void 0 ? {} : { kind: target.kind }
631
+ };
632
+ }
633
+ function backendDestinationPayload(parent, backend) {
634
+ return {
635
+ ...writeTargetPayload({
636
+ base: parent.instance.replace(/\/$/, ""),
637
+ workspaceId: parent.workspaceId,
638
+ label: backend.name,
639
+ kind: backend.kind
640
+ }),
641
+ url: backend.url,
642
+ ...backend.display === void 0 || backend.display === "" ? {} : { display: backend.display }
643
+ };
644
+ }
645
+ function hostLabel(origin) {
646
+ try {
647
+ return new URL(origin).host;
648
+ } catch {
649
+ return origin.replace(/^https?:\/\//, "").replace(/\/+$/, "");
650
+ }
651
+ }
652
+
653
+ // src/emit/operation-registry.ts
654
+ var EXIT_OUTCOME_UNKNOWN = 9;
655
+ var active;
656
+ function registerOperation(input) {
657
+ if (active !== void 0) {
658
+ throw new Error("An operation is already registered for this run; clear it before registering another.");
659
+ }
660
+ let writeSent = false;
661
+ const registration = {
662
+ ...input,
663
+ get writeSent() {
664
+ return writeSent;
665
+ },
666
+ markWriteSent() {
667
+ writeSent = true;
668
+ },
669
+ clear() {
670
+ if (active === registration) active = void 0;
671
+ }
672
+ };
673
+ active = registration;
674
+ return registration;
675
+ }
676
+ function activeOperation() {
677
+ return active;
678
+ }
679
+
680
+ // src/emit/help.ts
681
+ function table(rows, s, indent = " ", fixedWidth) {
682
+ const width = fixedWidth ?? Math.max(0, ...rows.map(([name]) => name.length));
683
+ return rows.map(([name, desc]) => `${indent}${s.cyan(name.padEnd(width))} ${s.dim(desc)}`);
684
+ }
685
+ function renderFlagSpec(ref) {
686
+ const spec = flagSpec(ref);
687
+ const values = flagValues(ref);
688
+ if (values === void 0 || typeof ref === "string" || ref.values === void 0) return spec;
689
+ return spec.replace(/<[^>]*>/, `<${values.join("|")}>`);
690
+ }
691
+ function flagSection(flags, s) {
692
+ if (!flags || flags.length === 0) return [];
693
+ const rows = flags.filter((ref) => Object.hasOwn(FLAGS, flagKey(ref))).map((ref) => [renderFlagSpec(ref), flagSummary(ref)]);
694
+ if (rows.length === 0) return [];
695
+ return ["", s.bold("Flags"), ...table(rows, s)];
696
+ }
697
+ function argSection(args, s) {
698
+ const rows = (args ?? []).flatMap((a) => {
699
+ if (a.selector !== void 0) {
700
+ return [[`<${a.name}>`, `${sourceSpellings(a.selector.accepted)}${OMITTED[a.selector.default]}`]];
701
+ }
702
+ return a.values !== void 0 && a.values.length > 0 ? [[`<${a.name}>`, a.values.join(", ")]] : [];
703
+ });
704
+ return rows.length === 0 ? [] : ["", s.bold("Arguments"), ...table(rows, s)];
705
+ }
706
+ var OMITTED = {
707
+ tracked: " (omitted: the backend this project last deployed to)",
708
+ entry: " (omitted: this project's entry file, compiled)",
709
+ none: ""
710
+ };
711
+ function exampleSection(example, s) {
712
+ return example ? ["", s.bold("Example"), ` ${s.dim(example)}`] : [];
713
+ }
714
+ function globalFlagRows() {
715
+ return GLOBAL_FLAGS.map((key) => [FLAGS[key].spec, FLAGS[key].summary]);
716
+ }
717
+ function globalFlagsLine(s, command, sub) {
718
+ const specs = GLOBAL_FLAGS.filter(
719
+ (key) => key !== "help" && key !== "version" && // A command that reaches no instance REFUSES `--profile` (see parseArgs).
720
+ (key !== "profile" || takesProfileFlag(command, sub)) && // `--no-refresh` turns off the AGENTS.md refresh a WORKSPACE compile does,
721
+ // so only a page for a command that runs one lists it — the commands that
722
+ // take the compile's env flags. `compile` and `routes` never refresh.
723
+ (key !== "no-refresh" || flagRefFor(command, sub, "backend-env-file") !== void 0) && // `completion` prints a script to source and refuses `--json`, so its
724
+ // page must not offer it.
725
+ (key !== "json" || command !== "completion")
726
+ ).map((key) => FLAGS[key].spec);
727
+ if (specs.length === 0) return [];
728
+ return ["", s.dim(`Also takes the global flags ${specs.join(" \xB7 ")} \u2014 see \`xanosdk --help\`.`)];
729
+ }
730
+ function renderGlobalHelp(s = stdoutStyle(), version = "") {
731
+ const byGroup = /* @__PURE__ */ new Map();
732
+ const push = (group, row) => {
733
+ const rows = byGroup.get(group) ?? [];
734
+ rows.push(row);
735
+ byGroup.set(group, rows);
736
+ };
737
+ for (const [name, spec] of Object.entries(COMMANDS)) {
738
+ if (spec.aliasOf === void 0) push(spec.group, [spec.display, spec.summary]);
739
+ for (const sub of Object.values(spec.subcommands ?? {})) {
740
+ if (sub.group === void 0) continue;
741
+ push(sub.group, [sub.display ?? `${name} ${sub.summary}`, sub.groupSummary ?? sub.summary]);
742
+ }
743
+ }
744
+ const width = Math.max(0, ...[...byGroup.values()].flat().map(([n]) => n.length));
745
+ const lines = [
746
+ `${s.bold("xanosdk")}${version ? ` ${s.dim(`v${version}`)}` : ""} \u2014 the AI-first SDK & CLI for Xano backends`,
747
+ "",
748
+ `${s.dim("Usage:")} xanosdk ${s.cyan("<command>")} ${s.dim("[options]")}`
749
+ ];
750
+ for (const group of HELP_GROUP_ORDER) {
751
+ const rows = byGroup.get(group);
752
+ if (!rows || rows.length === 0) continue;
753
+ lines.push("", s.bold(group), ...table(rows, s, " ", width));
754
+ }
755
+ lines.push("", s.bold("Global flags"), ...table(globalFlagRows(), s, " ", width));
756
+ lines.push(
757
+ "",
758
+ s.dim("Run `xanosdk <command> --help` for a command's arguments and flags."),
759
+ s.dim("Docs: https://www.npmjs.com/package/@xano/sdk")
760
+ );
761
+ return lines.join("\n") + "\n";
762
+ }
763
+ function renderCommandHelp(command, s = stdoutStyle()) {
764
+ const spec = getCommand(command);
765
+ if (!spec) return renderGlobalHelp(s);
766
+ const subs = liveSubcommandNames(command);
767
+ const usage = subs.length > 0 ? `xanosdk ${command} <subcommand> ${s.dim("[options]")}` : `xanosdk ${command}${renderArgs(spec.args) ? ` ${renderArgs(spec.args)}` : ""} ${s.dim("[options]")}`;
768
+ const lines = [`${s.bold(`xanosdk ${command}`)} \u2014 ${spec.summary}`, "", `${s.dim("Usage:")} ${usage}`];
769
+ if (subs.length > 0) {
770
+ const rows = subs.map((name) => {
771
+ const sub = getSubcommand(command, name);
772
+ const args = renderArgs(sub.args);
773
+ return [args ? `${name} ${args}` : name, sub.summary];
774
+ });
775
+ lines.push("", s.bold("Subcommands"), ...table(rows, s));
776
+ }
777
+ lines.push(...argSection(spec.args, s));
778
+ lines.push(...flagSection(visibleFlags(spec), s));
779
+ if (spec.notes !== void 0) lines.push("", s.bold("Notes"), ` ${spec.notes}`);
780
+ lines.push(...exampleSection(spec.example, s));
781
+ lines.push(...globalFlagsLine(s, command));
782
+ if (subs.length > 0) {
783
+ lines.push("", s.dim(`Run \`xanosdk ${command} <subcommand> --help\` for a subcommand's flags.`));
784
+ }
785
+ return lines.join("\n") + "\n";
786
+ }
787
+ function renderSubcommandHelp(command, sub, s = stdoutStyle()) {
788
+ const spec = getSubcommand(command, sub);
789
+ if (!spec) return renderCommandHelp(command, s);
790
+ const args = renderArgs(spec.args);
791
+ const lines = [
792
+ `${s.bold(`xanosdk ${command} ${sub}`)} \u2014 ${spec.summary}`,
793
+ "",
794
+ `${s.dim("Usage:")} xanosdk ${command} ${sub}${args ? ` ${args}` : ""} ${s.dim("[options]")}`
795
+ ];
796
+ lines.push(...argSection(spec.args, s));
797
+ lines.push(...flagSection(visibleFlags(spec), s));
798
+ lines.push(...exampleSection(spec.example, s));
799
+ lines.push(...globalFlagsLine(s, command, sub));
800
+ return lines.join("\n") + "\n";
801
+ }
802
+ function renderHelpFor(target, s, version = "") {
803
+ if (target?.command === void 0) return renderGlobalHelp(s, version);
804
+ if (target.subcommand !== void 0) return renderSubcommandHelp(target.command, target.subcommand, s);
805
+ return renderCommandHelp(target.command, s);
806
+ }
807
+ function indentBlock(text2, indent = " ") {
808
+ return text2.split("\n").map((line) => line === "" ? line : indent + line).join("\n");
809
+ }
810
+
811
+ // src/emit/errors.ts
812
+ function statesOutcomeUnknown(message) {
813
+ return /\bmay or may not have (taken effect|landed|published|been \w+)/.test(message);
814
+ }
815
+ var UsageError = class extends Error {
816
+ name = "UsageError";
817
+ /** The help block to print under the message. */
818
+ helpFor;
819
+ /**
820
+ * A one-line pointer to this help page, in place of the block. For a conflict
821
+ * between flags that each parsed fine: the message already names which to
822
+ * drop, and a full usage block under it buries that sentence. {@link helpFor}
823
+ * is for a mistake in the command's SHAPE, where the block lists what works.
824
+ */
825
+ hintFor;
826
+ /** A closest-match hint (`Did you mean: details`), when one is close enough. */
827
+ suggestion;
828
+ constructor(message, opts = {}) {
829
+ super(message);
830
+ this.helpFor = opts.helpFor;
831
+ this.hintFor = opts.hintFor;
832
+ this.suggestion = opts.suggestion;
833
+ }
834
+ };
835
+ var LocalFileNotFoundError = class extends UsageError {
836
+ exitCode = 1;
837
+ };
838
+ var CliError = class extends Error {
839
+ constructor(code, message, opts = {}) {
840
+ super(message, opts.cause === void 0 ? void 0 : { cause: opts.cause });
841
+ this.code = code;
842
+ this.details = opts.details;
843
+ this.exitCode = opts.exitCode;
844
+ }
845
+ code;
846
+ name = "CliError";
847
+ details;
848
+ exitCode;
849
+ };
850
+ function isUsageError(err) {
851
+ return err instanceof UsageError || err instanceof Error && err.name === "UsageError";
852
+ }
853
+ function unknownCommand(name, opts = {}) {
854
+ if (name.startsWith("-") && name !== "-") {
855
+ const flag = flagName(name);
856
+ const hint = suggestFlag(flag, void 0);
857
+ return new UsageError(
858
+ `Unknown flag ${flag} before the command. Global flags go after it: \`xanosdk <command> ${hint ?? "<flag>"}${hint === "-p" || hint === "--profile" ? " <profile>" : ""}\`.`,
859
+ { helpFor: {}, suggestion: hint }
860
+ );
861
+ }
862
+ const owned = verbOwnerHint(name, opts.help === true);
863
+ if (owned !== void 0) {
864
+ return new UsageError(`Unknown command "${name}". ${owned.hint}`, {
865
+ helpFor: { command: owned.command }
866
+ });
867
+ }
868
+ return new UsageError(`Unknown command "${name}".`, {
869
+ helpFor: {},
870
+ suggestion: suggestVerb(name, liveCommandNames())
871
+ });
872
+ }
873
+ function verbOwnerHint(name, help) {
874
+ const owners = liveCommandNames().filter(
875
+ (c) => liveSubcommandNames(c).includes(name)
876
+ );
877
+ if (owners.length === 0) return void 0;
878
+ const paths = owners.map((c) => `\`xanosdk ${help ? "help " : ""}${c} ${name}\``).join(" or ");
879
+ const nouns = owners.map((c) => `\`${c}\``).join(" and ");
880
+ return {
881
+ command: owners[0],
882
+ hint: `\`${name}\` is a subcommand of ${nouns}: ${paths}.`
883
+ };
884
+ }
885
+ function unknownHelpTopic(name) {
886
+ const owned = verbOwnerHint(name, true);
887
+ if (owned !== void 0) {
888
+ return new UsageError(
889
+ `\`xanosdk help\`: no help topic "${name}". ${owned.hint}`,
890
+ {
891
+ helpFor: { command: owned.command }
892
+ }
893
+ );
894
+ }
895
+ return new UsageError(`\`xanosdk help\`: no help topic "${name}".`, {
896
+ helpFor: {},
897
+ suggestion: suggest(name, liveCommandNames())
898
+ });
899
+ }
900
+ function unknownSubcommand(command, sub, positionals = []) {
901
+ const moved = movedVerb(command, sub, positionals);
902
+ if (moved !== void 0) return moved;
903
+ const missing = sub === void 0 || sub === "" || sub.startsWith("-");
904
+ const what = missing ? "no subcommand given" : `unknown subcommand "${sub}"`;
905
+ const verbs = liveSubcommandNames(command);
906
+ return new UsageError(`\`xanosdk ${command}\`: ${what}.`, {
907
+ helpFor: { command },
908
+ suggestion: !missing ? suggestVerb(sub, verbs) : void 0
909
+ });
910
+ }
911
+ function suggestVerb(typed, verbs) {
912
+ const synonym = VERB_SYNONYMS[typed]?.find((v) => verbs.includes(v));
913
+ if (synonym !== void 0) return synonym;
914
+ const spelled = suggest(typed, verbs);
915
+ if (spelled === void 0 || negates(typed, spelled)) return void 0;
916
+ const meant = Object.hasOwn(VERB_INTENT, typed) ? typed : suggest(typed, Object.keys(VERB_INTENT));
917
+ const want = meant === void 0 ? void 0 : VERB_INTENT[meant];
918
+ const got = Object.hasOwn(VERB_INTENT, spelled) ? VERB_INTENT[spelled] : void 0;
919
+ return want !== void 0 && got !== void 0 && want !== got ? void 0 : spelled;
920
+ }
921
+ function negates(a, b) {
922
+ const stem = (w, p) => w.startsWith(p) ? w.slice(p.length).replace(/^-/, "") : void 0;
923
+ return ["un", "de"].some((p) => stem(a, p) === b || stem(b, p) === a);
924
+ }
925
+ var VERB_INTENT = {
926
+ list: "read",
927
+ ls: "read",
928
+ show: "read",
929
+ get: "read",
930
+ details: "read",
931
+ view: "read",
932
+ info: "read",
933
+ describe: "read",
934
+ search: "read",
935
+ cat: "read",
936
+ pull: "fetch",
937
+ fetch: "fetch",
938
+ download: "fetch",
939
+ export: "fetch",
940
+ push: "send",
941
+ upload: "send",
942
+ put: "send",
943
+ set: "send",
944
+ unset: "send",
945
+ delete: "send",
946
+ remove: "send",
947
+ rm: "send",
948
+ install: "send",
949
+ reinstall: "send",
950
+ create: "send",
951
+ add: "send",
952
+ prune: "send",
953
+ rename: "send",
954
+ deploy: "send",
955
+ "set-live": "send",
956
+ "set-default": "send",
957
+ use: "send"
958
+ };
959
+ var VERB_SYNONYMS = {
960
+ remove: ["delete", "unset", "prune"],
961
+ rm: ["delete", "remove", "unset", "prune"],
962
+ del: ["delete", "remove", "unset"],
963
+ delete: ["remove", "unset"],
964
+ destroy: ["delete", "remove"],
965
+ uninstall: ["remove", "delete"],
966
+ un: ["remove", "delete"],
967
+ unset: ["delete", "remove"],
968
+ mv: ["rename"],
969
+ move: ["rename"],
970
+ switch: ["use", "set-live"],
971
+ promote: ["set-live"],
972
+ activate: ["set-live", "use"],
973
+ default: ["set-default"],
974
+ select: ["use"],
975
+ ls: ["list"],
976
+ new: ["create", "add"],
977
+ add: ["create", "install"],
978
+ create: ["add"],
979
+ info: ["show", "get", "details"],
980
+ view: ["show", "get", "details"],
981
+ describe: ["show", "get", "details"],
982
+ get: ["show", "details"],
983
+ show: ["get", "details"]
984
+ };
985
+ function unknownFlag(flags, target, alsoKnown = []) {
986
+ const names = [...new Set(flags.map(flagName))];
987
+ const known = (name) => suggestFlag(name, target, alsoKnown) === name || scopedFlagNames(target).some((n) => shortSpellings(n).includes(name));
988
+ const valued = names.filter((n) => known(n) && flags.some((f) => f !== n && flagName(f) === n));
989
+ const unknown = names.filter((n) => !valued.includes(n));
990
+ const noValue = valued.length === 0 ? "" : `${valued.map((n) => `\`${n}\``).join(", ")} ${valued.length === 1 ? "takes" : "take"} no value \u2014 drop the \`=\` and what follows it.`;
991
+ const [first, ...rest] = unknown;
992
+ if (first === void 0) return new UsageError(noValue, { helpFor: target });
993
+ const tokenNote = target?.command === "profile" && target.subcommand === "add" && unknown.includes("--token") ? ` The token is read from stdin: \`printf %s "$TOKEN" | xanosdk profile add <name>\`.` : "";
994
+ return new UsageError(
995
+ `Unknown flag ${first}${rest.length ? ` (also ${rest.join(", ")})` : ""}.${noValue === "" ? "" : ` ${noValue}`}${tokenNote}`,
996
+ {
997
+ helpFor: target,
998
+ suggestion: suggestFlag(first, target, alsoKnown)
999
+ }
1000
+ );
1001
+ }
1002
+ function shortSpellings(key) {
1003
+ const spec = FLAGS[key]?.spec ?? "";
1004
+ return spec.split(/[\s,=[]+/).filter((t) => /^-[A-Za-z]$/.test(t));
1005
+ }
1006
+ function flagName(token) {
1007
+ const eq = token.indexOf("=");
1008
+ return eq < 0 ? token : token.slice(0, eq);
1009
+ }
1010
+ function suggestFlag(flag, target, alsoKnown = []) {
1011
+ const names = [...scopedFlagNames(target), ...alsoKnown];
1012
+ const short = /^-([A-Za-z])$/.exec(flagName(flag))?.[1];
1013
+ if (short !== void 0) {
1014
+ const shorts = names.flatMap((n) => shortSpellings(n));
1015
+ const other = short === short.toLowerCase() ? short.toUpperCase() : short.toLowerCase();
1016
+ if (shorts.includes(`-${other}`)) return `-${other}`;
1017
+ }
1018
+ const typed = flagName(flag).replace(/^-+/, "");
1019
+ const match = suggest(typed, names);
1020
+ return match === void 0 ? void 0 : `--${match}`;
1021
+ }
1022
+ function scopedFlagNames(target) {
1023
+ const command = target?.command;
1024
+ const spec = command === void 0 ? void 0 : getCommand(command);
1025
+ const own = spec === void 0 ? [] : target?.subcommand !== void 0 ? [getSubcommand(command, target.subcommand)] : spec.subcommands !== void 0 ? Object.values(spec.subcommands) : [spec];
1026
+ const declared = own.flatMap((s) => s === void 0 ? [] : (visibleFlags(s) ?? []).map(flagKey));
1027
+ const globals = GLOBAL_FLAGS.filter(
1028
+ (f) => f !== "profile" || command === void 0 || takesProfileFlag(command, target?.subcommand)
1029
+ );
1030
+ return [.../* @__PURE__ */ new Set([...globals, ...declared])];
1031
+ }
1032
+ function extraArguments(extras, target, max, attachedValueFlag) {
1033
+ const where = target.subcommand ? `${target.command} ${target.subcommand}` : target.command;
1034
+ const named = extras.map((e) => `"${e.includes("=") ? `${flagName(e)}=\u2026` : e}"`).join(", ");
1035
+ const noun = extras.length === 1 ? "argument" : "arguments";
1036
+ const selector = max === 0 && extras.length === 1 ? positionalSelectorHint(extras[0], target) : void 0;
1037
+ const why = selector !== void 0 ? `\`xanosdk ${where}\` takes no positional arguments; it names its backend with \`${selector.flag}\`: \`${selector.flag} ${extras[0]}\`.` : attachedValueFlag !== void 0 ? (
1038
+ // `--lock` is the only flag with an attached-only value form, and its
1039
+ // value is a path — spelled out here rather than reconstructed from the
1040
+ // flag registry, whose `spec` strings are written for help, not reuse.
1041
+ `\`${attachedValueFlag}\` takes its value attached: \`${attachedValueFlag}=<path>\`.`
1042
+ ) : specFor(target)?.extraArgHint ?? (max === 0 ? `\`xanosdk ${where}\` takes no positional arguments.` : `\`xanosdk ${where}\` takes at most ${max}: ${renderArgs(specFor(target)?.args)}.`);
1043
+ return new UsageError(
1044
+ `\`xanosdk ${where}\`: unexpected ${noun} ${named} \u2014 ${why}`,
1045
+ {
1046
+ helpFor: target,
1047
+ ...selector === void 0 ? {} : { suggestion: selector.flag }
1048
+ }
1049
+ );
1050
+ }
1051
+ var BACKEND_HANDLE = /^(?:workspace|ephemeral|local-engine|tenant)(?::[^\s=]+)?$/;
1052
+ function positionalSelectorHint(extra, target) {
1053
+ if (!BACKEND_HANDLE.test(extra)) return void 0;
1054
+ const own = selectorSpellings(target.command, target.subcommand);
1055
+ return own.length === 1 && /^`--/.test(own[0]) ? { flag: own[0].slice(1, -1) } : void 0;
1056
+ }
1057
+ function envSetArgumentsRefused(problem, flags = []) {
1058
+ const target = { command: "env", subcommand: "set" };
1059
+ const suggestion = flags.filter((f) => f.startsWith("--")).map((f) => suggestFlag(f, target)).find((m) => m !== void 0);
1060
+ const what = problem === "flag" ? "an argument starting with `-` is not a flag it knows" : "it takes at most NAME and VALUE, and got more";
1061
+ return new UsageError(
1062
+ `\`xanosdk env set\`: ${what}. It is not repeated here in case it is the value. A value that starts with \`-\` or holds spaces is safest piped on stdin: \`printf %s "$VALUE" | xanosdk env set NAME\`.`,
1063
+ { helpFor: target, suggestion }
1064
+ );
1065
+ }
1066
+ function specFor(target) {
1067
+ return target.subcommand !== void 0 ? getSubcommand(target.command, target.subcommand) : getCommand(target.command);
1068
+ }
1069
+ function missingArgument(arg, target) {
1070
+ const where = target.subcommand ? `${target.command} ${target.subcommand}` : target.command;
1071
+ return new UsageError(`\`xanosdk ${where}\`: missing required <${arg}>.`, {
1072
+ helpFor: target
1073
+ });
1074
+ }
1075
+ function reportFailure(err, version = "", argv = []) {
1076
+ const s = stderrStyle();
1077
+ const message = (err instanceof Error ? err.message : String(err)).replace(
1078
+ /^xanosdk: /,
1079
+ ""
1080
+ );
1081
+ if (failureWritesDocument(argv, err) && !jsonDocumentWritten(err))
1082
+ writeJson(failureDocument(err, message));
1083
+ error(indentContinuation(message));
1084
+ if (!isUsageError(err)) return;
1085
+ const many = err.suggestions;
1086
+ const near = (Array.isArray(many) && many.length > 1 && many.every((n) => typeof n === "string") ? many : err.suggestion === void 0 ? [] : [err.suggestion]).filter((n) => !namesSuggestion(message, n));
1087
+ if (near.length > 0) {
1088
+ process.stderr.write("\n");
1089
+ detail(`Did you mean: ${near.map((n) => s.cyan(n)).join(" or ")}`);
1090
+ }
1091
+ if (err.hintFor?.command !== void 0) {
1092
+ const path = [err.hintFor.command, err.hintFor.subcommand].filter((p) => p !== void 0).join(" ");
1093
+ process.stderr.write("\n");
1094
+ detail(`Run \`xanosdk ${path} --help\` for its usage and flags.`);
1095
+ }
1096
+ if (err.helpFor === void 0) return;
1097
+ process.stderr.write(terminalText("\n" + indentBlock(renderHelpFor(err.helpFor, s, version))));
1098
+ }
1099
+ function failureWritesDocument(argv, err) {
1100
+ const json = argv.includes("--json");
1101
+ return json || isMachineOutput({ json }) && !stdoutCarriesData(argv, err);
1102
+ }
1103
+ function namesSuggestion(message, suggestion) {
1104
+ return message.includes(`"${suggestion}"`) || message.includes(`\`${suggestion}\``);
1105
+ }
1106
+ var DATA_STDOUT_COMMANDS = /* @__PURE__ */ new Set([
1107
+ "export",
1108
+ "llms",
1109
+ "completion",
1110
+ "version",
1111
+ "help"
1112
+ ]);
1113
+ var VALUE_FLAGS = /* @__PURE__ */ new Set(["--profile", "-p", "--config", "--origin"]);
1114
+ function stdoutCarriesData(argv, err) {
1115
+ if ((argv.includes("--help") || argv.includes("-h")) && !isUsageError(err)) return true;
1116
+ if (argv.includes("--path=-") || argv.some((a, i) => a === "--path" && argv[i + 1] === "-"))
1117
+ return true;
1118
+ const command = argv.find(
1119
+ (a, i) => !a.startsWith("-") && !VALUE_FLAGS.has(argv[i - 1] ?? "")
1120
+ );
1121
+ if (command === "export")
1122
+ return !writesToFile(argv) && !argv.includes("--check");
1123
+ return command === void 0 || DATA_STDOUT_COMMANDS.has(command);
1124
+ }
1125
+ function writesToFile(argv) {
1126
+ for (let i = 0; i < argv.length; i++) {
1127
+ const a = argv[i];
1128
+ const value = a === "--out" || a === "-o" ? argv[i + 1] : a.startsWith("--out=") ? a.slice("--out=".length) : void 0;
1129
+ if (value !== void 0 && value !== "" && value !== "-") return true;
1130
+ }
1131
+ return false;
1132
+ }
1133
+ function indentContinuation(message) {
1134
+ const [head, ...rest] = message.split("\n");
1135
+ if (rest.length === 0) return message;
1136
+ const text2 = rest.filter((line) => line.trim() !== "");
1137
+ if (text2.length > 0 && text2.every((line) => /^\s/.test(line))) return message;
1138
+ return [
1139
+ head,
1140
+ ...rest.map((line) => line.trim() === "" ? "" : ` ${line}`)
1141
+ ].join("\n");
1142
+ }
1143
+ function failureDocument(err, message) {
1144
+ return { ok: false, error: failureError(err, message, processExitCode(err)) };
1145
+ }
1146
+ function failureError(err, message, exitCode) {
1147
+ const details = ownCode(err)?.details;
1148
+ const own = err?.suggestion;
1149
+ const suggestion = isUsageError(err) ? err.suggestion : typeof own === "string" ? own : void 0;
1150
+ const many = err?.suggestions;
1151
+ const suggestions = Array.isArray(many) && many.length > 1 && many.every((s) => typeof s === "string") ? many : void 0;
1152
+ return {
1153
+ code: failureCode(err),
1154
+ message,
1155
+ exitCode,
1156
+ ...details === void 0 ? {} : { details },
1157
+ ...suggestion === void 0 ? {} : { suggestion },
1158
+ ...suggestion === void 0 || suggestions === void 0 ? {} : { suggestions }
1159
+ };
1160
+ }
1161
+ function failureCode(err) {
1162
+ return ownCode(err)?.code ?? (isUsageError(err) ? "SDK_USAGE" : "SDK_ERROR");
1163
+ }
1164
+ function ownCode(err) {
1165
+ const { code, details } = err ?? {};
1166
+ return typeof code === "string" && code.startsWith("SDK_") ? { code, details } : void 0;
1167
+ }
1168
+ function exitCodeOf(err) {
1169
+ const code = err?.exitCode;
1170
+ return typeof code === "number" && Number.isInteger(code) && code > 0 && code < 256 ? code : 1;
1171
+ }
1172
+ function processExitCode(err) {
1173
+ const own = exitCodeOf(err);
1174
+ if (own !== 1 || err?.exitCode === 1)
1175
+ return own;
1176
+ return err instanceof Error && statesOutcomeUnknown(err.message) ? EXIT_OUTCOME_UNKNOWN : 1;
1177
+ }
1178
+ var MOVED_TO_TOP_LEVEL = /* @__PURE__ */ new Map([
1179
+ ["tables", /* @__PURE__ */ new Set(["workspace", "ephemeral", "tenant", "local-engine"])],
1180
+ ["impersonate", /* @__PURE__ */ new Set(["ephemeral", "tenant", "local-engine"])]
1181
+ ]);
1182
+ function movedVerb(command, sub, positionals) {
1183
+ if (command === void 0 || sub === void 0 || MOVED_TO_TOP_LEVEL.get(sub)?.has(command) !== true) {
1184
+ return void 0;
1185
+ }
1186
+ const name = positionals[0];
1187
+ const backend = command === "workspace" ? "workspace" : name !== void 0 && name !== "" ? `${command}:${name}` : command === "tenant" ? "tenant:<name>" : command;
1188
+ const replacement = sub === "tables" ? tablesCommand(backend) : `xanosdk ${sub} ${backend}`;
1189
+ return new UsageError(
1190
+ `\`xanosdk ${command} ${sub}\` is now \`${replacement}\`: \`${sub}\` is one top-level verb that takes the backend as its argument, and bare it follows what this project last deployed to.`,
1191
+ { helpFor: { command: sub } }
1192
+ );
1193
+ }
1194
+ function installCliDiagnosticSink() {
1195
+ setDiagnosticSink((diagnostic) => {
1196
+ warn(diagnostic.message, diagnostic.code);
1197
+ if (diagnostic.subject !== void 0) noteRunWarning(diagnostic.code, diagnostic.message, diagnostic.subject);
1198
+ });
1199
+ }
1200
+
1201
+ // src/emit/name-check.ts
1202
+ var CONTROL = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/u;
1203
+ var CONTROL_NAMES = {
1204
+ " ": "a tab",
1205
+ "\r": "a carriage return",
1206
+ "\n": "a line break",
1207
+ "\u2028": "a line break",
1208
+ "\u2029": "a line break"
1209
+ };
1210
+ var runContext = {};
1211
+ function setRunNameContext(ctx) {
1212
+ runContext = ctx ?? {};
1213
+ }
1214
+ function runNameContext() {
1215
+ return runContext;
1216
+ }
1217
+ function checkOneName(value, what, opts = {}) {
1218
+ const trimmed = value.trim();
1219
+ const bad = CONTROL.exec(trimmed);
1220
+ if (bad === null) return;
1221
+ const hint = opts.helpFor === void 0 ? {} : { hintFor: opts.helpFor };
1222
+ if (opts.echo === false) {
1223
+ throw new UsageError(
1224
+ `${capital(what)} holds ${describe(bad[0])}, and a name cannot (it is not repeated here). Nothing was sent.`,
1225
+ hint
1226
+ );
1227
+ }
1228
+ const lines = trimmed.split(/\r?\n|[\u2028\u2029]/u).map((l) => l.trim()).filter((l) => l !== "");
1229
+ if (lines.length > 1 && lines.every((l) => !CONTROL.test(l))) {
1230
+ const prefix = /^[a-z][a-z-]*:/.exec(lines[0])?.[0] ?? "";
1231
+ const names = lines.map((l) => prefix !== "" && l.startsWith(prefix) ? l.slice(prefix.length) : l);
1232
+ const shown = names.slice(0, 3).map((n) => `"${n}"`).join(", ") + (names.length > 3 ? ", \u2026" : "");
1233
+ const loop = opts.loop?.(value, prefix, names);
1234
+ throw new UsageError(
1235
+ `${opts.verb === void 0 ? "A command" : `\`${opts.verb}\``} takes one name per command, and ${what} holds ${names.length}, one per line (${shown}). Nothing was sent.` + (loop === void 0 ? " Run the command once for each name." : `
1236
+ Run it once for each name:
1237
+ ${loop}`),
1238
+ hint
1239
+ );
1240
+ }
1241
+ throw new UsageError(
1242
+ `${capital(what)} ${JSON.stringify(trimmed)} holds ${describe(bad[0])}, which no name carries. Nothing was sent.`,
1243
+ hint
1244
+ );
1245
+ }
1246
+ function describe(ch) {
1247
+ return `a control character (${CONTROL_NAMES[ch] ?? `U+${ch.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}`})`;
1248
+ }
1249
+ function capital(s) {
1250
+ return s.charAt(0).toUpperCase() + s.slice(1);
1251
+ }
1252
+
1253
+ // src/emit/source-selector.ts
1254
+ var CUT_KINDS = ["workspace", "ephemeral", "tenant"];
1255
+ var EXIT_SOURCE_UNRESOLVABLE = 8;
1256
+ var PREFIXED = {
1257
+ release: "required",
1258
+ tenant: "required",
1259
+ ephemeral: "optional",
1260
+ "local-engine": "optional"
1261
+ };
1262
+ var BARE = ["workspace", "ephemeral", "local-engine"];
1263
+ function isKindShaped(raw) {
1264
+ return /^[a-z][a-z-]*:/.test(raw);
1265
+ }
1266
+ function spellingsOf(kind) {
1267
+ switch (kind) {
1268
+ case "workspace":
1269
+ return ["workspace"];
1270
+ case "ephemeral":
1271
+ return ["ephemeral", "ephemeral:<name>"];
1272
+ case "local-engine":
1273
+ return ["local-engine", "local-engine:<name>"];
1274
+ case "release":
1275
+ return ["release:<name>"];
1276
+ case "tenant":
1277
+ return ["tenant:<name>"];
1278
+ case "file":
1279
+ return ["a path to a bundle .json"];
1280
+ }
1281
+ }
1282
+ function sourceSpellings(accepted) {
1283
+ const parts = accepted.flatMap(spellingsOf);
1284
+ if (parts.length <= 1) return parts.join("");
1285
+ return `${parts.slice(0, -1).join(", ")}, or ${parts[parts.length - 1]}`;
1286
+ }
1287
+ function refuse(raw, accepted, helpFor, because, noun = SOURCE_NOUN, suggestion) {
1288
+ return new UsageError(
1289
+ `"${raw}" ${because}. ${noun.plural} are ${sourceSpellings(accepted)}.`,
1290
+ { hintFor: helpFor, ...suggestion === void 0 ? {} : { suggestion } }
1291
+ );
1292
+ }
1293
+ function keywordSuggestion(raw, accepted) {
1294
+ const colon = raw.indexOf(":");
1295
+ if (colon > 0) {
1296
+ const kinds = accepted.filter((k) => (Object.hasOwn(PREFIXED, k) ? PREFIXED[k] : void 0) !== void 0);
1297
+ const kind = suggest(raw.slice(0, colon), kinds);
1298
+ return kind === void 0 ? void 0 : `${kind}${raw.slice(colon)}`;
1299
+ }
1300
+ return suggest(raw, accepted.filter((k) => BARE.includes(k)));
1301
+ }
1302
+ var SOURCE_NOUN = { singular: "source", plural: "Sources" };
1303
+ function parseSource(raw, accepted, helpFor, noun = SOURCE_NOUN) {
1304
+ checkOneName(raw, `the ${noun.singular}`, { helpFor, ...runNameContext() });
1305
+ if (isKindShaped(raw)) {
1306
+ const colon = raw.indexOf(":");
1307
+ const kind = raw.slice(0, colon);
1308
+ const name = raw.slice(colon + 1).trim();
1309
+ if ((Object.hasOwn(PREFIXED, kind) ? PREFIXED[kind] : void 0) === void 0) {
1310
+ throw BARE.includes(kind) ? refuse(raw, accepted, helpFor, `takes no name \u2014 ${kind} names one thing`, noun) : refuse(raw, accepted, helpFor, `names no ${noun.singular} kind "${kind}"`, noun, keywordSuggestion(raw, accepted));
1311
+ }
1312
+ if (!accepted.includes(kind)) {
1313
+ throw refuse(raw, accepted, helpFor, `names ${withArticle(kind.replace("-", " "))}, which this command does not take`, noun);
1314
+ }
1315
+ if (name === "") throw refuse(raw, accepted, helpFor, `names no ${kind}`, noun);
1316
+ return { kind, name };
1317
+ }
1318
+ if (BARE.includes(raw)) {
1319
+ const kind = raw;
1320
+ if (!accepted.includes(kind)) {
1321
+ throw refuse(raw, accepted, helpFor, `names the ${kind}, which this command does not take`, noun);
1322
+ }
1323
+ return { kind };
1324
+ }
1325
+ if (accepted.includes("file") && (/\.json$/i.test(raw) || /[\\/]/.test(raw))) {
1326
+ return { kind: "file", path: raw };
1327
+ }
1328
+ if (/\.json$/i.test(raw) || /[\\/]/.test(raw)) {
1329
+ throw refuse(raw, accepted, helpFor, "names a path, and a path has never run", noun);
1330
+ }
1331
+ const named = accepted.filter((k) => (Object.hasOwn(PREFIXED, k) ? PREFIXED[k] : void 0) !== void 0);
1332
+ const others = accepted.filter((k) => k !== "file" && (Object.hasOwn(PREFIXED, k) ? PREFIXED[k] : void 0) === void 0);
1333
+ if (named.length === 1 && others.length === 0) {
1334
+ return { kind: named[0], name: raw };
1335
+ }
1336
+ throw refuse(raw, accepted, helpFor, `names no ${noun.singular}`, noun, keywordSuggestion(raw, accepted));
1337
+ }
1338
+ function verbBackendName(raw, kind, helpFor, flags = "") {
1339
+ const value = raw.trim();
1340
+ if (!isKindShaped(value)) return value;
1341
+ const colon = value.indexOf(":");
1342
+ const typed = value.slice(0, colon);
1343
+ const name = value.slice(colon + 1).trim();
1344
+ const verb = `xanosdk ${kind} ${helpFor.subcommand}`;
1345
+ if (typed === kind) {
1346
+ if (name === "") throw new UsageError(`"${raw}" names no ${kind}. \`${verb}\` takes ${withArticle(kind)} name.`, { hintFor: helpFor });
1347
+ return name;
1348
+ }
1349
+ const shared = helpFor.subcommand === "get" || helpFor.subcommand === "delete";
1350
+ const other = shared && (typed === "tenant" || typed === "ephemeral") ? `xanosdk ${typed} ${helpFor.subcommand}` : void 0;
1351
+ const known = Object.hasOwn(PREFIXED, typed) || BARE.includes(typed);
1352
+ throw new UsageError(
1353
+ `"${raw}" ${known ? `names ${withArticle(typed.replace("-", " "))}` : `names no backend kind "${typed}"`}, and \`${verb}\` takes ${withArticle(kind)} name (\`${kind}:<name>\` or the bare name).` + (other !== void 0 && name !== "" ? ` For ${withArticle(typed)}, run \`${other} ${shellQuote(name)}${flags}\`.` : ""),
1354
+ { hintFor: helpFor }
1355
+ );
1356
+ }
1357
+ function isBackendHandle(name) {
1358
+ return /^[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}$/.test(name);
1359
+ }
1360
+
1361
+ // src/emit/commands.ts
1362
+ function renderArgs(args) {
1363
+ return (args ?? []).map((a) => a.required && a.satisfiedBy === void 0 ? `<${a.name}>` : `[${a.name}]`).join(" ");
1364
+ }
1365
+ var HELP_GROUP_ORDER = [
1366
+ "Author",
1367
+ "Deploy",
1368
+ "Environments",
1369
+ "Account",
1370
+ "Maintenance"
1371
+ ];
1372
+ var FLAGS = {
1373
+ out: { spec: "--out, -o <path>", summary: "Write the artifact to this path instead of stdout (`-` is stdout)" },
1374
+ lock: { spec: "--lock[=<path>]", summary: "Name the xano.lock to use \u2014 default: beside the entry file" },
1375
+ "no-lock": { spec: "--no-lock", summary: "Build with no lock: identities derive from names, public URLs are left to the instance" },
1376
+ entry: {
1377
+ // `--entry <path>` and `--entry=<path>` both parse; the spaced spelling is
1378
+ // what makes completion offer files after it.
1379
+ spec: "--entry <path>",
1380
+ summary: "Workspace entry to resolve xano.lock beside (for lock subcommands that take no entry file)"
1381
+ },
1382
+ "frozen-lock": { spec: "--frozen-lock", summary: "CI guard: fail instead of changing the lock, or on a lock entry nothing matches" },
1383
+ "allow-lock-orphans": {
1384
+ spec: "--allow-lock-orphans",
1385
+ summary: "With --frozen-lock: accept lock entries no exported object matches, for a workspace adopted with `lock import` and ported a piece at a time"
1386
+ },
1387
+ strict: { spec: "--strict", summary: "Promote every export warning (data-losing shapes, unresolvable filters) to a hard failure" },
1388
+ yes: { spec: "--yes, -y", summary: "Confirm a destructive action non-interactively" },
1389
+ bundle: { spec: "--bundle <path>", summary: "Use an already-exported bundle instead of an entry file" },
1390
+ reset: {
1391
+ spec: "--reset",
1392
+ summary: "Replace the environment and re-seed it, overriding --keep-data (a deploy without --keep-data already does)"
1393
+ },
1394
+ "keep-data": {
1395
+ spec: "--keep-data",
1396
+ summary: "Keep the environment's table rows: merge into what an earlier deploy filled instead of replacing it. Seed rows are not re-written, objects removed from the project are deleted, and a new or never-filled environment is replaced and seeded as usual. --reset overrides it; --to already merges"
1397
+ },
1398
+ // `test`'s selector. It was `--env`, which read as "an environment variable"
1399
+ // beside `--env-var`/`--backend-env-file` and named only two of the backend kinds.
1400
+ // Its accepted spellings and completion values come from the slot declared
1401
+ // on each `test` verb, not from this row.
1402
+ on: {
1403
+ spec: "--on <backend>",
1404
+ summary: "Run on this backend instead of the one this project last deployed to"
1405
+ },
1406
+ kind: {
1407
+ spec: "--kind <unit|workflow>",
1408
+ summary: "Only this test family (default: both)",
1409
+ values: ["unit", "workflow"]
1410
+ },
1411
+ concurrency: {
1412
+ spec: "--concurrency <n>",
1413
+ summary: "Run this many tests at once (default: 1). Tests share the environment database, so raise it only when yours do not depend on shared state."
1414
+ },
1415
+ "expires-hours": { spec: "--expires-hours <n>", summary: "Ephemeral TTL at create time, 1\u201324 (default: 1)" },
1416
+ static: { spec: "--static <dir>", summary: "Archive this built frontend and deploy it to the static host" },
1417
+ "local-engine": {
1418
+ spec: "--local-engine[=<version|url|path>]",
1419
+ summary: "Deploy to an engine on this machine instead of an ephemeral. Bare: runs the project's pinned engine version (the latest on first run, then pinned in package.json \u2014 commit it); a newer engine is offered, never applied without a yes. A version, URL or archive path (or XANOSDK_LOCAL_ENGINE_OVERRIDE, for every run in a shell) runs that engine as an override and never touches the pin; a URL must be https (plain http only from this machine). Not combinable with --to or --static"
1420
+ },
1421
+ // Keyed apart from the global `version` row: that one is the first-argument
1422
+ // `xanosdk --version`, this one a value an engine verb takes after the verb.
1423
+ "engine-version": {
1424
+ spec: "--version <v>",
1425
+ summary: "An engine version, like v0.1.5 (the leading v is optional)"
1426
+ },
1427
+ "no-dev-env": {
1428
+ spec: "--no-dev-env",
1429
+ summary: "Do not point this project's .env.local at the deployed backend (only written when no static site is published)"
1430
+ },
1431
+ "static-env": { spec: "--static-env KEY=VALUE", summary: "Public config baked in as window.<KEY> (repeatable; never secrets)" },
1432
+ "env-var": {
1433
+ spec: "--env-var KEY=VALUE",
1434
+ summary: "Set one BACKEND workspace env var for this run (repeatable). Beats xano/.env and --backend-env-file; the value never touches disk"
1435
+ },
1436
+ "backend-env-file": {
1437
+ spec: "--backend-env-file <path>",
1438
+ summary: "Read backend env values from this dotenv-style file INSTEAD of the default xano/.env (for CI, which does not have the ignored default)"
1439
+ },
1440
+ "allow-empty-env": {
1441
+ spec: "--allow-empty-env=NAME[,NAME]",
1442
+ summary: "Send these declared names EMPTY when no value is supplied, clearing them in whatever imports the bundle. Only `deploy` refuses without it; per-name on purpose, and a bare --allow-empty-env is refused"
1443
+ },
1444
+ "allow-empty-doc-token": {
1445
+ spec: "--allow-empty-doc-token=<scope>",
1446
+ summary: "Send this scope's documentation token EMPTY when none is supplied, clearing that doc site's gate in whatever imports the bundle \u2014 `workspace`, or an API group's name. Repeat for more than one. Without it `deploy` refuses any gate left with no token, and every build refuses one on a group that publishes its docs (`swagger` on); a bare --allow-empty-doc-token is refused"
1447
+ },
1448
+ "secrets-file": {
1449
+ spec: "--secrets-file <path>",
1450
+ summary: "Read documentation tokens from this file INSTEAD of the default xano/.secrets.json (for CI, which does not have the ignored default)"
1451
+ },
1452
+ "doc-token": {
1453
+ spec: "--doc-token <scope>=<value>",
1454
+ summary: "Supply one documentation token inline \u2014 `workspace=\u2026`, or an API group's name. Repeat for more than one. Prefer --secrets-file: a value here is visible in shell history, the process list, and any CI log that echoes the command"
1455
+ },
1456
+ "no-secrets": {
1457
+ spec: "--no-secrets",
1458
+ summary: "Find the documentation tokens and write none \u2014 for a machine where a secret on disk is not wanted. The tree still declares the gates, so a later deploy refuses rather than clearing one"
1459
+ },
1460
+ export: {
1461
+ spec: "--export <name>",
1462
+ summary: "The named export to compile, when the module exports several defs"
1463
+ },
1464
+ emit: {
1465
+ spec: "--emit <path>",
1466
+ summary: "Write a generated route + socket module there (plain data, no SDK import; `-` is stdout)"
1467
+ },
1468
+ "static-host": { spec: "--static-host <name>", summary: "Static-host name to deploy to (default: default)" },
1469
+ "static-routing": {
1470
+ spec: "--static-routing spa|multipage",
1471
+ summary: "Override URL resolution (inferred from the bundle; rarely needed)",
1472
+ values: ["spa", "multipage"]
1473
+ },
1474
+ test: {
1475
+ spec: "--test",
1476
+ summary: "After deploying, run the environment's tests; exit 5 if one fails, 6 if they cannot be reached; the deploy stands either way"
1477
+ },
1478
+ // Three flags where there was one. `--no-verify` meant a post-deploy liveness
1479
+ // probe, an offline round-trip diff, and "do not load the entry file" — three
1480
+ // unrelated checks whose only shared property was the word "verify", so the
1481
+ // one summary had to say "instead" mid-sentence and a reader had to know
1482
+ // which command they were on to know what they were turning off.
1483
+ "skip-liveness": {
1484
+ spec: "--skip-liveness",
1485
+ summary: "Do not wait to confirm the deploy came up (static host, microservices)"
1486
+ },
1487
+ "skip-roundtrip": {
1488
+ spec: "--skip-roundtrip",
1489
+ summary: "Do not check that the written tree re-exports as it was pulled (offline; no network, no deploy)"
1490
+ },
1491
+ "identity-only": {
1492
+ spec: "--identity-only",
1493
+ summary: "Act on the named lock entries without loading the entry file"
1494
+ },
1495
+ "require-microservices": {
1496
+ spec: "--require-microservices",
1497
+ summary: "Fail the deploy (exit 4) when a microservice is not ready by the end of the wait"
1498
+ },
1499
+ report: {
1500
+ spec: "--report <grouped|full|json>",
1501
+ summary: "Findings as grouped root causes (default), every site, or JSON",
1502
+ values: ["grouped", "full", "json"]
1503
+ },
1504
+ origin: {
1505
+ spec: "--origin <origin>",
1506
+ summary: "Xano OAuth host for `login` and a XANO_REFRESH_TOKEN exchange (default: $XANO_ORIGIN)"
1507
+ },
1508
+ config: { spec: "--config <path>", summary: "Explicit credential file (default: $XANO_CONFIG)" },
1509
+ local: { spec: "--local", summary: "Use the project-local ./.xano/auth.json instead of the shared cache" },
1510
+ profile: {
1511
+ spec: "--profile, -p <name>",
1512
+ summary: "Commands that sign in: which stored credential profile to act as \u2014 the only thing that overrides this project's xano.profile.json (then $XANO_PROFILE, then the credential file default)"
1513
+ },
1514
+ all: { spec: "--all", summary: "Every stored profile, not just the active one" },
1515
+ "all-workspaces": { spec: "--all-workspaces", summary: "Enumerate across every workspace, not just the token's" },
1516
+ guest: { spec: "--guest, -g", summary: "Mint a read-only guest session (browse only)" },
1517
+ "url-only": { spec: "--url-only, -u", summary: "Print the dashboard URL instead of opening a browser" },
1518
+ prompt: { spec: "--prompt", summary: "Print only the add-on wiring prompt, for piping to a coding agent" },
1519
+ port: { spec: "--port <n>", summary: "Loopback callback port (default: 47100)" },
1520
+ "workspace-id": { spec: "--workspace-id <n>", summary: "Numeric workspace the meta API token acts on" },
1521
+ paste: {
1522
+ spec: "--paste",
1523
+ summary: "Sign in without the loopback callback: open the printed URL in any browser and paste the redirect back. For a host whose 127.0.0.1 the browser cannot reach \u2014 remote shell, container, Codespace. Needs a terminal."
1524
+ },
1525
+ scope: { spec: '--scope "<list>"', summary: "OAuth scopes to request (default: the built-in set)" },
1526
+ runtime: { spec: "--runtime", summary: "After the round-trip, run each deployed function and report" },
1527
+ capture: { spec: "--capture", summary: "Write each round-tripped function's fetched JSON" },
1528
+ "legacy-runtime": { spec: "--legacy-runtime", summary: "Remove the runtime copy earlier versions left in your own cache directory" },
1529
+ verbose: { spec: "--verbose", summary: "Print full diffs and raw engine detail" },
1530
+ instance: { spec: "--instance <url>", summary: "Override XANO_VALIDATE_INSTANCE for this run" },
1531
+ format: {
1532
+ spec: "--format <json|multidoc>",
1533
+ summary: "Which artifact to emit: json (default), or multidoc (the backend as XanoScript, rendered by the engine)",
1534
+ values: ["json", "multidoc"]
1535
+ },
1536
+ path: { spec: "--path <p>", summary: "Output location \u2014 `-` for stdout, a dir, or a file path" },
1537
+ name: { spec: "--name <n>", summary: "Name for what this command produces" },
1538
+ framework: {
1539
+ spec: "--framework <id>",
1540
+ summary: "Frontend framework to scaffold: react (default), svelte",
1541
+ values: ["react", "svelte"]
1542
+ },
1543
+ theme: {
1544
+ spec: "--theme <id>",
1545
+ summary: "shadcn/ui theme \u2014 <base> or <base>-<accent> (e.g. zinc-blue), a registry theme URL, or a registry item JSON path; an unknown id lists every base and accent",
1546
+ // Completion offers the base colors alone — the accent half multiplies them
1547
+ // into 126 values, which is a menu no one reads at a tab-complete prompt.
1548
+ // `--help` carries the accent list; this carries the starting points.
1549
+ values: ["neutral", "stone", "zinc", "mauve", "olive", "mist", "taupe"],
1550
+ open: true
1551
+ },
1552
+ radius: {
1553
+ spec: "--radius <len>",
1554
+ summary: "Corner radius for the scaffold's theme \u2014 a number of rem (0, 0.5, 1) or a CSS length",
1555
+ values: ["0", "0.25", "0.5", "0.625", "0.75", "1"],
1556
+ open: true
1557
+ },
1558
+ dark: {
1559
+ spec: "--dark <mode>",
1560
+ summary: "What switches the app into its dark palette: system (default, follows the OS), toggle (adds a control), off",
1561
+ values: ["system", "toggle", "off"]
1562
+ },
1563
+ font: {
1564
+ spec: "--font <id>",
1565
+ summary: "Body typeface \u2014 sans faces only (mono: --font-mono; serif: --font-heading), self-hosted from its @fontsource package (default: the system stack)",
1566
+ values: fontIdsFor("sans")
1567
+ },
1568
+ "font-mono": {
1569
+ spec: "--font-mono <id>",
1570
+ summary: "Code typeface \u2014 mono faces only (default: the system mono stack)",
1571
+ values: fontIdsFor("mono")
1572
+ },
1573
+ "font-heading": {
1574
+ spec: "--font-heading <id>",
1575
+ summary: "Heading typeface, any face, bound to h1\u2013h6 (default: inherits the body face)",
1576
+ values: fontIdsFor("heading")
1577
+ },
1578
+ icons: {
1579
+ spec: "--icons <id>",
1580
+ summary: "Icon set: lucide (default), tabler, phosphor",
1581
+ values: ["lucide", "tabler", "phosphor"]
1582
+ },
1583
+ "no-agents-md": { spec: "--no-agents-md", summary: "Do not write the AGENTS.md agent brief" },
1584
+ ai: {
1585
+ spec: "--ai <preset|none>",
1586
+ summary: "For scripted callers: `none` is --no-agents-md; any other value (an agent name) writes the one AGENTS.md every agent reads"
1587
+ },
1588
+ marketplace: {
1589
+ spec: "--marketplace <pkgs>",
1590
+ summary: "Marketplace modules to install and register, comma-separated, by the names `marketplace install` takes (auth resolves to @xano-sdk/auth); a name the marketplace does not list exits 8 before anything is written. An add-on install or the project npm install that fails exits 2 with the project left in place"
1591
+ },
1592
+ // `--from` and `--to` are every read's and every write's selector. Which
1593
+ // backends each command takes is declared on its own reference (a
1594
+ // `selector`), so these shared rows carry no spelling list and no values.
1595
+ from: {
1596
+ spec: "--from <source>",
1597
+ summary: "The backend to read from"
1598
+ },
1599
+ to: {
1600
+ spec: "--to <destination>",
1601
+ summary: "The backend to write to"
1602
+ },
1603
+ description: {
1604
+ spec: "--description <text>",
1605
+ summary: "What this release is for"
1606
+ },
1607
+ release: {
1608
+ spec: "--release <name>",
1609
+ summary: "The release this frontend belongs to \u2014 checked to exist and reported with the publish"
1610
+ },
1611
+ web: {
1612
+ spec: "--web",
1613
+ summary: "Collect the scaffold options in a browser instead of on the command line"
1614
+ },
1615
+ check: {
1616
+ spec: "--check",
1617
+ summary: "Report whether an upgrade is available and exit 7, without installing it"
1618
+ },
1619
+ /**
1620
+ * One meaning, everywhere: OVERWRITE something that already exists.
1621
+ *
1622
+ * `--yes` is the other half of the pair and means "do not ask me". They were
1623
+ * synonyms on three commands, where `--force` bought a second spelling for a
1624
+ * confirmation prompt and nothing else — so a reader could not tell, from the
1625
+ * flag alone, whether a command was going to overwrite anything. No command
1626
+ * takes both.
1627
+ */
1628
+ force: { spec: "--force", summary: "Overwrite something that already exists" },
1629
+ "backend-dir": {
1630
+ spec: "--backend-dir <path>",
1631
+ summary: "The backend directory to act on, when this project does not keep it in xano/ and nothing on disk says so"
1632
+ },
1633
+ "no-install": { spec: "--no-install", summary: "Skip the post-scaffold npm install" },
1634
+ "dry-run": { spec: "--dry-run", summary: "Print what would change and exit without sending it" },
1635
+ prune: { spec: "--prune", summary: "Also delete workspace objects your project no longer defines" },
1636
+ "reset-data": { spec: "--reset-data", summary: "Empty every table the bundle carries before importing" },
1637
+ seed: { spec: "--seed", summary: "Write the bundle's table rows (off by default; `--replace` always writes them)" },
1638
+ table: {
1639
+ spec: "--table <guid>",
1640
+ summary: `Which table to act on, by guid (repeatable) \u2014 \`${tablesCommand("workspace")}\` lists them`
1641
+ },
1642
+ write: {
1643
+ spec: "--write",
1644
+ summary: "Actually perform the write \u2014 without it this is a dry run that changes nothing"
1645
+ },
1646
+ replace: {
1647
+ spec: "--replace",
1648
+ summary: "Wipe the workspace \u2014 including ALL its branches \u2014 and import in its place"
1649
+ },
1650
+ branch: {
1651
+ spec: "--branch <label>",
1652
+ summary: "Release to this branch instead of the live one (stages logic; schema is shared)"
1653
+ },
1654
+ "set-live": { spec: "--set-live", summary: "Promote the branch to live once the import lands" },
1655
+ "expect-live": {
1656
+ spec: "--expect-live <label>",
1657
+ summary: "With --set-live: refuse unless <label> is live \u2014 checked before landing and again before switching (not atomic)"
1658
+ },
1659
+ "to-profile": {
1660
+ spec: "--to-profile <name>",
1661
+ summary: "The stored credential profile whose instance and workspace receive the release"
1662
+ },
1663
+ "allow-shared-schema-changes": {
1664
+ spec: "--allow-shared-schema-changes",
1665
+ summary: "Proceed even though table/microservice changes reach every branch"
1666
+ },
1667
+ "allow-branch-deletion": {
1668
+ spec: "--allow-branch-deletion",
1669
+ summary: "Acknowledge that --replace permanently deletes the workspace's other branches"
1670
+ },
1671
+ "backup-branch": {
1672
+ spec: "--backup-branch[=<label>]",
1673
+ summary: "Snapshot the live branch's logic first; set-live back restores logic, not tables (shared by every branch)"
1674
+ },
1675
+ open: { spec: "--open", summary: "Open the deployed URL in your browser when it lands" },
1676
+ // ── Global (accepted by every command; see GLOBAL_FLAGS) ───────────────
1677
+ json: {
1678
+ spec: "--json",
1679
+ summary: "Force JSON on stdout (default: whenever stdout is not a terminal, a failure's document too \u2014 except help, `version`, which stays text for `$(xanosdk version)`, and a command whose stdout is its data, such as `export` or `--path -`)"
1680
+ },
1681
+ "no-refresh": {
1682
+ spec: "--no-refresh",
1683
+ summary: "Do not refresh the managed block in AGENTS.md"
1684
+ },
1685
+ help: { spec: "--help, -h", summary: "Show help for the command and exit" },
1686
+ version: { spec: "--version, -v", summary: "Print the CLI version and exit" }
1687
+ };
1688
+ var GLOBAL_FLAGS = [
1689
+ "json",
1690
+ // Global rather than part of the shared AUTH bundle: it occupies ONE help row
1691
+ // here, against one on each of ~35 authenticated commands' manifest entries.
1692
+ // Commands that cannot honour it REFUSE it (see the post-loop cross-check in
1693
+ // `parseArgs`) rather than accepting and ignoring it.
1694
+ "profile",
1695
+ "no-refresh",
1696
+ "help",
1697
+ "version"
1698
+ ];
1699
+ var AUTH = ["origin", "config", "local"];
1700
+ var CREDENTIAL_FILE = ["config", "local"];
1701
+ function isAuthenticatedCommand(command, subcommand) {
1702
+ return flagRefFor(command, subcommand, "config") !== void 0;
1703
+ }
1704
+ var PROFILE_BY_NAME = ["add", "use", "set-default", "delete"];
1705
+ function takesProfileFlag(command, subcommand) {
1706
+ if (command === "profile" && subcommand !== void 0 && PROFILE_BY_NAME.includes(subcommand)) return false;
1707
+ return isAuthenticatedCommand(command, subcommand);
1708
+ }
1709
+ var CUT = ["workspace", "ephemeral", "tenant"];
1710
+ var BACKEND = ["workspace", "ephemeral", "local-engine", "tenant"];
1711
+ var TEST_ON = {
1712
+ key: "on",
1713
+ summary: "Run on this backend instead of the one this project last deployed to",
1714
+ selector: { accepted: BACKEND, role: "on", default: "tracked" }
1715
+ };
1716
+ var TEST_LIST_ON = {
1717
+ ...TEST_ON,
1718
+ summary: "List the tests on this backend instead of the one this project last deployed to"
1719
+ };
1720
+ var REFUSES_EMPTY_ENV = /* @__PURE__ */ new Set(["deploy"]);
1721
+ var REFUSES_EMPTY_DOC_TOKEN = /* @__PURE__ */ new Set(["deploy"]);
1722
+ var ENV_VALUE_FLAGS = [
1723
+ "env-var",
1724
+ "backend-env-file",
1725
+ "allow-empty-env",
1726
+ "allow-empty-doc-token",
1727
+ "secrets-file",
1728
+ "doc-token"
1729
+ ];
1730
+ var ENV_VAR_TARGET_FLAGS = [
1731
+ {
1732
+ key: "to",
1733
+ summary: "Write to this backend instead of the one this project last deployed to",
1734
+ selector: { accepted: BACKEND, role: "to", default: "tracked" }
1735
+ },
1736
+ { key: "yes", summary: "Skip the confirmation a workspace or tenant write asks for (required when there is no terminal)" }
1737
+ ];
1738
+ var COMPILE = [
1739
+ "lock",
1740
+ "no-lock",
1741
+ "frozen-lock",
1742
+ "allow-lock-orphans",
1743
+ "strict",
1744
+ ...ENV_VALUE_FLAGS
1745
+ ];
1746
+ var COMPARISON_LOCK_FLAGS = [
1747
+ "lock",
1748
+ "no-lock",
1749
+ "frozen-lock",
1750
+ "allow-lock-orphans"
1751
+ ];
1752
+ var COMPILE_COMPARISON_ONLY = COMPILE.filter(
1753
+ (key) => !COMPARISON_LOCK_FLAGS.includes(key)
1754
+ ).map(
1755
+ (key) => ENV_VALUE_FLAGS.includes(key) ? {
1756
+ key,
1757
+ // The shared summary's trailing punctuation is not load-bearing for
1758
+ // another command's help text: normalize it before appending.
1759
+ summary: `${FLAGS[key].summary.replace(/[.\s]+$/, "")}. Applies ONLY to the local-compile comparison this command runs against the source \u2014 the released bytes come from what is running`
1760
+ } : key
1761
+ );
1762
+ var SCAFFOLD = [
1763
+ { key: "name", summary: "Project name (default: the target directory's basename)" },
1764
+ "framework",
1765
+ "theme",
1766
+ "radius",
1767
+ "dark",
1768
+ "font",
1769
+ "font-mono",
1770
+ "font-heading",
1771
+ "icons",
1772
+ "no-agents-md",
1773
+ "ai",
1774
+ {
1775
+ key: "force",
1776
+ summary: "Write into a non-empty target directory. Over an existing project it lists every file it would overwrite and confirms first (--yes without a terminal); files the scaffold does not write are kept"
1777
+ },
1778
+ "no-install"
1779
+ ];
1780
+ var GUID_STABILITY_NOTE = "Guids survive a redeploy, so one written down earlier keeps matching \u2014 and a rename whose xano.lock entry moves with it (`lock rename`) keeps it too; one the lock is not told about gives the table a new guid";
1781
+ function tablesCommand(backend = "<backend>") {
1782
+ return `xanosdk tables ${backend}`;
1783
+ }
1784
+ function withToOnly(key) {
1785
+ return { key, summary: `${FLAGS[key].summary} \u2014 only with --to` };
1786
+ }
1787
+ function withoutTo(key, summary = FLAGS[key].summary) {
1788
+ return { key, summary: `${summary} \u2014 not with --to` };
1789
+ }
1790
+ var COMMANDS = {
1791
+ // ── Author ──────────────────────────────────────────────────────────────
1792
+ compile: {
1793
+ group: "Author",
1794
+ display: "compile <file>",
1795
+ // Says "single object def", not "workspace": this command takes ONE def and
1796
+ // prints its JSON artifact. `compile` is the first command listed under
1797
+ // Author, so it is the first thing tried on the scaffold entry (a
1798
+ // workspace), which fails — the summary must not promise otherwise.
1799
+ // `export` is the workspace command. It does not type-check: the entry is
1800
+ // loaded with its types stripped, so `tsc` is what catches a type error.
1801
+ summary: "Compile a single object def and print its JSON artifact (not type-checked \u2014 run `tsc` for that)",
1802
+ args: [{ name: "file", required: true, path: true }],
1803
+ flags: ["out", "lock", "strict", "export"],
1804
+ example: "xanosdk compile ./xano/query/public/health_GET.ts"
1805
+ },
1806
+ export: {
1807
+ group: "Author",
1808
+ display: "export <file>",
1809
+ summary: "Compile and write the deployable JSON bundle",
1810
+ args: [{ name: "file", required: true, path: true }],
1811
+ flags: [
1812
+ "out",
1813
+ ...COMPILE,
1814
+ {
1815
+ key: "check",
1816
+ summary: "CI check: run every export check and fail instead of changing the lock, writing nothing \u2014 no bundle, no lock, so no secrets are needed"
1817
+ }
1818
+ ],
1819
+ example: "xanosdk export ./index.ts --out bundle.json"
1820
+ },
1821
+ routes: {
1822
+ group: "Author",
1823
+ display: "routes <file>",
1824
+ summary: "List each query's verb + resolved api:<canonical>/<name>",
1825
+ args: [{ name: "file", required: true, path: true }],
1826
+ flags: [
1827
+ "lock",
1828
+ "emit",
1829
+ {
1830
+ key: "strict",
1831
+ summary: "With --emit: write nothing, and fail when the file is missing or out of date (what xano:check runs)"
1832
+ }
1833
+ ],
1834
+ example: "xanosdk routes ./index.ts --emit xano/routes.gen.ts"
1835
+ },
1836
+ // `routes` is the canonical spelling: it is the word every web framework uses
1837
+ // for this list, where `paths` is OpenAPI's term for the same thing and reads
1838
+ // as filesystem paths to everyone else. `paths` still dispatches — it is what
1839
+ // the command was called — but it is off the menu.
1840
+ paths: {
1841
+ group: "Author",
1842
+ display: "paths <file>",
1843
+ summary: "Alias for `routes`",
1844
+ aliasOf: "routes",
1845
+ args: [{ name: "file", required: true, path: true }],
1846
+ flags: [
1847
+ "lock",
1848
+ "emit",
1849
+ {
1850
+ key: "strict",
1851
+ summary: "With --emit: write nothing, and fail when the file is missing or out of date (what xano:check runs)"
1852
+ }
1853
+ ]
1854
+ },
1855
+ init: {
1856
+ group: "Author",
1857
+ display: "init [dir]",
1858
+ // Toolchain modules contribute their own question flags; see the field's
1859
+ // doc for the obligation this takes on.
1860
+ deferUnknownFlags: true,
1861
+ summary: "Scaffold a Xano SDK project \u2014 empty, or filled from an existing backend",
1862
+ args: [{ name: "dir", required: false, path: true }],
1863
+ // Two axes on top of the shared scaffold flags: WHERE `xano/` comes from
1864
+ // (`--from`) and HOW the options were collected (`--web`). They compose —
1865
+ // a browser-chosen shell around a decoded workspace is one invocation.
1866
+ //
1867
+ // `--marketplace` rides with them but is not in SCAFFOLD: a `--from` run
1868
+ // writes a project around a workspace that already exists, and adding
1869
+ // add-ons to one is `marketplace install`, not a scaffold decision.
1870
+ //
1871
+ // `--report`, `--skip-roundtrip` and the auth flags only bite under `--from`;
1872
+ // passing them without it is a usage error rather than a silent no-op.
1873
+ flags: [
1874
+ ...SCAFFOLD,
1875
+ "marketplace",
1876
+ {
1877
+ key: "from",
1878
+ summary: "Fill xano/ by decoding an existing backend instead of writing the empty starter",
1879
+ selector: { accepted: [...BACKEND, "release", "file"], role: "from", default: "none" }
1880
+ },
1881
+ "web",
1882
+ "skip-roundtrip",
1883
+ "report",
1884
+ "no-secrets",
1885
+ {
1886
+ key: "yes",
1887
+ summary: "Confirm without asking what --force overwrites, or what --from replaces in an existing xano/ \u2014 required when there is no terminal"
1888
+ },
1889
+ {
1890
+ key: "branch",
1891
+ summary: "Read this branch instead of the live one (`--from workspace` only)"
1892
+ },
1893
+ ...AUTH
1894
+ ],
1895
+ // One flag from each axis the command now has — look, add-ons —
1896
+ // rather than every flag it accepts.
1897
+ example: "xanosdk init my-app --theme zinc-blue --marketplace @xano-sdk/auth"
1898
+ },
1899
+ marketplace: {
1900
+ group: "Author",
1901
+ // Every verb, spelled out. The family is a lifecycle — find it, add it,
1902
+ // change it, drop it — and a row that stopped at `install` read as though
1903
+ // the last two did not exist. `tenant` already carries six the same way.
1904
+ display: "marketplace <list|search|details|install|reinstall|remove>",
1905
+ summary: "Find Xano SDK add-on packages and add them to this project",
1906
+ subcommands: {
1907
+ // No apostrophes in any registry string: zsh completion single-quotes
1908
+ // these, and the completion suite fails the whole script on an odd quote.
1909
+ list: {
1910
+ summary: "List every published add-on, newest first",
1911
+ extraArgHint: "`list` prints the whole catalogue; `xanosdk marketplace search <query>` is the filter.",
1912
+ example: "xanosdk marketplace list"
1913
+ },
1914
+ search: {
1915
+ summary: "Search add-ons by keyword across name, tagline and description",
1916
+ // Variadic: the handler joins every term into one phrase query, so
1917
+ // `search ai agent` searches for "ai agent" rather than dropping "agent".
1918
+ args: [{ name: "query", required: true, variadic: true }],
1919
+ example: "xanosdk marketplace search auth"
1920
+ },
1921
+ details: {
1922
+ summary: "Show what an add-on installs, what it needs, and how to register it",
1923
+ args: [{ name: "package", required: true }],
1924
+ flags: ["prompt"],
1925
+ example: "xanosdk marketplace details @xano-sdk/auth"
1926
+ },
1927
+ install: {
1928
+ summary: "Install a marketplace module into the Xano SDK project in the current directory, by package or catalogue name (auth resolves to @xano-sdk/auth); a name the marketplace does not list exits 8",
1929
+ args: [{ name: "package", required: true }],
1930
+ // An installed toolchain module contributes questions, each deriving a
1931
+ // flag that answers it non-interactively — and which modules exist is
1932
+ // not knowable until npm has run, long after parsing. Declared on the
1933
+ // VERB, never on `marketplace`: see SubcommandSpec.deferUnknownFlags.
1934
+ deferUnknownFlags: true,
1935
+ example: "xanosdk marketplace install @xano-sdk/auth"
1936
+ },
1937
+ reinstall: {
1938
+ summary: "Re-ask the questions for an installed toolchain module and re-apply its settings (takes the names install takes)",
1939
+ args: [{ name: "package", required: true }],
1940
+ // Same reason as `install`: this verb runs the questionnaire, so the
1941
+ // flags a module derives from its own questions cannot be known until
1942
+ // the module has been imported.
1943
+ deferUnknownFlags: true,
1944
+ example: "xanosdk marketplace reinstall <toolchain-package>"
1945
+ },
1946
+ remove: {
1947
+ summary: "Uninstall a Xano SDK module and drop the settings and file lines it contributed (takes the names install takes)",
1948
+ args: [{ name: "package", required: true }],
1949
+ // Deliberately NO deferUnknownFlags: this verb runs no
1950
+ // questionnaire, so nothing downstream could ever claim a plugin flag.
1951
+ // Deferring here would accept `--renderer-dir=x` on a removal and
1952
+ // silently discard it.
1953
+ example: "xanosdk marketplace remove <toolchain-package>"
1954
+ }
1955
+ }
1956
+ },
1957
+ // ── Deploy ──────────────────────────────────────────────────────────────
1958
+ deploy: {
1959
+ group: "Deploy",
1960
+ display: "deploy [source]",
1961
+ summary: "Ship to a live ephemeral env \u2192 URL",
1962
+ // Optional: a bare `deploy` inside a project compiles its entry, and the
1963
+ // argument may name a backend to take the bytes FROM instead of a path.
1964
+ args: [
1965
+ {
1966
+ name: "source",
1967
+ required: false,
1968
+ path: true,
1969
+ satisfiedBy: ["bundle"],
1970
+ selector: { accepted: ["release", ...BACKEND, "file"], role: "subject", default: "entry" }
1971
+ }
1972
+ ],
1973
+ flags: [
1974
+ withoutTo("expires-hours"),
1975
+ withoutTo(
1976
+ "name",
1977
+ "Display name for the ephemeral env (default for a new one: the release name for release:<name>, else the workspace name, else this directory's)"
1978
+ ),
1979
+ {
1980
+ key: "to",
1981
+ summary: "Merge into a real destination instead of replacing an ephemeral. The escape hatch from the release flow",
1982
+ // An ephemeral and a local engine are where a deploy goes WITHOUT
1983
+ // `--to`; naming one here is the other path spelled wrong, and the
1984
+ // reason says which flag that path is.
1985
+ selector: {
1986
+ accepted: ["workspace", "tenant"],
1987
+ role: "to",
1988
+ default: "none",
1989
+ refused: {
1990
+ "local-engine": "a deploy to a local engine is `--local-engine`, which also downloads, pins and starts one",
1991
+ ephemeral: "a deploy with no `--to` already replaces an ephemeral. To merge into one instead, name it as the tenant it is: `--to tenant:<ephemeral name>`"
1992
+ }
1993
+ }
1994
+ },
1995
+ "local-engine",
1996
+ withToOnly("dry-run"),
1997
+ withToOnly("prune"),
1998
+ withToOnly("reset-data"),
1999
+ withToOnly("seed"),
2000
+ withToOnly("replace"),
2001
+ withToOnly("allow-shared-schema-changes"),
2002
+ withToOnly("allow-branch-deletion"),
2003
+ withToOnly("branch"),
2004
+ withToOnly("set-live"),
2005
+ withToOnly("backup-branch"),
2006
+ "yes",
2007
+ "bundle",
2008
+ "static",
2009
+ { key: "static-host", summary: "With --static: static-host name to deploy to (default: default)" },
2010
+ { key: "static-routing", summary: "With --static: override URL resolution (inferred from the bundle; rarely needed)" },
2011
+ {
2012
+ key: "static-env",
2013
+ summary: "With --static: public config baked in as window.<KEY> (repeatable; never secrets)"
2014
+ },
2015
+ withoutTo("no-dev-env"),
2016
+ "skip-liveness",
2017
+ withoutTo("require-microservices"),
2018
+ withoutTo("test"),
2019
+ withoutTo("kind", "With --test: only this test family (default: both)"),
2020
+ withoutTo("concurrency", "With --test: run this many tests at once (default: 1)"),
2021
+ withoutTo("open"),
2022
+ "keep-data",
2023
+ withoutTo("reset"),
2024
+ ...COMPILE,
2025
+ ...AUTH
2026
+ ],
2027
+ example: "xanosdk deploy ./index.ts --test"
2028
+ },
2029
+ env: {
2030
+ group: "Deploy",
2031
+ display: "env <pull|set|unset>",
2032
+ summary: "The backend env VALUES in .env beside the backend (xano/.env by default) \u2014 one of the two files there that are not committed \u2014 and one value at a time on a running backend",
2033
+ subcommands: {
2034
+ pull: {
2035
+ // Self-contained: the scoped help page renders this line ALONE, without
2036
+ // the `env` summary above it that says which file "that" is.
2037
+ summary: "Fill the local .env from a backend that is running. Over an existing file it lists what changes and confirms, then rewrites the whole file; a missing file is created without asking, and identical values write nothing",
2038
+ flags: [
2039
+ {
2040
+ key: "from",
2041
+ summary: "Read the values from this backend instead of the one this project last deployed to",
2042
+ selector: { accepted: BACKEND, role: "from", default: "tracked" }
2043
+ },
2044
+ {
2045
+ key: "yes",
2046
+ summary: "Skip the confirmation before an existing .env is changed (required for that when there is no terminal)"
2047
+ },
2048
+ "backend-dir",
2049
+ ...AUTH
2050
+ ],
2051
+ example: "xanosdk env pull --from workspace"
2052
+ },
2053
+ set: {
2054
+ summary: "Set ONE env var on a running backend by name \u2014 creates it or replaces its value, leaves every other one alone. The value is the second argument, or stdin when omitted; it is never printed",
2055
+ args: [
2056
+ { name: "name", required: true },
2057
+ { name: "value", required: false }
2058
+ ],
2059
+ flags: [
2060
+ ...ENV_VAR_TARGET_FLAGS,
2061
+ {
2062
+ key: "allow-empty-env",
2063
+ spec: "--allow-empty-env=NAME",
2064
+ summary: "Store an EMPTY value for NAME. Refused without it: an empty value is usually an unset shell variable. To remove the variable, use `env unset`"
2065
+ },
2066
+ ...AUTH
2067
+ ],
2068
+ example: 'printf %s "$STRIPE_KEY" | xanosdk env set STRIPE_KEY --to workspace --yes'
2069
+ },
2070
+ unset: {
2071
+ summary: "Clear ONE env var on a running backend by name, leaving every other one alone. A name it does not have is reported, not an error",
2072
+ args: [{ name: "name", required: true }],
2073
+ flags: [...ENV_VAR_TARGET_FLAGS, ...AUTH],
2074
+ example: "xanosdk env unset STRIPE_KEY --to workspace --yes"
2075
+ }
2076
+ }
2077
+ },
2078
+ secrets: {
2079
+ group: "Deploy",
2080
+ // One verb today, and the noun is still the right shape: the file this
2081
+ // family owns is the project's secret STORE, and `xanosdk fill` would say
2082
+ // nothing about what is being filled.
2083
+ display: "secrets <fill>",
2084
+ summary: "The documentation tokens in .secrets.json beside the backend (xano/.secrets.json by default) \u2014 the other file there that is not committed",
2085
+ subcommands: {
2086
+ fill: {
2087
+ summary: "Mint a token for every documentation gate that has none (never replaces one)",
2088
+ args: [{ name: "file", required: false, path: true }],
2089
+ flags: ["lock"],
2090
+ example: "xanosdk secrets fill"
2091
+ }
2092
+ }
2093
+ },
2094
+ release: {
2095
+ group: "Deploy",
2096
+ display: "release <create|list|show|export|delete|transfer>",
2097
+ summary: "Cut and manage releases \u2014 the stored record of a backend that ran",
2098
+ subcommands: {
2099
+ create: {
2100
+ summary: "Cut a release from a running environment, tenant, or the workspace",
2101
+ args: [{ name: "name", required: true }],
2102
+ flags: [
2103
+ // A release is cut from something that RAN, so a path is not in the
2104
+ // set, and the cut runs on the instance, so a local engine is refused
2105
+ // with that reason rather than left unknown.
2106
+ {
2107
+ key: "from",
2108
+ summary: "Cut from this backend instead of the one this project last deployed to (a tenant only when it is a throwaway one: ephemeral or sandbox)",
2109
+ selector: {
2110
+ accepted: CUT,
2111
+ role: "from",
2112
+ default: "tracked",
2113
+ refused: {
2114
+ "local-engine": "the cut runs on the instance, which cannot reach an engine on this machine"
2115
+ }
2116
+ }
2117
+ },
2118
+ "description",
2119
+ // Only meaningful with `--from workspace`: it names which branch to
2120
+ // package. An environment has one, so it takes no label.
2121
+ { key: "branch", summary: "Cut from this branch of your workspace (default: the one it serves)" },
2122
+ // Deploy's own summary describes writing a BUNDLE's rows into a
2123
+ // target. This is the opposite direction — it captures the source's
2124
+ // current rows into the archive — so the shared summary would be a
2125
+ // category error here.
2126
+ // The re-mint caveat's second surface: the refusal catches a
2127
+ // stale guid, but only after one has been written down. This states it
2128
+ // before anything is run.
2129
+ {
2130
+ key: "seed",
2131
+ spec: "--seed[=<guids>]",
2132
+ summary: `Carry the source's table ROWS in the archive: every table, or only these guids (\`${tablesCommand()}\` lists them for the backend you are cutting from). ${GUID_STABILITY_NOTE}. Off by default \u2014 schema always travels either way`
2133
+ },
2134
+ { key: "yes", summary: "Skip the confirmation when seeded rows include non-public columns" },
2135
+ // The comparison's input, and the only reason a bundle path appears on
2136
+ // a command that cannot be cut FROM one. Advertised because it was
2137
+ // always accepted — the parser takes `--bundle` for every command —
2138
+ // and an accepted flag missing from the page is how the comparison
2139
+ // came to be documented by rows that named it and a page that did not.
2140
+ {
2141
+ key: "bundle",
2142
+ summary: "Compare the source against this already-exported bundle instead of compiling the project's entry. The release still carries what is RUNNING"
2143
+ },
2144
+ {
2145
+ key: "entry",
2146
+ summary: "Compare the source against a compile of this entry instead of the project's default one (a nested backend, `--entry=suites/alpha/xano/index.ts`). The release still carries what is RUNNING"
2147
+ },
2148
+ ...COMPILE_COMPARISON_ONLY,
2149
+ ...AUTH
2150
+ ],
2151
+ example: "xanosdk release create v2 --seed=386c35157cc010fb685bdf967258b502"
2152
+ },
2153
+ list: {
2154
+ summary: "Every release in this workspace",
2155
+ flags: [...AUTH]
2156
+ },
2157
+ show: {
2158
+ summary: "One release: where it came from, and what it carries",
2159
+ args: [{ name: "name", required: true }],
2160
+ flags: [...AUTH]
2161
+ },
2162
+ export: {
2163
+ summary: "Write a release out as XanoScript (its `workspace` block is named after the release)",
2164
+ args: [{ name: "name", required: true }],
2165
+ flags: ["path", ...AUTH]
2166
+ },
2167
+ delete: {
2168
+ summary: "Remove a release. Anything running it keeps running",
2169
+ args: [{ name: "name", required: true }],
2170
+ flags: ["yes", ...AUTH]
2171
+ },
2172
+ transfer: {
2173
+ summary: "Copy a stored release to another workspace or instance, checked by content hash",
2174
+ args: [{ name: "name", required: true }],
2175
+ flags: [
2176
+ "to-profile",
2177
+ {
2178
+ key: "dry-run",
2179
+ summary: "Report whether the release is already at the destination, and write nothing"
2180
+ },
2181
+ { key: "yes", summary: "Skip the confirmation (the seeded-table listing still prints)" },
2182
+ ...AUTH
2183
+ ],
2184
+ example: "xanosdk release transfer v2 --to-profile prod"
2185
+ }
2186
+ },
2187
+ example: "xanosdk release create v2"
2188
+ },
2189
+ pull: {
2190
+ group: "Author",
2191
+ display: "pull [source]",
2192
+ summary: "Refresh the backend of this project from a live one \u2014 rewrites the files it decodes, keeps and names files you added, and lists and confirms first",
2193
+ args: [
2194
+ {
2195
+ name: "source",
2196
+ required: false,
2197
+ selector: { accepted: [...BACKEND, "release"], role: "subject", default: "tracked" }
2198
+ }
2199
+ ],
2200
+ // `--yes`, as `env pull` spells the same act: everything it waives is one
2201
+ // meaning — replace local state anyway — and the registry holds each
2202
+ // command to one flag per meaning. The confirmation, uncommitted changes
2203
+ // and a lock that shares no identity with the source are all the same
2204
+ // answer to the same question.
2205
+ flags: [
2206
+ {
2207
+ key: "yes",
2208
+ summary: "Rewrite without asking (required when there is no terminal), over uncommitted changes and a lock that shares no identity with the source too \u2014 files you added are still kept"
2209
+ },
2210
+ "no-secrets",
2211
+ // The shared summary says "act on"; for `pull` the act is a refresh, and
2212
+ // a flag page that does not say what it rewrites is describing a different command.
2213
+ {
2214
+ key: "backend-dir",
2215
+ summary: "The backend directory to refresh (its decoded files are rewritten, files you added are kept), when this project does not keep it in xano/ and nothing on disk says so"
2216
+ },
2217
+ "skip-roundtrip",
2218
+ { key: "branch", summary: "Read this branch of the workspace instead of the live one (`workspace` only)" },
2219
+ ...AUTH
2220
+ ],
2221
+ example: "xanosdk pull release:main"
2222
+ },
2223
+ generate: {
2224
+ group: "Author",
2225
+ display: "generate <source>",
2226
+ summary: "Decode a backend or a bundle .json into a Xano SDK source tree, with no project around it",
2227
+ args: [
2228
+ {
2229
+ name: "source",
2230
+ required: true,
2231
+ path: true,
2232
+ selector: { accepted: [...BACKEND, "release", "file"], role: "subject", default: "none" }
2233
+ }
2234
+ ],
2235
+ flags: [
2236
+ { key: "out", spec: "--out, -o <dir>", summary: "Directory to write the tree into (default: ./xano)" },
2237
+ {
2238
+ key: "force",
2239
+ summary: "Replace a backend tree a decode wrote in --out (keeps .env and .secrets.json; reconciles xano.lock against the source)"
2240
+ },
2241
+ {
2242
+ key: "yes",
2243
+ summary: "With --force, replace files you edited since the last decode without asking (required when there is no terminal)"
2244
+ },
2245
+ { key: "branch", summary: "Read this branch of the workspace instead of the live one (`workspace` only)" },
2246
+ "no-secrets",
2247
+ ...AUTH
2248
+ ],
2249
+ example: "xanosdk generate release:v1 --out ./xano"
2250
+ },
2251
+ promote: {
2252
+ group: "Deploy",
2253
+ display: "promote <release>",
2254
+ summary: "Land a release in your real workspace",
2255
+ args: [{ name: "release", required: true }],
2256
+ // A promote NEVER lands on live, so the shared `--branch` summary ("instead
2257
+ // of the live one") describes the wrong thing here: the flag names the
2258
+ // branch, it does not divert from live. Absent, a label is derived — the
2259
+ // engine's own default is an empty one, which nothing can address.
2260
+ flags: [
2261
+ {
2262
+ key: "branch",
2263
+ summary: "Land on this branch (default: derived from the release name; never live)"
2264
+ },
2265
+ "set-live",
2266
+ "expect-live",
2267
+ {
2268
+ key: "allow-shared-schema-changes",
2269
+ summary: "Land a release that alters tables live serves from (tables are shared by every branch)"
2270
+ },
2271
+ "yes",
2272
+ {
2273
+ key: "entry",
2274
+ summary: "Record the landing in this nested backend's xano.lock, from a directory that is no project"
2275
+ },
2276
+ ...AUTH
2277
+ ],
2278
+ example: "xanosdk promote main"
2279
+ },
2280
+ publish: {
2281
+ group: "Deploy",
2282
+ display: "publish <dir>",
2283
+ summary: "Publish an already-built frontend to a static host \u2014 no compile, no backend import",
2284
+ args: [{ name: "dir", required: true, path: true }],
2285
+ // The destination's own base URL is injected as `window.XANO_HOST`, so the
2286
+ // SAME build published to two destinations serves two different documents.
2287
+ flags: [
2288
+ {
2289
+ key: "to",
2290
+ summary: "Where to publish, instead of the backend this project last deployed to",
2291
+ selector: {
2292
+ accepted: CUT,
2293
+ role: "to",
2294
+ default: "tracked",
2295
+ refused: { "local-engine": "a local engine takes a frontend only through `xanosdk deploy --local-engine --static <dir>`" }
2296
+ }
2297
+ },
2298
+ "release",
2299
+ {
2300
+ key: "branch",
2301
+ summary: "Refuse unless this branch is live on your workspace \u2014 the check that the frontend lands in front of the backend it was built for (--to workspace only)"
2302
+ },
2303
+ "static-env",
2304
+ "static-host",
2305
+ "static-routing",
2306
+ "skip-liveness",
2307
+ { key: "yes", summary: "Skip the confirmation before replacing a workspace's or tenant's frontend" },
2308
+ ...AUTH
2309
+ ],
2310
+ example: "xanosdk publish ./frontend/dist --to workspace --release v2 --branch v2-20260922T120000Z"
2311
+ },
2312
+ tenant: {
2313
+ group: "Environments",
2314
+ display: "tenant <list|get|deploy|delete>",
2315
+ summary: "Your real tenants \u2014 list, inspect, and land a release on one",
2316
+ subcommands: {
2317
+ list: { summary: "Every tenant under this workspace", flags: [...AUTH] },
2318
+ get: {
2319
+ summary: "The URL and state of one tenant",
2320
+ args: [{ name: "name", required: true }],
2321
+ flags: [...AUTH]
2322
+ },
2323
+ deploy: {
2324
+ summary: "Replace what a tenant serves with a release",
2325
+ args: [
2326
+ { name: "name", required: true },
2327
+ { name: "release", required: true }
2328
+ ],
2329
+ flags: ["yes", ...AUTH],
2330
+ example: "xanosdk tenant deploy acme v2"
2331
+ },
2332
+ delete: {
2333
+ summary: "Destroy a tenant and everything it serves",
2334
+ args: [{ name: "name", required: true }],
2335
+ flags: [
2336
+ "yes",
2337
+ {
2338
+ key: "lock",
2339
+ summary: "The xano.lock whose landing record for it is cleared \u2014 default: the project's. A name that is not there any more clears a stale record too"
2340
+ },
2341
+ ...AUTH
2342
+ ]
2343
+ }
2344
+ },
2345
+ example: "xanosdk tenant deploy acme v2"
2346
+ },
2347
+ preflight: {
2348
+ group: "Deploy",
2349
+ display: "preflight <file>",
2350
+ // Says "deploy" in the summary because the name has to keep signalling the
2351
+ // cost: this authenticates, creates a throwaway environment, and imports
2352
+ // into it. `validate` read as a local type-check, which is what people
2353
+ // reached for first and what this is not.
2354
+ summary: "Deploy to a throwaway tenant and verify the round-trip (needs auth)",
2355
+ args: [{ name: "file", required: true, path: true, satisfiedBy: ["bundle"] }],
2356
+ // `...AUTH` is what makes the "(needs auth)" above true for a user who has
2357
+ // only ever run `xanosdk login`: it declares the credential flags, and
2358
+ // `isAuthenticatedCommand` derives from that declaration — so registering
2359
+ // it here is also what gets `--profile` honoured rather than refused.
2360
+ // `--instance` remains the maintainer override and wins over all of it.
2361
+ flags: [
2362
+ "bundle",
2363
+ "runtime",
2364
+ "capture",
2365
+ "verbose",
2366
+ "instance",
2367
+ { key: "out", spec: "--out, -o <dir>", summary: "With --capture: the directory the fixtures land in (default: validate-out)" },
2368
+ ...COMPILE,
2369
+ ...AUTH
2370
+ ],
2371
+ example: "xanosdk preflight ./index.ts --runtime"
2372
+ },
2373
+ // ── Environments ────────────────────────────────────────────────────────
2374
+ workspace: {
2375
+ group: "Environments",
2376
+ display: "workspace",
2377
+ summary: "Your real workspace \u2014 details, export, diff, table resets, and branches",
2378
+ subcommands: {
2379
+ details: {
2380
+ summary: "Which instance and workspace am I bound to?",
2381
+ flags: [...AUTH],
2382
+ example: "xanosdk workspace details"
2383
+ },
2384
+ export: {
2385
+ summary: "Write its bundle JSON",
2386
+ flags: [
2387
+ "path",
2388
+ { key: "name", summary: "Output basename (default: `workspace`)" },
2389
+ { key: "branch", summary: "Export this branch instead of the live one" },
2390
+ ...AUTH
2391
+ ],
2392
+ example: "xanosdk workspace export --branch staging --path -"
2393
+ },
2394
+ diff: {
2395
+ // Named for the question, not the mechanism: "did my release land" is
2396
+ // what a staged branch cannot otherwise answer. The release reports what
2397
+ // it SENT; this reports what is there.
2398
+ summary: "Compare it (or one of its branches) against a local compile \u2014 which objects differ, are missing, or are unexpected. Exits 2 when anything declared differs or is missing",
2399
+ args: [{ name: "file", required: true, path: true, satisfiedBy: ["bundle"] }],
2400
+ flags: [
2401
+ "bundle",
2402
+ { key: "branch", summary: "Compare this branch instead of the live one" },
2403
+ ...COMPILE,
2404
+ ...AUTH
2405
+ ],
2406
+ example: "xanosdk workspace diff ./index.ts --branch staging"
2407
+ },
2408
+ "reset-tables": {
2409
+ // Named for what it does to the DATA, not for the two calls it makes.
2410
+ // "reset" is the promise: afterwards the table holds what the project
2411
+ // says it holds, no more and no less.
2412
+ summary: "Put named tables back to the seed rows your project compiles \u2014 every other table is left alone",
2413
+ // No `--bundle`: an exported bundle carries no seed rows, so there is
2414
+ // nothing in one to reset to. Undeclaring it also keeps a `.json`
2415
+ // positional from being read as one — the command refuses it by name.
2416
+ args: [{ name: "file", required: true, path: true }],
2417
+ flags: ["table", "write", "yes", ...COMPILE, ...AUTH],
2418
+ example: "xanosdk workspace reset-tables ./index.ts --table <guid> --write"
2419
+ },
2420
+ branch: {
2421
+ summary: "List its branches, set one live, or delete one",
2422
+ display: "workspace branch <list|set-live|delete> [label]",
2423
+ args: [
2424
+ // The closed set, so `--help` lists the verbs (and completion offers them).
2425
+ { name: "verb", required: true, values: ["list", "set-live", "delete"] },
2426
+ { name: "label", required: false }
2427
+ ],
2428
+ flags: [
2429
+ "yes",
2430
+ {
2431
+ key: "expect-live",
2432
+ summary: "With set-live: refuse unless <label> is live \u2014 checked before asking and again before switching (not atomic)"
2433
+ },
2434
+ ...AUTH
2435
+ ],
2436
+ example: "xanosdk workspace branch list"
2437
+ }
2438
+ }
2439
+ },
2440
+ ephemeral: {
2441
+ group: "Environments",
2442
+ display: "ephemeral",
2443
+ summary: "Manage ephemeral envs \u2014 list, get, delete, export",
2444
+ subcommands: {
2445
+ list: {
2446
+ summary: "List the ephemeral envs under your workspace",
2447
+ flags: ["all-workspaces", ...AUTH],
2448
+ example: "xanosdk ephemeral list"
2449
+ },
2450
+ get: {
2451
+ summary: "Show one env's URL, status, and expiry",
2452
+ args: [{ name: "name", required: true }],
2453
+ flags: [...AUTH]
2454
+ },
2455
+ delete: {
2456
+ summary: "Tear an env down now instead of waiting for its TTL",
2457
+ args: [{ name: "name", required: true }],
2458
+ flags: ["yes", ...AUTH]
2459
+ },
2460
+ export: {
2461
+ summary: "Write an env's bundle JSON (default: the ephemeral this project deployed to)",
2462
+ args: [{ name: "name", required: false }],
2463
+ flags: ["format", "path", { key: "name", summary: "Output basename (default: the env name)" }, ...AUTH]
2464
+ }
2465
+ }
2466
+ },
2467
+ "local-engine": {
2468
+ group: "Environments",
2469
+ display: "local-engine",
2470
+ // The handles that ship with `deploy --local-engine`: a local engine has no
2471
+ // TTL and nothing reclaims it, and its binary is never on `PATH`, so these
2472
+ // verbs are the only way to see or stop one (`impersonate local-engine`
2473
+ // opens one, like any other backend).
2474
+ summary: "See, authenticate against and stop local engines on this machine; move the project's engine pin and manage cached engine versions",
2475
+ subcommands: {
2476
+ list: {
2477
+ summary: "List local engines on this machine, marking the ones xanosdk started",
2478
+ example: "xanosdk local-engine list"
2479
+ },
2480
+ token: {
2481
+ // The engine's meta API accepts only its own bearer, and no summary
2482
+ // carries it — so this verb is the only way a suite gets one. Bare on
2483
+ // stdout even when piped, because `$(…)` is the form it exists for.
2484
+ summary: "Print a local engine's meta API bearer \u2014 the local XANO_META_TOKEN; `--json` adds its url and workspace id. Re-run after a restart, which re-mints it (default: the engine this project deployed to)",
2485
+ args: [{ name: "name", required: false }],
2486
+ example: "XANO_META_TOKEN=$(xanosdk local-engine token)"
2487
+ },
2488
+ stop: {
2489
+ // The name is optional because `--all` stands in for it — and `--all`
2490
+ // is the form most runs want, since it covers every project.
2491
+ summary: "Stop one local engine by name, or every one xanosdk started on this machine",
2492
+ args: [{ name: "name", required: true, satisfiedBy: ["all"] }],
2493
+ flags: [
2494
+ {
2495
+ key: "all",
2496
+ summary: "Every engine xanosdk started on this machine, across projects (foreign ones are reported, not stopped)"
2497
+ }
2498
+ ],
2499
+ example: "xanosdk local-engine stop --all"
2500
+ },
2501
+ update: {
2502
+ // Running it IS the confirmation, so it never prompts — the deploy only
2503
+ // offers a newer engine; this is the verb that takes it.
2504
+ summary: "Move this project's pinned engine to the latest release (or `--version <v>`, downgrades included), download it, and restart the project's running engine on it \u2014 the restarted engine starts empty, so the next deploy seeds it. Writes package.json: commit it",
2505
+ flags: [
2506
+ {
2507
+ key: "engine-version",
2508
+ summary: "Pin this engine version instead of the latest, like v0.1.5 \u2014 or `latest`, the default"
2509
+ }
2510
+ ],
2511
+ example: "xanosdk local-engine update"
2512
+ },
2513
+ cache: {
2514
+ // One verb with an action argument, not two top-level verbs: both act on
2515
+ // the same cached binaries under the engine cache.
2516
+ summary: "`list`: each cached engine version, its size on disk, and the engines running on it. `clear`: remove every cached engine and the runtime they unpacked, or one with `--version <v>` \u2014 any engine running on a removed version is stopped first; the next deploy fetches and restarts it",
2517
+ args: [{ name: "action", required: true, values: ["list", "clear"] }],
2518
+ flags: [
2519
+ {
2520
+ key: "engine-version",
2521
+ summary: "`clear` only: remove just this cached version \u2014 v0.1.5, `latest` (the release `update` would pin), `override`, or an override's `src-\u2026` id from `cache list`"
2522
+ },
2523
+ {
2524
+ key: "legacy-runtime",
2525
+ summary: "`clear` only: remove instead the runtime copy earlier versions unpacked in your own cache directory (`cache list` shows it); asks first"
2526
+ },
2527
+ { key: "yes", summary: "Skip the `--legacy-runtime` confirmation (required when there is no terminal)" }
2528
+ ],
2529
+ example: "xanosdk local-engine cache clear --version v0.1.5"
2530
+ }
2531
+ }
2532
+ },
2533
+ test: {
2534
+ group: "Environments",
2535
+ display: "test",
2536
+ summary: "Run the unit and workflow tests an environment carries",
2537
+ subcommands: {
2538
+ list: {
2539
+ summary: "List the tests in an environment, without running any",
2540
+ flags: [TEST_LIST_ON, "kind", ...AUTH],
2541
+ example: "xanosdk test list --on workspace"
2542
+ },
2543
+ run: {
2544
+ summary: "Run one test by name",
2545
+ args: [{ name: "name", required: true }],
2546
+ flags: [TEST_ON, ...AUTH],
2547
+ example: 'xanosdk test run "happy path" --on workspace'
2548
+ },
2549
+ "run-all": {
2550
+ summary: "Run every test in an environment and report pass/fail",
2551
+ flags: [TEST_ON, "kind", "concurrency", ...AUTH],
2552
+ example: "xanosdk test run-all --on ephemeral:pr-3"
2553
+ }
2554
+ }
2555
+ },
2556
+ tables: {
2557
+ group: "Environments",
2558
+ display: "tables [backend]",
2559
+ // How the guids `release create --seed` takes are obtained at all: they
2560
+ // appear in no artifact a user holds, and names cannot substitute (see
2561
+ // `TableSummary.name`). One verb for every running backend rather than a
2562
+ // copy under each noun, so bare follows what the project last deployed to.
2563
+ // The caveat rides in the SUMMARY rather than in the output: a line printed
2564
+ // on every run becomes furniture, and `--json` is a data channel.
2565
+ summary: `List a backend's tables with their guids, for \`release create --seed\` (default: the backend this project last deployed to). ${GUID_STABILITY_NOTE}`,
2566
+ args: [
2567
+ {
2568
+ name: "backend",
2569
+ required: false,
2570
+ selector: {
2571
+ accepted: BACKEND,
2572
+ role: "subject",
2573
+ default: "tracked",
2574
+ refused: {
2575
+ release: "a release is not a running backend \u2014 list the backend it was cut from, or land it and list that"
2576
+ }
2577
+ }
2578
+ }
2579
+ ],
2580
+ flags: [...AUTH],
2581
+ example: "xanosdk tables ephemeral:pr-3"
2582
+ },
2583
+ impersonate: {
2584
+ group: "Environments",
2585
+ display: "impersonate [backend]",
2586
+ // One verb for every backend a session can be minted for, so every kind
2587
+ // prints one JSON shape and bare opens what the project last deployed to.
2588
+ // The workspace is refused: it opens from the Xano dashboard as whoever is
2589
+ // signed in, so there is no session to mint.
2590
+ summary: "Open a backend's dashboard in the builder as a scoped session \u2014 the url carries it, so treat it as a credential (default: the backend this project last deployed to)",
2591
+ args: [
2592
+ {
2593
+ name: "backend",
2594
+ required: false,
2595
+ selector: {
2596
+ accepted: ["ephemeral", "local-engine", "tenant"],
2597
+ role: "subject",
2598
+ default: "tracked",
2599
+ refused: {
2600
+ workspace: "your workspace opens from the Xano dashboard as whoever is signed in, so there is no session to mint",
2601
+ release: "a release is not a running backend \u2014 land it with `xanosdk deploy release:<name>` and open that"
2602
+ }
2603
+ }
2604
+ }
2605
+ ],
2606
+ flags: [
2607
+ { key: "guest", summary: "Mint a read-only guest session (browse only)" },
2608
+ "url-only",
2609
+ ...AUTH
2610
+ ],
2611
+ example: "xanosdk impersonate --guest"
2612
+ },
2613
+ // ── Account ─────────────────────────────────────────────────────────────
2614
+ login: {
2615
+ group: "Account",
2616
+ display: "login",
2617
+ summary: "OAuth sign-in \u2014 shared cache, or --local per project",
2618
+ flags: [
2619
+ "local",
2620
+ "paste",
2621
+ "port",
2622
+ "scope",
2623
+ "origin",
2624
+ "config",
2625
+ { key: "force", summary: "Overwrite the cached credential \u2014 sign in again even when one is already there" }
2626
+ ],
2627
+ example: "xanosdk login --local"
2628
+ },
2629
+ logout: {
2630
+ group: "Account",
2631
+ display: "logout",
2632
+ summary: "Revoke the active profile and remove it from the credential file",
2633
+ flags: ["all", "yes", "local", "config"],
2634
+ example: "xanosdk logout --profile staging"
2635
+ },
2636
+ status: {
2637
+ group: "Account",
2638
+ display: "status",
2639
+ summary: "Who am I, which workspace, and the env this project last deployed to",
2640
+ flags: [...AUTH],
2641
+ // Where a profile that is not stored is said: a typed one is a refusal, a
2642
+ // pinned one is state the report carries (E2E pass 21 — documented, not changed).
2643
+ notes: "A typed --profile that is not stored exits 8; one this project pins (xano.profile.json, $XANO_PROFILE) is reported as not signed in, exit 0.",
2644
+ example: "xanosdk status --json # \u2192 { signedIn, signIn, instance, profile, user, workspace, environment }"
2645
+ },
2646
+ whoami: {
2647
+ group: "Account",
2648
+ display: "whoami",
2649
+ summary: "Show the signed-in user and instance URL",
2650
+ flags: [...AUTH],
2651
+ example: "xanosdk whoami"
2652
+ },
2653
+ // `whoami` is the canonical spelling for the QUESTION — it is the word every
2654
+ // other CLI answers it under. `profile` is the noun that owns the stored
2655
+ // credentials themselves, and its verbs manage them.
2656
+ profile: {
2657
+ group: "Account",
2658
+ display: "profile <verb>",
2659
+ summary: "Manage stored credential profiles",
2660
+ subcommands: {
2661
+ list: {
2662
+ summary: "Every stored profile, with the default and the active one marked",
2663
+ flags: [...CREDENTIAL_FILE],
2664
+ example: "xanosdk profile list"
2665
+ },
2666
+ show: {
2667
+ summary: "What one profile addresses \u2014 never its token (default: the active one)",
2668
+ args: [{ name: "name", required: false }],
2669
+ flags: [...CREDENTIAL_FILE],
2670
+ example: "xanosdk profile show staging"
2671
+ },
2672
+ // `use` and `set-default` differ only in SCOPE and sit one keystroke
2673
+ // apart, so each summary says which — the output does too.
2674
+ use: {
2675
+ summary: "Pin THIS PROJECT to a profile, in a committed xano.profile.json",
2676
+ args: [{ name: "name", required: true }],
2677
+ flags: [...CREDENTIAL_FILE],
2678
+ example: "xanosdk profile use staging"
2679
+ },
2680
+ "set-default": {
2681
+ summary: "Set the profile THIS MACHINE falls back to when nothing else selects one",
2682
+ args: [{ name: "name", required: true }],
2683
+ flags: [...CREDENTIAL_FILE],
2684
+ example: "xanosdk profile set-default prod"
2685
+ },
2686
+ add: {
2687
+ summary: "Store a meta API token credential under a name \u2014 the token is read from piped stdin or the terminal, and checked against the instance",
2688
+ args: [{ name: "name", required: true }],
2689
+ flags: [
2690
+ { key: "instance", summary: "Instance URL the meta API token addresses" },
2691
+ "workspace-id",
2692
+ { key: "force", summary: "Replace a profile that already exists under this name" },
2693
+ ...CREDENTIAL_FILE
2694
+ ],
2695
+ example: "xanosdk profile add ci --instance https://x8ki.xano.io --workspace-id 7"
2696
+ },
2697
+ delete: {
2698
+ summary: "Remove a profile, revoking its sign-in session \u2014 a meta API token stays valid until revoked at its source",
2699
+ args: [{ name: "name", required: true }],
2700
+ flags: ["yes", ...CREDENTIAL_FILE],
2701
+ example: "xanosdk profile delete staging --yes"
2702
+ }
2703
+ }
2704
+ },
2705
+ // ── Maintenance ─────────────────────────────────────────────────────────
2706
+ lock: {
2707
+ group: "Maintenance",
2708
+ display: "lock",
2709
+ summary: "Maintain xano.lock identities \u2014 rename, prune, import",
2710
+ subcommands: {
2711
+ rename: {
2712
+ summary: "Move an entry keeping its identity, so the next export renames in place",
2713
+ args: [
2714
+ { name: "kind", required: true },
2715
+ { name: "old", required: true },
2716
+ { name: "new", required: true }
2717
+ ],
2718
+ flags: [
2719
+ { key: "lock", summary: "Name the xano.lock to edit \u2014 default: beside --entry or the project entry" },
2720
+ "entry"
2721
+ ],
2722
+ example: "xanosdk lock rename --entry=xano/index.ts table users members"
2723
+ },
2724
+ prune: {
2725
+ summary: "Drop orphaned entries (all, or just the named keys)",
2726
+ args: [
2727
+ // `--entry=<path>` names the same file; with it, every positional is a key.
2728
+ { name: "entry-file", required: true, path: true, satisfiedBy: ["identity-only", "entry"] },
2729
+ { name: "keys\u2026", required: false, variadic: true }
2730
+ ],
2731
+ flags: [
2732
+ "yes",
2733
+ "lock",
2734
+ { key: "entry", summary: "The entry file as a flag, in place of <entry-file> \u2014 every positional is then a key" },
2735
+ {
2736
+ key: "identity-only",
2737
+ summary: "Prune the named keys without loading the entry file"
2738
+ }
2739
+ ],
2740
+ example: "xanosdk lock prune ./index.ts --yes"
2741
+ },
2742
+ // `import`, not `adopt`: the verb names where the identities COME FROM,
2743
+ // which is the only thing a reader needs in order to know whether this is
2744
+ // the command they want. "Adopt" described the internal effect and left
2745
+ // the input — a live export — entirely unstated.
2746
+ import: {
2747
+ summary: "Import identities from a live backend's exported bundle (`xanosdk workspace export`), so existing objects are not recreated",
2748
+ args: [{ name: "bundle.json", required: true, path: true }],
2749
+ flags: [
2750
+ "yes",
2751
+ { key: "lock", summary: "Name the xano.lock to write \u2014 default: beside --entry or the project entry" },
2752
+ "entry"
2753
+ ],
2754
+ example: "xanosdk lock import ./live.json --entry=xano/index.ts"
2755
+ }
2756
+ }
2757
+ },
2758
+ completion: {
2759
+ group: "Maintenance",
2760
+ display: "completion <shell>",
2761
+ summary: "Print a shell completion script (bash, zsh, fish)",
2762
+ args: [{ name: "shell", required: true, values: ["bash", "zsh", "fish"] }],
2763
+ example: 'xanosdk completion zsh > "${fpath[1]}/_xanosdk"'
2764
+ },
2765
+ version: {
2766
+ group: "Maintenance",
2767
+ display: "version",
2768
+ summary: "Print the CLI version"
2769
+ },
2770
+ upgrade: {
2771
+ group: "Maintenance",
2772
+ display: "upgrade",
2773
+ summary: "Install the latest @xano/sdk, or report an available upgrade with --check",
2774
+ flags: ["check"],
2775
+ example: "xanosdk upgrade --check"
2776
+ },
2777
+ help: {
2778
+ group: "Maintenance",
2779
+ display: "help",
2780
+ summary: "Show this help",
2781
+ // Variadic: a help target is a command PATH (`help workspace export`), and
2782
+ // `resolveHelpRequest` reads it from the raw argv before any arity check.
2783
+ args: [{ name: "command", required: false, variadic: true }],
2784
+ example: "xanosdk help deploy"
2785
+ }
2786
+ };
2787
+ function isCommand(name) {
2788
+ return Object.hasOwn(COMMANDS, name);
2789
+ }
2790
+ function getCommand(name) {
2791
+ return isCommand(name) ? COMMANDS[name] : void 0;
2792
+ }
2793
+ function acceptsFlag(command, subcommand, key) {
2794
+ return flagRefFor(command, subcommand, key) !== void 0;
2795
+ }
2796
+ function flagRefFor(command, subcommand, key) {
2797
+ if (command === void 0) return void 0;
2798
+ const spec = subcommand === void 0 ? getCommand(command) : getSubcommand(command, subcommand);
2799
+ return (spec?.flags ?? []).find((f) => flagKey(f) === key);
2800
+ }
2801
+ function getSubcommand(command, sub) {
2802
+ const subs = getCommand(command)?.subcommands;
2803
+ return subs && Object.hasOwn(subs, sub) ? subs[sub] : void 0;
2804
+ }
2805
+ function liveCommandNames() {
2806
+ return Object.entries(COMMANDS).filter(([, spec]) => spec.aliasOf === void 0).map(([name]) => name);
2807
+ }
2808
+ function flagNames() {
2809
+ return Object.keys(FLAGS);
2810
+ }
2811
+ function flagKey(ref) {
2812
+ return typeof ref === "string" ? ref : ref.key;
2813
+ }
2814
+ function flagSpec(ref) {
2815
+ if (typeof ref !== "string" && ref.spec !== void 0) return ref.spec;
2816
+ return FLAGS[flagKey(ref)].spec;
2817
+ }
2818
+ function flagSummary(ref) {
2819
+ if (typeof ref === "string") return FLAGS[ref].summary;
2820
+ if (ref.selector !== void 0) return `${ref.summary}: ${sourceSpellings(ref.selector.accepted)}`;
2821
+ return ref.summary;
2822
+ }
2823
+ function selectorValues(selector) {
2824
+ return SELECTOR_BARE.filter((k) => selector.accepted.includes(k));
2825
+ }
2826
+ var SELECTOR_BARE = ["workspace", "ephemeral", "local-engine"];
2827
+ function argValues(arg) {
2828
+ if (arg.values !== void 0) return arg.values;
2829
+ return arg.selector !== void 0 ? selectorValues(arg.selector) : void 0;
2830
+ }
2831
+ function flagValues(ref) {
2832
+ if (typeof ref !== "string" && ref.values !== void 0) return ref.values;
2833
+ if (typeof ref !== "string" && ref.selector !== void 0) return selectorValues(ref.selector);
2834
+ return FLAGS[flagKey(ref)]?.values;
2835
+ }
2836
+ function flagValuesClosed(ref) {
2837
+ if (typeof ref !== "string" && ref.values !== void 0) return true;
2838
+ if (typeof ref !== "string" && ref.selector !== void 0) return ref.selector.accepted.every((k) => k === "workspace");
2839
+ return FLAGS[flagKey(ref)]?.open !== true;
2840
+ }
2841
+ function publishedFlagValues(ref) {
2842
+ const values = flagValues(ref);
2843
+ if (values === void 0 || values.length === 0) return {};
2844
+ return flagValuesClosed(ref) ? { values: [...values] } : { examples: [...values] };
2845
+ }
2846
+ function liveSubcommandNames(command) {
2847
+ const subs = getCommand(command)?.subcommands;
2848
+ if (!subs) return [];
2849
+ return Object.entries(subs).filter(([, spec]) => spec.unreleased === void 0).map(([name]) => name);
2850
+ }
2851
+ function visibleFlags(spec) {
2852
+ const hidden = spec.unreleasedFlags;
2853
+ if (!spec.flags || !hidden || hidden.length === 0) return spec.flags;
2854
+ return spec.flags.filter((ref) => !hidden.includes(flagKey(ref)));
2855
+ }
2856
+ function selectorSpellings(command, subcommand) {
2857
+ if (command === void 0) return [];
2858
+ const spec = subcommand === void 0 ? getCommand(command) : getSubcommand(command, subcommand);
2859
+ const flags = (spec?.flags ?? []).filter((f) => typeof f !== "string" && f.selector !== void 0).map((f) => `\`--${flagKey(f)}\``);
2860
+ if (flags.length > 0) return flags;
2861
+ const positional = (spec?.args ?? []).find((a) => a.selector !== void 0);
2862
+ return positional === void 0 ? [] : [`its \`<${positional.name}>\` argument`];
2863
+ }
2864
+ function structuredFlag(ref) {
2865
+ const m = /^(--[a-z][a-z-]*)(?:, (-[a-z]))?(.*)$/.exec(flagSpec(ref));
2866
+ const name = m?.[1] ?? `--${flagKey(ref)}`;
2867
+ const arg = (m?.[3] ?? "").trim();
2868
+ return {
2869
+ name,
2870
+ ...m?.[2] === void 0 ? {} : { short: m[2] },
2871
+ ...arg === "" ? {} : { arg },
2872
+ ...publishedFlagValues(ref),
2873
+ description: flagSummary(ref)
2874
+ };
2875
+ }
2876
+ function helpDocument(request) {
2877
+ const flags = (spec2) => (visibleFlags(spec2) ?? []).map((ref) => ({ flag: flagSpec(ref), summary: flagSummary(ref), ...structuredFlag(ref) }));
2878
+ const spec = request.command === void 0 ? void 0 : getCommand(request.command);
2879
+ if (spec === void 0 || request.command === void 0) {
2880
+ return {
2881
+ commands: liveCommandNames().map((name) => {
2882
+ const c = getCommand(name);
2883
+ return { name, usage: c.display, summary: c.summary, subcommands: liveSubcommandNames(name) };
2884
+ })
2885
+ };
2886
+ }
2887
+ const sub = request.subcommand === void 0 ? void 0 : getSubcommand(request.command, request.subcommand);
2888
+ if (sub !== void 0) {
2889
+ return {
2890
+ command: request.command,
2891
+ subcommand: request.subcommand,
2892
+ summary: sub.summary,
2893
+ flags: flags(sub),
2894
+ ...sub.example === void 0 ? {} : { example: sub.example }
2895
+ };
2896
+ }
2897
+ return {
2898
+ command: request.command,
2899
+ usage: spec.display,
2900
+ summary: spec.summary,
2901
+ flags: flags(spec),
2902
+ subcommands: liveSubcommandNames(request.command).map((name) => ({ name, summary: spec.subcommands[name].summary })),
2903
+ ...spec.example === void 0 ? {} : { example: spec.example }
2904
+ };
2905
+ }
2906
+
2907
+ export {
2908
+ setRunNameContext,
2909
+ checkOneName,
2910
+ CUT_KINDS,
2911
+ EXIT_SOURCE_UNRESOLVABLE,
2912
+ BARE,
2913
+ isKindShaped,
2914
+ sourceSpellings,
2915
+ parseSource,
2916
+ verbBackendName,
2917
+ isBackendHandle,
2918
+ renderArgs,
2919
+ HELP_GROUP_ORDER,
2920
+ FLAGS,
2921
+ GLOBAL_FLAGS,
2922
+ isAuthenticatedCommand,
2923
+ takesProfileFlag,
2924
+ REFUSES_EMPTY_ENV,
2925
+ REFUSES_EMPTY_DOC_TOKEN,
2926
+ GUID_STABILITY_NOTE,
2927
+ tablesCommand,
2928
+ COMMANDS,
2929
+ isCommand,
2930
+ getCommand,
2931
+ acceptsFlag,
2932
+ flagRefFor,
2933
+ getSubcommand,
2934
+ liveCommandNames,
2935
+ flagNames,
2936
+ flagKey,
2937
+ flagSpec,
2938
+ flagSummary,
2939
+ selectorValues,
2940
+ argValues,
2941
+ flagValues,
2942
+ flagValuesClosed,
2943
+ publishedFlagValues,
2944
+ liveSubcommandNames,
2945
+ visibleFlags,
2946
+ selectorSpellings,
2947
+ structuredFlag,
2948
+ helpDocument,
2949
+ relForwardSlash,
2950
+ pathsShownFrom,
2951
+ displayPath,
2952
+ setTypedCwd,
2953
+ pastePath,
2954
+ projectFileCli,
2955
+ spellProjectCli,
2956
+ projectSdkDir,
2957
+ spellProjectSdkDir,
2958
+ installedCliAt,
2959
+ cliPrefixAt,
2960
+ withCliPrefix,
2961
+ installCliPrefix,
2962
+ isMachineOutput,
2963
+ jsonWarning,
2964
+ mergeJsonWarnings,
2965
+ interruptedRunFinished,
2966
+ writeJson,
2967
+ interruptDocumentText,
2968
+ interruptedRunWroteDocument,
2969
+ interruptedRunDocumentExitCode,
2970
+ noteRunWarning,
2971
+ runWarnings,
2972
+ noteRunAccepted,
2973
+ runAccepted,
2974
+ setRunFailureExplainer,
2975
+ explainRunFailure,
2976
+ inJsonDocumentScope,
2977
+ installStdoutPipeGuard,
2978
+ style,
2979
+ stderrStyle,
2980
+ stdoutStyle,
2981
+ safeText,
2982
+ quotedNames,
2983
+ withoutUrls,
2984
+ terminalText,
2985
+ printHuman,
2986
+ formatTableListing,
2987
+ formatFields,
2988
+ step,
2989
+ success,
2990
+ error,
2991
+ warn,
2992
+ info,
2993
+ detail,
2994
+ link,
2995
+ blank,
2996
+ elapsedSuffix,
2997
+ spinner,
2998
+ clearProgress,
2999
+ withSpinner,
3000
+ formatExpiration,
3001
+ describeWriteTarget,
3002
+ discloseWriteTarget,
3003
+ credentialWriteTarget,
3004
+ writeTargetPayload,
3005
+ backendDestinationPayload,
3006
+ hostLabel,
3007
+ EXIT_OUTCOME_UNKNOWN,
3008
+ registerOperation,
3009
+ activeOperation,
3010
+ renderGlobalHelp,
3011
+ renderHelpFor,
3012
+ indentBlock,
3013
+ statesOutcomeUnknown,
3014
+ UsageError,
3015
+ LocalFileNotFoundError,
3016
+ CliError,
3017
+ isUsageError,
3018
+ unknownCommand,
3019
+ unknownHelpTopic,
3020
+ unknownSubcommand,
3021
+ suggestVerb,
3022
+ unknownFlag,
3023
+ flagName,
3024
+ extraArguments,
3025
+ envSetArgumentsRefused,
3026
+ missingArgument,
3027
+ reportFailure,
3028
+ failureWritesDocument,
3029
+ failureError,
3030
+ failureCode,
3031
+ exitCodeOf,
3032
+ processExitCode,
3033
+ movedVerb,
3034
+ installCliDiagnosticSink
3035
+ };
3036
+ //# sourceMappingURL=chunk-PTHVMXZI.js.map