@xano/sdk 1.0.6 → 1.0.7

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 (215) hide show
  1. package/CHANGELOG.md +20 -5
  2. package/README.md +30 -4
  3. package/dist/.build-fingerprint +1 -1
  4. package/dist/{agent-file-refresh-67QIX45H.js → agent-file-refresh-DGGSRPJ4.js} +12 -12
  5. package/dist/agent-skill-command-37DFYS7Q.js +414 -0
  6. package/dist/{answer-shape-UCDUKPAN.js → answer-shape-RBFDCNZ7.js} +4 -4
  7. package/dist/{backend-dir-3LIL6SCT.js → backend-dir-KDD43X7K.js} +14 -14
  8. package/dist/{backend-slot-JREP27UD.js → backend-slot-TBOVZXDE.js} +3 -3
  9. package/dist/bin.js +48 -47
  10. package/dist/{branch-2IPHOAYS.js → branch-7PIKNUD7.js} +11 -10
  11. package/dist/{branch-commands-KTKAXBAN.js → branch-commands-EGY7ZEZE.js} +23 -22
  12. package/dist/bundle.js +4 -4
  13. package/dist/{chunk-GWTFI3GA.js → chunk-26LHXLD3.js} +2 -2
  14. package/dist/{chunk-ENMBEXOP.js → chunk-2ACWDSAQ.js} +3 -3
  15. package/dist/{chunk-GOLFAEUV.js → chunk-2SD4LA22.js} +2 -2
  16. package/dist/{chunk-GZHLCUZ6.js → chunk-2XWVZRL6.js} +7 -7
  17. package/dist/{chunk-IF4PEGVD.js → chunk-2YER2J47.js} +11 -11
  18. package/dist/{chunk-N5I37JFB.js → chunk-3FRGNBOC.js} +2 -2
  19. package/dist/{chunk-YKP4ZKVO.js → chunk-46PATL23.js} +3 -3
  20. package/dist/{chunk-QJM5XZ4K.js → chunk-47XT6WQL.js} +8 -8
  21. package/dist/{chunk-AWQ7BQTQ.js → chunk-4GPIOIAC.js} +6 -1
  22. package/dist/{chunk-ND43ZOS3.js → chunk-567KK6XF.js} +7 -7
  23. package/dist/{chunk-EQFYOOO6.js → chunk-5GIOCDUM.js} +829 -893
  24. package/dist/{chunk-TTEIDD5Q.js → chunk-5SCPRXFB.js} +4 -4
  25. package/dist/{chunk-LAOMN6QQ.js → chunk-5ZG7V2VW.js} +3 -3
  26. package/dist/{chunk-JXVJGF3Y.js → chunk-7M6JP3FS.js} +2 -2
  27. package/dist/{chunk-JFBRXRJD.js → chunk-7XXWKTCE.js} +36 -36
  28. package/dist/{chunk-PL7AIAWS.js → chunk-A4R5CAY4.js} +4 -111
  29. package/dist/{chunk-SPKA2LV6.js → chunk-AKERAUNH.js} +4 -4
  30. package/dist/{chunk-26MOFAJT.js → chunk-ARWMVNDJ.js} +6 -3
  31. package/dist/{chunk-I3VHW6XM.js → chunk-B2URJBC4.js} +18 -18
  32. package/dist/{chunk-A7MRZ4GF.js → chunk-B3P25SDP.js} +4 -4
  33. package/dist/chunk-BRANWM4U.js +853 -0
  34. package/dist/{chunk-CHINR7WD.js → chunk-BSVQEKHO.js} +4 -4
  35. package/dist/{chunk-UD2Z7K6W.js → chunk-BZ6WTG3E.js} +4 -4
  36. package/dist/{chunk-D7BUMOKU.js → chunk-CH23ONYG.js} +76 -5
  37. package/dist/{chunk-763M6LX3.js → chunk-CNZASQPL.js} +2 -2
  38. package/dist/{chunk-TECTL2NU.js → chunk-CPN6WSBH.js} +4 -4
  39. package/dist/{chunk-5YQV35C2.js → chunk-CT3J5JRZ.js} +7 -7
  40. package/dist/{chunk-YYC2DZMG.js → chunk-D5OZRJ3T.js} +6 -6
  41. package/dist/{chunk-XFBGXB7X.js → chunk-DG3APBUJ.js} +149 -97
  42. package/dist/chunk-DIWF7L33.js +995 -0
  43. package/dist/{chunk-RIN4YY34.js → chunk-DXZTL7NA.js} +95 -58
  44. package/dist/{chunk-PMMHSX4H.js → chunk-EF4MHLEW.js} +4 -4
  45. package/dist/{chunk-ZDP6GDAB.js → chunk-ELPQTDW6.js} +101 -93
  46. package/dist/{chunk-Q22BMRPF.js → chunk-EPFDY5JU.js} +2 -2
  47. package/dist/{chunk-ZJSTUD6D.js → chunk-EU32BC5B.js} +8 -8
  48. package/dist/{chunk-3BBIDW3Y.js → chunk-FDTET7FZ.js} +3 -3
  49. package/dist/{chunk-YYLUBYXM.js → chunk-FENA7K7C.js} +3 -3
  50. package/dist/{chunk-QZEAANWP.js → chunk-GHMLRFRX.js} +8 -8
  51. package/dist/{chunk-MBDFH7XB.js → chunk-H2K4GFUS.js} +3 -3
  52. package/dist/{chunk-U35MTOXQ.js → chunk-HTQWAQRW.js} +3 -3
  53. package/dist/{chunk-ROY4YAEQ.js → chunk-HU7F56VF.js} +22 -2
  54. package/dist/{chunk-2FLIJGBZ.js → chunk-HZ6ADG3O.js} +47 -8
  55. package/dist/{chunk-GLY552SI.js → chunk-I6XRUU6U.js} +54 -54
  56. package/dist/{chunk-KPFS3RGM.js → chunk-IPNN2KRW.js} +3 -3
  57. package/dist/{chunk-LD6ARK3A.js → chunk-JOOKM7AH.js} +2 -2
  58. package/dist/{chunk-6X6BJN6Y.js → chunk-JOWY6HFL.js} +3 -3
  59. package/dist/{chunk-UIVMR7UK.js → chunk-JX6N73H3.js} +2 -2
  60. package/dist/{chunk-JRVQ7M7W.js → chunk-L472YIGG.js} +8 -8
  61. package/dist/{chunk-YR2I5HGE.js → chunk-L6HZ67P6.js} +2 -2
  62. package/dist/chunk-LCOCRJ4K.js +116 -0
  63. package/dist/{chunk-3EDSPMXN.js → chunk-LJM5CIY4.js} +5 -1
  64. package/dist/{chunk-NPODGBVJ.js → chunk-M2C54ZBC.js} +4 -4
  65. package/dist/{chunk-QXYMDARD.js → chunk-M3NEK3LT.js} +4 -4
  66. package/dist/{chunk-BL3AZ3AP.js → chunk-MBL7CXJ7.js} +2 -2
  67. package/dist/{chunk-7GAIJW62.js → chunk-MYZRMSPM.js} +2 -2
  68. package/dist/{chunk-GHQ4BVI4.js → chunk-N3YFCFCO.js} +13 -13
  69. package/dist/{chunk-M5CSVB23.js → chunk-NDJAKSE7.js} +11 -8
  70. package/dist/{chunk-Z4ZGTCCD.js → chunk-NV37YGOV.js} +6 -6
  71. package/dist/{chunk-GW5RHGOB.js → chunk-O56DQKPL.js} +9 -9
  72. package/dist/{chunk-U6MTGB46.js → chunk-ORGNLQN6.js} +5 -5
  73. package/dist/{chunk-I3H3HCPY.js → chunk-PEIBGH2V.js} +33 -30
  74. package/dist/{chunk-5TVFLG3C.js → chunk-PEX4QZVI.js} +2 -2
  75. package/dist/{chunk-HCG7NDIL.js → chunk-PV25BDCH.js} +5 -5
  76. package/dist/{chunk-VDHA5SSQ.js → chunk-PY722CHR.js} +2 -2
  77. package/dist/{chunk-VW4CWVYX.js → chunk-QGIZLFAS.js} +4 -4
  78. package/dist/{chunk-SSITMX7I.js → chunk-QRQ54LUI.js} +16 -14
  79. package/dist/{chunk-OIKLDDYC.js → chunk-RBU2YX22.js} +3 -3
  80. package/dist/{chunk-EADVVTDK.js → chunk-RRMH7WMY.js} +7 -7
  81. package/dist/{chunk-WZHLMU6T.js → chunk-S46ODQRA.js} +2 -2
  82. package/dist/{chunk-SPITRSOF.js → chunk-SDGV76HF.js} +2 -2
  83. package/dist/{chunk-ATJ2W7DC.js → chunk-SGK3PTTM.js} +281 -121
  84. package/dist/{chunk-3II44CUJ.js → chunk-TWVUYS63.js} +24 -24
  85. package/dist/{chunk-2WBH5HUY.js → chunk-U5M7T6CI.js} +7 -7
  86. package/dist/{chunk-6X3MY2JP.js → chunk-UYFUIHH3.js} +2 -2
  87. package/dist/{chunk-IMELQ2I6.js → chunk-V7MBRUK6.js} +3 -3
  88. package/dist/{chunk-NDWVJ2QZ.js → chunk-VAGSKUWC.js} +3 -3
  89. package/dist/{chunk-WBH4KJWM.js → chunk-VIJ5D3RC.js} +3 -3
  90. package/dist/{chunk-ITC2R2OT.js → chunk-VNDR2T35.js} +7 -7
  91. package/dist/{chunk-IXFJORNH.js → chunk-WNCW2RNB.js} +4 -4
  92. package/dist/{chunk-BTVUYHWV.js → chunk-WUEPP5HD.js} +4 -4
  93. package/dist/{local-engine-command-RYLGMQ2O.js → chunk-YCUDOF6Q.js} +22 -77
  94. package/dist/{chunk-YGLMRH5U.js → chunk-YH2JVJAO.js} +12 -12
  95. package/dist/{chunk-PFBXSVZF.js → chunk-ZGLNHA7T.js} +7 -7
  96. package/dist/{chunk-CCU5CCRX.js → chunk-ZJOAWRED.js} +8 -8
  97. package/dist/{chunk-FU3VCE5A.js → chunk-ZXRDD3Q2.js} +13 -9
  98. package/dist/cli.d.ts +25 -4
  99. package/dist/cli.js +45 -42
  100. package/dist/{codegen-command-R5IASBFC.js → codegen-command-T7TC7PQO.js} +58 -57
  101. package/dist/{commands-H7CPMMHH.js → commands-JDENTDJS.js} +2 -2
  102. package/dist/{completion-W5ZAI6TN.js → completion-YFD5OVJW.js} +8 -4
  103. package/dist/{config-MZ5KG4EP.js → config-YJFUTRJW.js} +7 -7
  104. package/dist/{deploy-command-34T2LKQ5.js → deploy-command-OEVEE6UG.js} +50 -49
  105. package/dist/{deploy-source-YLQ7WMYR.js → deploy-source-HYVZEYXV.js} +33 -32
  106. package/dist/{dev-env-sync-TMJTNU3U.js → dev-env-sync-EFDCJ6KU.js} +48 -47
  107. package/dist/{display-name-hint-ZJGFNJKQ.js → display-name-hint-SW3GB3V7.js} +13 -12
  108. package/dist/{emit-D125xxty.d.ts → emit-Dov_92kn.d.ts} +1 -1
  109. package/dist/{env-example-refresh-CQP3ZMKM.js → env-example-refresh-WNSOH534.js} +59 -58
  110. package/dist/{env-pull-command-UTG6IC2K.js → env-pull-command-UYEXMQ3P.js} +43 -42
  111. package/dist/{env-target-FZROWYFS.js → env-target-JBSLBKNX.js} +12 -11
  112. package/dist/{env-var-command-VYDBQJJW.js → env-var-command-BJNRAXNV.js} +49 -48
  113. package/dist/{ephemeral-BIE6FMJV.js → ephemeral-CEOGMIEA.js} +10 -9
  114. package/dist/{ephemeral-command-OZ26RGXF.js → ephemeral-command-IPSGBCS5.js} +61 -60
  115. package/dist/{ephemeral-state-SNZOX2YK.js → ephemeral-state-MTBASPRS.js} +10 -9
  116. package/dist/{generate-command-4HR7MR36.js → generate-command-XQXODBS6.js} +73 -71
  117. package/dist/{gitignore-EWQBXNX2.js → gitignore-RUVCIZO4.js} +18 -18
  118. package/dist/{impersonate-command-WC7OGKUM.js → impersonate-command-MA27O7S5.js} +41 -40
  119. package/dist/{import-7Z4GCCPO.js → import-XKRFHABE.js} +4 -4
  120. package/dist/index.d.ts +4 -4
  121. package/dist/{init-command-HAO3WXH3.js → init-command-6RDTCMAB.js} +61 -46
  122. package/dist/{init-modules-NSKD4ASY.js → init-modules-DHTBOCQT.js} +7 -7
  123. package/dist/{init-web-MKFFOQUU.js → init-web-ELBXSXDL.js} +2 -2
  124. package/dist/internal.d.ts +4 -4
  125. package/dist/internal.js +1 -1
  126. package/dist/{keep-data-merge-QR2TMKEO.js → keep-data-merge-TDJOIAVT.js} +23 -23
  127. package/dist/{lambda-config-reconcile-7FJXXV6V.js → lambda-config-reconcile-47X5C2E4.js} +6 -5
  128. package/dist/{landing-record-MWXFIRCP.js → landing-record-TPPYFQAS.js} +21 -21
  129. package/dist/{local-engine-choice-VD5LNXJU.js → local-engine-choice-S6VHPJRU.js} +36 -35
  130. package/dist/local-engine-command-4EZCGZ6M.js +85 -0
  131. package/dist/{local-engine-config-W3KB7RWM.js → local-engine-config-2EBL3QKA.js} +3 -2
  132. package/dist/{local-engine-deploy-6O7NKZCA.js → local-engine-deploy-FOPNWU7X.js} +17 -15
  133. package/dist/local-engine-lookup-GM3E3NPP.js +43 -0
  134. package/dist/local-engine-mcp-bridge-QKZHUGW3.js +423 -0
  135. package/dist/local-engine-mcp-command-BFQVLXZC.js +181 -0
  136. package/dist/{local-engine-process-ZLLZEIRF.js → local-engine-process-XUQPQENQ.js} +11 -8
  137. package/dist/{local-engine-state-OCW5YDD7.js → local-engine-state-JQPKGB65.js} +4 -3
  138. package/dist/{local-engine-update-check-LVX4HBBI.js → local-engine-update-check-S7UF6ZF5.js} +6 -5
  139. package/dist/{lock-commands-X2OECR4R.js → lock-commands-HJ6Y5QVS.js} +51 -50
  140. package/dist/{login-command-RLLKD565.js → login-command-JO55NZAS.js} +32 -32
  141. package/dist/{logout-command-XDMSXCDO.js → logout-command-MPRIRSJA.js} +15 -14
  142. package/dist/{marketplace-command-2NHHY2X3.js → marketplace-command-BM6G257N.js} +33 -33
  143. package/dist/{marketplace-resolve-OTZYT4FG.js → marketplace-resolve-AWH3RG57.js} +5 -5
  144. package/dist/{meta-client-TMHVBZFY.js → meta-client-AOSWODQQ.js} +13 -12
  145. package/dist/{module-manifest-FNMW23IX.js → module-manifest-GXI46PEF.js} +3 -3
  146. package/dist/node.d.ts +4 -4
  147. package/dist/node.js +50 -49
  148. package/dist/{operation-outcome-RN62735X.js → operation-outcome-4UKPXTNC.js} +25 -23
  149. package/dist/{output-target-MOLCTPBP.js → output-target-RAZ4KN5J.js} +19 -19
  150. package/dist/{plan-disclosure-CY7AF6KP.js → plan-disclosure-JR52DWXN.js} +13 -12
  151. package/dist/{plugin-contributions-WR26U7NT.js → plugin-contributions-E6XHLQWK.js} +5 -5
  152. package/dist/{plugin-prompt-ZUYQQIX4.js → plugin-prompt-IODX5EU6.js} +4 -4
  153. package/dist/{plugin-questions-HAZOQ67R.js → plugin-questions-AAAJ7POP.js} +3 -3
  154. package/dist/{preflight-command-OHJXYND3.js → preflight-command-7GKJBWOQ.js} +52 -51
  155. package/dist/{profile-command-6JWT2BTL.js → profile-command-CM6J7E2M.js} +33 -33
  156. package/dist/{profile-pointer-PDA5XBIB.js → profile-pointer-KTYXL6FU.js} +4 -3
  157. package/dist/{project-dependency-GZWWGWEW.js → project-dependency-OQ5575QQ.js} +6 -6
  158. package/dist/{project-sdk-3W72H5QO.js → project-sdk-2ESHHZVL.js} +3 -3
  159. package/dist/{promote-command-UYAMUXKB.js → promote-command-BDRPG6UU.js} +68 -67
  160. package/dist/{prompt-U37K5RPQ.js → prompt-MQPGU4ZI.js} +3 -3
  161. package/dist/{publish-command-BUS27HGB.js → publish-command-IEMYZ7LF.js} +55 -54
  162. package/dist/{pull-command-ZGUNP27P.js → pull-command-S5E2ABZ4.js} +61 -60
  163. package/dist/{pull-superseded-EZBGYRZF.js → pull-superseded-E34BZVLH.js} +3 -3
  164. package/dist/{release-command-BQ6OHS3P.js → release-command-7F5TBKO2.js} +58 -57
  165. package/dist/{release-ns-command-ATGVBVIU.js → release-ns-command-EK2ZQ4CC.js} +84 -83
  166. package/dist/{retry-command-QJ57WVW7.js → retry-command-GL5HCMVB.js} +9 -8
  167. package/dist/{routes-manifest-file-UALYSZLY.js → routes-manifest-file-LCIKPDAG.js} +5 -5
  168. package/dist/scaffold.js +4 -4
  169. package/dist/secrets-IV4N5HYI.js +20 -0
  170. package/dist/{secrets-file-LMS7KX3E.js → secrets-file-LXREYU3M.js} +18 -18
  171. package/dist/{secrets-fill-command-QNBDGCGM.js → secrets-fill-command-QHZS3KWM.js} +49 -48
  172. package/dist/{seed-SZ6OS5DQ.js → seed-FRKMDN2Z.js} +4 -4
  173. package/dist/{source-resolve-MKLNYFWG.js → source-resolve-BBHYTOXI.js} +23 -21
  174. package/dist/{static-host-ONEHA4LI.js → static-host-7LC7OZR4.js} +4 -4
  175. package/dist/{status-command-XKIFKBGM.js → status-command-TY253MJT.js} +52 -51
  176. package/dist/{store-Bg4Na6Sm.d.ts → store-Boba9OOh.d.ts} +1 -1
  177. package/dist/{store-X6ZH7EC3.js → store-VJ3OS6VO.js} +7 -6
  178. package/dist/{sync-contributions-HNVHDIQW.js → sync-contributions-63542VE4.js} +9 -9
  179. package/dist/{sync-record-PRXHLK4S.js → sync-record-RGHK7EAL.js} +13 -12
  180. package/dist/{table-DC36QA4Y.js → table-OAYGFGEN.js} +5 -5
  181. package/dist/{tables-command-UQLKTELN.js → tables-command-PZIVDAH3.js} +38 -37
  182. package/dist/{tenant-EKNQGG5A.js → tenant-Y3II4VY3.js} +11 -10
  183. package/dist/{tenant-command-2LWP2MPB.js → tenant-command-G6XON7CF.js} +86 -85
  184. package/dist/{test-command-IU5MBBXY.js → test-command-3FZOX7O3.js} +41 -40
  185. package/dist/{tests-RG2Y5EQ4.js → tests-KF6N6BZ7.js} +5 -5
  186. package/dist/{token-7AWSJLKO.js → token-DJJUW5HY.js} +11 -10
  187. package/dist/{toolchain-hooks-4ZMQLBPQ.js → toolchain-hooks-7PWCFLSU.js} +4 -4
  188. package/dist/{toolchain-modules-VU7SURVJ.js → toolchain-modules-OTNSKK52.js} +4 -4
  189. package/dist/{toolchain-peers-CIDNEEQV.js → toolchain-peers-KQ7TQ2AR.js} +7 -7
  190. package/dist/{tracked-backend-4BHSV7NC.js → tracked-backend-AJCGTO5Y.js} +36 -35
  191. package/dist/{update-check-A7FXIINW.js → update-check-4E5L6GAW.js} +46 -45
  192. package/dist/{upgrade-command-C5KBITFI.js → upgrade-command-BXMSQN4C.js} +52 -49
  193. package/dist/{whoami-command-7WQII2H4.js → whoami-command-NLCCIEUM.js} +14 -13
  194. package/dist/{workspace-Z46PUZNI.js → workspace-PNMJOXE4.js} +4 -4
  195. package/dist/{workspace-binding-JE6YNDZJ.js → workspace-binding-J5GWDFRI.js} +13 -12
  196. package/dist/{workspace-command-FC4IMLAE.js → workspace-command-MHIIY352.js} +79 -78
  197. package/dist/{workspace-env-N4ZPFT6A.js → workspace-env-LLRWCHSA.js} +15 -15
  198. package/dist/{workspace-export-3A5BZTPS.js → workspace-export-BIKAYHWJ.js} +4 -4
  199. package/dist/{writable-D7KCZI5N.js → writable-UOTO4WWC.js} +3 -3
  200. package/dist/{xanosdk-import-P2A2KSXM.js → xanosdk-import-S7A3CVBN.js} +5 -5
  201. package/dist/{xanosdk-project-6AGMW2SL.js → xanosdk-project-J4VCFRHP.js} +15 -15
  202. package/guides/README.md +2 -2
  203. package/guides/cli.md +69 -0
  204. package/guides/codegen.md +23 -5
  205. package/guides/codes.md +1 -0
  206. package/guides/coverage.md +5 -0
  207. package/guides/deploying.md +28 -0
  208. package/guides/scaffold.md +61 -10
  209. package/llms-full.txt +1 -1
  210. package/llms.txt +1 -1
  211. package/manifest.json +63 -5
  212. package/package.json +5 -2
  213. package/skills/xano-backend/SKILL.md +119 -0
  214. package/dist/chunk-LL7SGTRC.js +0 -663
  215. package/dist/chunk-M6ZFSTIZ.js +0 -630
@@ -3,29 +3,30 @@ import {
3
3
  } from "./chunk-LBJA7IEM.js";
4
4
  import {
5
5
  questionOrCancel
6
- } from "./chunk-JXVJGF3Y.js";
6
+ } from "./chunk-7M6JP3FS.js";
7
7
  import {
8
8
  ensureWorkspaceEnvGitignored
9
- } from "./chunk-UD2Z7K6W.js";
9
+ } from "./chunk-BZ6WTG3E.js";
10
10
  import {
11
11
  readVersion
12
- } from "./chunk-XFBGXB7X.js";
12
+ } from "./chunk-DG3APBUJ.js";
13
13
  import {
14
14
  WORKSPACE_ENV_EXAMPLE_FILE,
15
15
  renderWorkspaceEnvExample
16
- } from "./chunk-HCG7NDIL.js";
16
+ } from "./chunk-PV25BDCH.js";
17
17
  import {
18
18
  parseSlot,
19
19
  requireBackendSlot
20
- } from "./chunk-VDHA5SSQ.js";
20
+ } from "./chunk-PY722CHR.js";
21
21
  import {
22
+ MERGED_IN_EXISTING,
22
23
  XANO_DIR,
23
24
  changedOnDisk,
24
- decideOverwrite,
25
+ describeClash,
26
+ existingProjectClashes,
25
27
  isNonEmptyDir,
26
- plannedAgentsMd,
27
28
  scaffoldProject
28
- } from "./chunk-LL7SGTRC.js";
29
+ } from "./chunk-DIWF7L33.js";
29
30
  import {
30
31
  inProject,
31
32
  installModules,
@@ -33,7 +34,7 @@ import {
33
34
  preflightPackages,
34
35
  rebaseLocalSpec,
35
36
  renderXanoIndexWithModules
36
- } from "./chunk-YYC2DZMG.js";
37
+ } from "./chunk-D5OZRJ3T.js";
37
38
  import {
38
39
  npmViewVersion
39
40
  } from "./chunk-ZFDZKNGG.js";
@@ -42,11 +43,14 @@ import {
42
43
  } from "./chunk-FWD7AL6N.js";
43
44
  import {
44
45
  isLocalSpecifier
45
- } from "./chunk-QJM5XZ4K.js";
46
+ } from "./chunk-47XT6WQL.js";
46
47
  import {
47
48
  readToolchainBlock,
48
49
  readToolchainConfig
49
50
  } from "./chunk-DXUICABI.js";
51
+ import {
52
+ statusLabel
53
+ } from "./chunk-L6HZ67P6.js";
50
54
  import {
51
55
  detectInstallRoot,
52
56
  detectPackageManager,
@@ -58,24 +62,29 @@ import {
58
62
  localPathOf,
59
63
  packageNameOf,
60
64
  readInstalledManifestState
61
- } from "./chunk-763M6LX3.js";
62
- import {
63
- statusLabel
64
- } from "./chunk-YR2I5HGE.js";
65
+ } from "./chunk-CNZASQPL.js";
65
66
  import {
66
67
  readEnvVar
67
68
  } from "./chunk-X2NL4KUO.js";
68
69
  import {
69
70
  DEFAULT_FRAMEWORK,
70
71
  FRAMEWORKS,
71
- NODE_MIN,
72
72
  allFrontendPresets,
73
+ findFrontendPreset
74
+ } from "./chunk-BRANWM4U.js";
75
+ import {
76
+ BACKEND_TSCONFIG_PATH,
77
+ ICON_LIBRARIES,
78
+ NODE_MIN,
73
79
  checkJobDir,
74
80
  checkWorkflowName,
75
81
  checkWorkflowPath,
76
- findFrontendPreset,
77
82
  initLanding,
83
+ mergeGitignore,
78
84
  renderApiTs,
85
+ renderBackendPackageJson,
86
+ renderBackendReadme,
87
+ renderBackendTsconfig,
79
88
  renderCheckWorkflow,
80
89
  renderCnUtil,
81
90
  renderEnvExample,
@@ -91,13 +100,14 @@ import {
91
100
  renderViteConfig,
92
101
  renderXanoExampleMd,
93
102
  renderXanoIndex,
94
- resolveFrameworkFlag,
103
+ resolveIconsFlag,
95
104
  sdkDep
96
- } from "./chunk-EQFYOOO6.js";
105
+ } from "./chunk-5GIOCDUM.js";
97
106
  import {
98
- ICON_LIBRARIES,
99
- resolveIconsFlag
100
- } from "./chunk-M6ZFSTIZ.js";
107
+ composeBlock,
108
+ gitattributesSpec,
109
+ upsertBlock
110
+ } from "./chunk-LJM5CIY4.js";
101
111
  import {
102
112
  UsageError,
103
113
  blank,
@@ -120,7 +130,7 @@ import {
120
130
  unknownFlag,
121
131
  warn,
122
132
  writeJson
123
- } from "./chunk-D7BUMOKU.js";
133
+ } from "./chunk-CH23ONYG.js";
124
134
  import {
125
135
  suggest
126
136
  } from "./chunk-UTI5G6OJ.js";
@@ -235,6 +245,8 @@ async function resolveThemeChoice(args) {
235
245
  }
236
246
 
237
247
  // src/emit/frontend-resolve.ts
248
+ var NO_FRONTEND = "none";
249
+ var FRAMEWORK_CHOICES = [...FRAMEWORKS, NO_FRONTEND];
238
250
  function defaultFrontendPreset() {
239
251
  const preset = findFrontendPreset(DEFAULT_FRAMEWORK);
240
252
  if (preset === void 0) {
@@ -242,6 +254,10 @@ function defaultFrontendPreset() {
242
254
  }
243
255
  return preset;
244
256
  }
257
+ function isNoFrontend(token) {
258
+ const t = token.trim().toLowerCase();
259
+ return t === NO_FRONTEND || t === "no frontend";
260
+ }
245
261
  async function promptFramework() {
246
262
  const presets = allFrontendPresets();
247
263
  const rl = createInterface({ input: process.stdin, output: process.stderr });
@@ -250,6 +266,7 @@ async function promptFramework() {
250
266
  `
251
267
  Which frontend framework?
252
268
  ` + presets.map((p, i) => ` ${i + 1}) ${p.label}${p.id === DEFAULT_FRAMEWORK ? " (default)" : ""}`).join("\n") + `
269
+ ${presets.length + 1}) No frontend (the backend only)
253
270
  `
254
271
  );
255
272
  const answer = await questionOrCancel(rl, `Enter a number or name, or leave blank for the default: `);
@@ -259,13 +276,24 @@ Which frontend framework?
259
276
  if (Number.isInteger(byIndex) && byIndex >= 1 && byIndex <= presets.length) {
260
277
  return presets[byIndex - 1];
261
278
  }
279
+ if (byIndex === presets.length + 1 || isNoFrontend(token)) return null;
262
280
  return findFrontendPreset(token) ?? defaultFrontendPreset();
263
281
  } finally {
264
282
  rl.close();
265
283
  }
266
284
  }
285
+ function resolveFrameworkValue(flag) {
286
+ if (isNoFrontend(flag)) return null;
287
+ return flagValue(flag, FRAMEWORK_CHOICES, () => {
288
+ const preset = findFrontendPreset(flag);
289
+ if (preset === void 0) {
290
+ throw new Error(`Unknown --framework "${flag}". Valid values: ${FRAMEWORK_CHOICES.join(", ")}.`);
291
+ }
292
+ return preset;
293
+ });
294
+ }
267
295
  async function resolveFrontendPreset(flag) {
268
- if (flag !== void 0 && flag !== "") return flagValue(flag, FRAMEWORKS, () => resolveFrameworkFlag(flag));
296
+ if (flag !== void 0 && flag !== "") return resolveFrameworkValue(flag);
269
297
  if (process.stdin.isTTY && process.stderr.isTTY) return promptFramework();
270
298
  return defaultFrontendPreset();
271
299
  }
@@ -432,12 +460,78 @@ function projectShellFiles(vars, preset, parts, choice = defaultThemeChoice(), c
432
460
  ...preset.files(vars, parts.landing, choice)
433
461
  ]);
434
462
  }
463
+ function backendShellFiles(vars, shell, contributions = {}, existingXanoSdk) {
464
+ const backend = [
465
+ { path: BACKEND_TSCONFIG_PATH, content: renderBackendTsconfig() },
466
+ { path: "xano/lambdas/tsconfig.json", content: renderLambdaTsconfig("backend") }
467
+ ];
468
+ const manifest = {
469
+ path: "package.json",
470
+ content: withXanoSdkBlock(
471
+ renderBackendPackageJson(vars),
472
+ contributions.xanosdk,
473
+ shell.kind === "existing" ? void 0 : existingXanoSdk
474
+ )
475
+ };
476
+ if (shell.kind === "existing") {
477
+ return spelledForProject(vars, [
478
+ manifest,
479
+ ...backend,
480
+ ...moduleTypeMarker(shell.dir),
481
+ // The line-ending rule, scoped to `xano/`: a `*` rule at the project's
482
+ // root would renormalize every file the project already has.
483
+ { path: `${XANO_DIR}/.gitattributes`, content: renderGitattributes() },
484
+ ...moduleGitattributes(shell.dir, contributions.gitattributes ?? []),
485
+ ...gitignoreBlock(shell.dir, vars.sdkVersion)
486
+ ]);
487
+ }
488
+ return spelledForProject(vars, [
489
+ manifest,
490
+ ...backend,
491
+ { path: ".gitignore", content: renderGitignore() },
492
+ { path: ".gitattributes", content: renderGitattributes(contributions.gitattributes) },
493
+ { path: checkWorkflowPath(vars.install), content: renderCheckWorkflow(vars.install) },
494
+ { path: "README.md", content: shell.readme }
495
+ ]);
496
+ }
497
+ function moduleTypeMarker(dir) {
498
+ let manifest;
499
+ try {
500
+ manifest = JSON.parse(readFileSync2(join(dir, "package.json"), "utf8"));
501
+ } catch {
502
+ return [];
503
+ }
504
+ if (manifest?.type === "module") return [];
505
+ return [{ path: `${XANO_DIR}/package.json`, content: `${JSON.stringify({ type: "module" }, null, 2)}
506
+ ` }];
507
+ }
508
+ function gitignoreBlock(dir, version) {
509
+ const path = join(dir, ".gitignore");
510
+ const existing = existsSync(path) ? readFileSync2(path, "utf8") : null;
511
+ const merged = mergeGitignore(existing, version);
512
+ return merged === existing ? [] : [{ path: ".gitignore", content: merged }];
513
+ }
514
+ function moduleGitattributes(dir, contributions) {
515
+ if (contributions.length === 0) return [];
516
+ const path = join(dir, ".gitattributes");
517
+ let text = existsSync(path) ? readFileSync2(path, "utf8") : "";
518
+ for (const { pkg, version, lines } of contributions) {
519
+ const spec = gitattributesSpec(pkg);
520
+ text = upsertBlock(text, spec, composeBlock(spec, lines, version)).text;
521
+ }
522
+ return [{ path: ".gitattributes", content: text }];
523
+ }
435
524
  function spelledForProject(vars, files) {
436
525
  return files.map((f) => ({ ...f, content: spellProjectSdkDir(spellProjectCli(f.content, vars.cli), vars.sdkDir) }));
437
526
  }
438
- function buildFileSet(vars, preset, choice, contributions = {}, existingXanoSdk) {
527
+ function buildFileSet(targetDir, vars, preset, mode, choice, contributions = {}, existingXanoSdk) {
439
528
  return [
440
- ...projectShellFiles(
529
+ ...preset === null ? backendShellFiles(
530
+ vars,
531
+ mode === "new" ? { kind: "new", readme: renderBackendReadme(vars) } : { kind: "existing", dir: targetDir },
532
+ contributions,
533
+ existingXanoSdk
534
+ ) : projectShellFiles(
441
535
  vars,
442
536
  preset,
443
537
  { readme: renderReadme(vars, preset, choice), landing: initLanding(vars) },
@@ -488,14 +582,41 @@ function rejectPullOnlyFlags(args) {
488
582
  { helpFor: { command: "init" } }
489
583
  );
490
584
  }
491
- function decideScaffoldTarget(targetDir, force) {
492
- const decided = decideOverwrite(targetDir, { force, regenerable: false });
493
- if (decided === "refuse") {
494
- throw new UsageError(
495
- `Target directory ${targetDir} is not empty. ` + (process.stdin.isTTY === true ? `Re-run with --force to scaffold into it anyway.` : `Re-run with --force --yes to scaffold into it anyway (--yes confirms the overwrite, which cannot be asked without a terminal).`)
496
- );
585
+ function frontendOnlyFlags(args) {
586
+ return [
587
+ ...args.theme !== void 0 ? ["--theme"] : [],
588
+ ...args.radius !== void 0 ? ["--radius"] : [],
589
+ ...args.dark !== void 0 ? ["--dark"] : [],
590
+ ...args.font !== void 0 ? ["--font"] : [],
591
+ ...args.fontMono !== void 0 ? ["--font-mono"] : [],
592
+ ...args.fontHeading !== void 0 ? ["--font-heading"] : [],
593
+ ...args.icons !== void 0 ? ["--icons"] : []
594
+ ];
595
+ }
596
+ function refuseFrontendOnlyFlags(args, why) {
597
+ const passed = frontendOnlyFlags(args);
598
+ if (passed.length === 0) return;
599
+ const one = passed.length === 1;
600
+ throw new UsageError(
601
+ `${passed.join(", ")} ${one ? "applies" : "apply"} only with a frontend, and ${why}. Drop ${one ? "it" : "them"}.`,
602
+ { helpFor: { command: "init" } }
603
+ );
604
+ }
605
+ async function resolveInitFrontend(args, targetDir, mode) {
606
+ if (mode === "existing") {
607
+ if (args.framework !== void 0 && resolveFrameworkValue(args.framework) !== null) {
608
+ throw new UsageError(
609
+ `\`--framework ${args.framework}\` writes a new frontend, and ${targetDir} is not empty: an existing app gets the backend only. Drop --framework to add the backend to it, or run init in an empty directory for a full app.`,
610
+ { helpFor: { command: "init" } }
611
+ );
612
+ }
613
+ refuseFrontendOnlyFlags(args, `${targetDir} is an existing project, which gets the backend only`);
614
+ return null;
497
615
  }
498
- return decided;
616
+ if (args.framework === void 0) return void 0;
617
+ const preset = resolveFrameworkValue(args.framework);
618
+ if (preset === null) refuseFrontendOnlyFlags(args, `\`--framework ${NO_FRONTEND}\` writes none`);
619
+ return preset;
499
620
  }
500
621
  function readLockEntryCount(targetDir) {
501
622
  const path = join(targetDir, LOCK_REL);
@@ -507,32 +628,43 @@ function readLockEntryCount(targetDir) {
507
628
  return 0;
508
629
  }
509
630
  }
510
- async function confirmForcedOverwrite(targetDir, files, args, agents) {
511
- const agentsMd = plannedAgentsMd(targetDir, {
512
- agentsMd: !args.noAgentsMd,
513
- appName: agents.appName,
514
- regenerable: false,
515
- sdkVersion: readVersion(),
516
- frontend: agents.frontend,
517
- theme: agents.theme
518
- });
519
- const changed = changedOnDisk(targetDir, agentsMd === void 0 ? files : [...files, agentsMd]);
520
- if (changed.length === 0) return true;
521
- warn(
522
- `init --force overwrites ${changed.length} file${changed.length === 1 ? "" : "s"} already in ${targetDir}:`,
523
- "init.overwrite",
524
- [...changed.slice(0, 30), ...changed.length > 30 ? [`\u2026 and ${changed.length - 30} more`] : []]
525
- );
526
- if (args.yes === true) return true;
527
- const { confirm } = await import("./prompt-U37K5RPQ.js");
528
- const { yesRerun } = await import("./retry-command-QJ57WVW7.js");
631
+ async function settleClashes(targetDir, files, args) {
632
+ const clashes = existingProjectClashes(targetDir, files);
633
+ if (clashes.length === 0) return [];
634
+ const one = clashes.length === 1;
635
+ if (!args.force) {
636
+ throw new UsageError(
637
+ `init adds the backend to ${targetDir}, and ${one ? "this clashes" : `these ${clashes.length} clash`} with what is already there:
638
+ ${clashes.map((c) => ` ${describeClash(c)}`).join("\n")}
639
+ Nothing was written. ` + (process.stdin.isTTY === true ? `Re-run with --force to write over ${one ? "it" : "them"}.` : `Re-run with --force --yes to write over ${one ? "it" : "them"} (--yes confirms the overwrite, which cannot be asked without a terminal).`)
640
+ );
641
+ }
642
+ const scripts = clashes.flatMap((c) => c.kind === "script" ? [c.name] : []);
643
+ const changed = changedOnDisk(targetDir, files.filter((f) => !MERGED_IN_EXISTING.has(f.path)));
644
+ const listed = [...changed, ...clashes.filter((c) => c.kind === "script").map(describeClash)];
645
+ if (listed.length === 0) return scripts;
646
+ const counted = [
647
+ ...changed.length === 0 ? [] : [`${changed.length} file${changed.length === 1 ? "" : "s"}`],
648
+ ...scripts.length === 0 ? [] : [`${scripts.length} script${scripts.length === 1 ? "" : "s"}`]
649
+ ].join(" and ");
650
+ warn(`init --force overwrites ${counted} already in ${targetDir}:`, "init.overwrite", [
651
+ ...listed.slice(0, 30),
652
+ ...listed.length > 30 ? [`\u2026 and ${listed.length - 30} more`] : []
653
+ ]);
654
+ if (args.yes === true) return scripts;
655
+ const { confirm } = await import("./prompt-MQPGU4ZI.js");
656
+ const { yesRerun } = await import("./retry-command-GL5HCMVB.js");
529
657
  const { rerun, note } = yesRerun(args, "init");
658
+ const noun = scripts.length === 0 ? "file" : changed.length === 0 ? "script" : "file and script";
530
659
  const ok = await confirm(
531
- `Overwrite ${changed.length === 1 ? "this file" : `these ${changed.length} files`} in ${targetDir}?`,
532
- { flag: "--yes", refusal: { details: { written: false, files: changed }, rerun, note } }
660
+ `Overwrite ${listed.length === 1 ? `this ${noun}` : `these ${listed.length} ${noun === "file and script" ? "files and scripts" : `${noun}s`}`} in ${targetDir}?`,
661
+ { flag: "--yes", refusal: { details: { written: false, files: listed }, rerun, note } }
533
662
  );
534
- if (!ok) info("Cancelled. Nothing was written.");
535
- return ok;
663
+ if (!ok) {
664
+ info("Cancelled. Nothing was written.");
665
+ return "cancelled";
666
+ }
667
+ return scripts;
536
668
  }
537
669
  function renderMinimalPackageJson(appName, sdkVersion) {
538
670
  return `${JSON.stringify(
@@ -596,7 +728,7 @@ async function runInitCommand(args) {
596
728
  }
597
729
  const source = resolveFromSource(args.from);
598
730
  if (source.kind === "file") await refuseUnknownProfileFlag(args, resolve(args.positionals[0] ?? "."));
599
- const { runInitFromCommand } = await import("./codegen-command-R5IASBFC.js");
731
+ const { runInitFromCommand } = await import("./codegen-command-T7TC7PQO.js");
600
732
  return runInitFromCommand(args, source);
601
733
  }
602
734
  rejectPullOnlyFlags(args);
@@ -604,10 +736,11 @@ async function runInitCommand(args) {
604
736
  const targetDir = resolve(targetArg);
605
737
  await refuseUnknownProfileFlag(args, targetDir);
606
738
  const appName = sanitizeAppName(args.name ?? basename(targetDir));
739
+ const mode = isNonEmptyDir(targetDir) ? "existing" : "new";
607
740
  const existingXanoSdk = readToolchainBlock(targetDir);
608
741
  const typedModules = parseMarketplaceFlag(args.marketplace);
609
- if (args.framework !== void 0) await resolveFrontendPreset(args.framework);
610
- await resolveThemeChoice(args);
742
+ const flagFrontend = await resolveInitFrontend(args, targetDir, mode);
743
+ if (flagFrontend !== null) await resolveThemeChoice(args);
611
744
  const unclaimable = args.unknownFlags.filter((f) => {
612
745
  const name = flagName(f);
613
746
  if (!name.startsWith("--")) return true;
@@ -615,10 +748,10 @@ async function runInitCommand(args) {
615
748
  return flagNames().includes(bare) || bare.startsWith("no-") && flagNames().includes(bare.slice(3));
616
749
  });
617
750
  if (unclaimable.length > 0) throw unknownFlag(unclaimable, { command: "init" });
618
- const { refusePlugAndPlay } = await import("./project-dependency-GZWWGWEW.js");
619
- const { retryCommand } = await import("./retry-command-QJ57WVW7.js");
751
+ const { refusePlugAndPlay } = await import("./project-dependency-OQ5575QQ.js");
752
+ const { retryCommand } = await import("./retry-command-GL5HCMVB.js");
620
753
  refusePlugAndPlay(targetDir, retryCommand(args, { command: "init" }).command);
621
- const { resolveMarketplaceSpecs, withCatalogueRerun } = await import("./marketplace-resolve-OTZYT4FG.js");
754
+ const { resolveMarketplaceSpecs, withCatalogueRerun } = await import("./marketplace-resolve-AWH3RG57.js");
622
755
  const resolvedModules = typedModules.length === 0 ? [] : await resolveMarketplaceSpecs(typedModules, "xanosdk init --marketplace").catch(async (err) => {
623
756
  throw await withCatalogueRerun(err, args, "init");
624
757
  });
@@ -627,50 +760,45 @@ async function runInitCommand(args) {
627
760
  if (requestedModules.length > 0) preflightPackages(requestedModules, targetDir);
628
761
  const deferredModules = args.noInstall ? requestedModules : [];
629
762
  const modules = args.noInstall ? [] : requestedModules;
630
- let overwrite;
631
763
  let moduleOutcome;
632
- const forcedOver = args.force && isNonEmptyDir(targetDir);
633
764
  const hadLock = readLockEntryCount(targetDir);
634
- let earlyPreset;
765
+ let overrideScripts;
766
+ const settle = async () => mode === "existing" ? settleClashes(
767
+ targetDir,
768
+ buildFileSet(targetDir, { appName, sdkVersion: readVersion() }, null, mode, defaultThemeChoice(), {}, existingXanoSdk),
769
+ args
770
+ ) : [];
635
771
  let passOne;
636
772
  if (modules.length > 0) {
637
- overwrite = decideScaffoldTarget(targetDir, args.force);
638
- if (forcedOver) {
639
- earlyPreset = await resolveFrontendPreset(args.framework);
640
- const earlyTheme = await resolveThemeChoice(args);
641
- const provisional = buildFileSet(
642
- { appName, sdkVersion: readVersion() },
643
- earlyPreset,
644
- earlyTheme,
645
- { gitattributes: [], xanosdk: {} },
646
- existingXanoSdk
647
- );
648
- const agents = { appName, frontend: earlyPreset, theme: earlyTheme };
649
- if (!await confirmForcedOverwrite(targetDir, provisional, args, agents)) return;
650
- }
773
+ const settled = await settle();
774
+ if (settled === "cancelled") return;
775
+ overrideScripts = settled;
651
776
  passOne = snapshotForRollback(targetDir);
652
777
  mkdirSync(targetDir, { recursive: true });
653
- writeFileSync(
654
- join(targetDir, "package.json"),
655
- renderMinimalPackageJson(appName, readVersion()),
656
- "utf8"
657
- );
778
+ if (mode === "new" || !existsSync(join(targetDir, "package.json"))) {
779
+ writeFileSync(
780
+ join(targetDir, "package.json"),
781
+ renderMinimalPackageJson(appName, readVersion()),
782
+ "utf8"
783
+ );
784
+ }
658
785
  blank();
659
786
  moduleOutcome = await installModules(targetDir, modules);
660
787
  if (moduleOutcome.toolchain.length > 0) {
661
- const { addToolchainPeers } = await import("./toolchain-peers-CIDNEEQV.js");
788
+ const { addToolchainPeers } = await import("./toolchain-peers-KQ7TQ2AR.js");
662
789
  const rerun = retryCommand(args, { command: "init" }).command;
663
790
  for (const pkg of moduleOutcome.toolchain) await addToolchainPeers(targetDir, pkg, rerun);
664
791
  }
665
792
  }
666
793
  let scaffolded = false;
667
794
  try {
668
- const { discoverToolchainPlugins } = await import("./toolchain-modules-VU7SURVJ.js");
795
+ const { discoverToolchainPlugins } = await import("./toolchain-modules-OTNSKK52.js");
669
796
  const toolchain = await discoverToolchainPlugins(targetDir, { frozen: false, configuring: true });
670
- const preset = earlyPreset ?? await resolveFrontendPreset(args.framework);
797
+ const preset = flagFrontend !== void 0 ? flagFrontend : await resolveFrontendPreset(args.framework);
798
+ if (preset === null && flagFrontend === void 0) refuseFrontendOnlyFlags(args, "no frontend was chosen");
671
799
  const choice = await resolveThemeChoice(args);
672
- const { pluginPrompter } = await import("./plugin-prompt-ZUYQQIX4.js");
673
- const { contributionOutcomes, recordedConfig, runPluginQuestionnaire } = await import("./plugin-contributions-WR26U7NT.js");
800
+ const { pluginPrompter } = await import("./plugin-prompt-IODX5EU6.js");
801
+ const { contributionOutcomes, recordedConfig, runPluginQuestionnaire } = await import("./plugin-contributions-E6XHLQWK.js");
674
802
  const { answers: pluginAnswers } = await runPluginQuestionnaire(toolchain.loaded, {
675
803
  host: "init",
676
804
  unknownFlags: args.unknownFlags,
@@ -689,12 +817,14 @@ async function runInitCommand(args) {
689
817
  if (record !== void 0) pluginConfig[outcome.pkg] = record;
690
818
  }
691
819
  const vars = templateVarsFor(appName, targetDir);
692
- overwrite ??= decideScaffoldTarget(targetDir, args.force);
693
- const fileSet = buildFileSet(vars, preset, choice, { gitattributes, xanosdk: pluginConfig }, existingXanoSdk);
694
- if (forcedOver && earlyPreset === void 0 && !await confirmForcedOverwrite(targetDir, fileSet, args, { appName, frontend: preset, theme: choice }))
695
- return;
820
+ if (overrideScripts === void 0) {
821
+ const settled = await settle();
822
+ if (settled === "cancelled") return;
823
+ overrideScripts = settled;
824
+ }
825
+ const fileSet = buildFileSet(targetDir, vars, preset, mode, choice, { gitattributes, xanosdk: pluginConfig }, existingXanoSdk);
696
826
  step(
697
- `Scaffolding ${style.bold(appName)} (${preset.label}, ${choice.theme.label}) in ${targetDir}`
827
+ mode === "existing" ? `Adding a Xano backend to ${style.bold(appName)} in ${targetDir}` : preset === null ? `Scaffolding ${style.bold(appName)} (no frontend) in ${targetDir}` : `Scaffolding ${style.bold(appName)} (${preset.label}, ${choice.theme.label}) in ${targetDir}`
698
828
  );
699
829
  const pin = await planProfilePin(args, targetDir);
700
830
  scaffolded = true;
@@ -708,9 +838,14 @@ async function runInitCommand(args) {
708
838
  // An `init` project's `xano/` is hand-authored, never machine-written: it is
709
839
  // not refreshable, and `--force` must not clear it.
710
840
  regenerable: false,
711
- overwrite,
712
- // Only this path writes package.json twice, so only this path merges.
713
- mergePackageJson: modules.length > 0,
841
+ // A new project's directory is empty, and an existing one's clashes were
842
+ // settled above: nothing here is refused.
843
+ overwrite: "full",
844
+ // An existing project's manifest is the user's, merged into with the
845
+ // project winning. Otherwise only the module path writes package.json
846
+ // twice, so only that path merges.
847
+ mergePackageJson: mode === "existing" ? "project" : modules.length > 0 ? "rendered" : void 0,
848
+ overrideScripts,
714
849
  // A project install failing for the reason an add-on's already did (the
715
850
  // manifest they share names a range npm has no version for) is that one
716
851
  // failure, already warned — not a second warning repeating npm's text.
@@ -728,7 +863,7 @@ async function runInitCommand(args) {
728
863
  reportWorkflowPlacement(result.written, vars.install, targetDir);
729
864
  pin.report();
730
865
  const pinnedProfile = pin.name;
731
- info(`Theme: ${choice.theme.label} \u2014 dark mode: ${choice.dark}`);
866
+ if (preset !== null) info(`Theme: ${choice.theme.label} \u2014 dark mode: ${choice.dark}`);
732
867
  if (deferredModules.length > 0) {
733
868
  recordDeferredModules(targetDir, deferredModules);
734
869
  info(`Added to package.json, not installed (--no-install): ${deferredModules.join(", ")}.`);
@@ -789,10 +924,10 @@ async function runInitCommand(args) {
789
924
  }
790
925
  }
791
926
  if (result.install === "installed") {
792
- const { skewedProjectSdk } = await import("./project-sdk-3W72H5QO.js");
927
+ const { skewedProjectSdk } = await import("./project-sdk-2ESHHZVL.js");
793
928
  const installedSdk = skewedProjectSdk(targetDir, readVersion());
794
929
  if (installedSdk !== void 0) {
795
- const { reconcileWithInstalled } = await import("./upgrade-command-C5KBITFI.js");
930
+ const { reconcileWithInstalled } = await import("./upgrade-command-BXMSQN4C.js");
796
931
  const rendered = reconcileWithInstalled(targetDir);
797
932
  if (rendered.length > 0) {
798
933
  info(`Rendered ${rendered.join(", ")} with the installed @xano/sdk ${installedSdk.version} (this CLI is ${readVersion()}).`);
@@ -824,17 +959,18 @@ async function runInitCommand(args) {
824
959
  }
825
960
  const cdHint = targetDir === process.cwd() ? "" : ` cd ${shellWord(targetArg)}
826
961
  `;
962
+ const needsInstall = !(result.install === "installed" || sdkResolves(targetDir));
827
963
  detail(
828
964
  `Next steps:
829
- ` + cdHint + (result.install === "installed" || sdkResolves(targetDir) ? `` : ` ${installLine}
830
- `) + // A declared name with no line in xano/.env refuses the deploy, so the
965
+ ` + cdHint + (needsInstall ? ` ${installLine}
966
+ ` : ``) + // A declared name with no line in xano/.env refuses the deploy, so the
831
967
  // step that supplies it comes first.
832
968
  (addonEnv.length > 0 ? ` cp xano/.env.example xano/.env # then set ${addonEnv.join(", ")} \u2014 the add-ons read ${addonEnv.length === 1 ? "it" : "them"}
833
969
  ` : ``) + // The Xano Engine first: it needs no account, so sign-in waits for
834
970
  // the cloud deploy that does.
835
971
  ` npm run xano:deploy # run the backend on the Xano Engine, on this machine
836
- npm run dev # run the frontend, pointed at it
837
- ` + loginNextStep(pin, targetDir) + ` npm run xano:deploy:ephemeral # build the frontend, then deploy \u2192 live ephemeral URL
972
+ ` + (preset === null ? `` : ` npm run dev # run the frontend, pointed at it
973
+ `) + loginNextStep(pin, targetDir) + `${ephemeralNextStep(preset !== null)}
838
974
 
839
975
  ` + (hadLock !== void 0 ? `xano/xano.lock was kept (${hadLock} ${hadLock === 1 ? "entry" : "entries"}). An entry the new xano/index.ts
840
976
  does not export fails \`npm run xano:check\`; once those objects are gone for good,
@@ -848,11 +984,18 @@ ${ROUTES_REL} was written for the add-ons' endpoints \u2014 commit it too.` : ""
848
984
  writeJson({
849
985
  dir: targetDir,
850
986
  name: appName,
851
- framework: preset.id,
852
- theme: choice.theme.id,
853
- dark: choice.dark,
987
+ // `new` or `existing`: whether this run wrote a project, or added the
988
+ // backend to one that was already there.
989
+ mode,
990
+ framework: preset?.id ?? NO_FRONTEND,
991
+ theme: preset === null ? null : choice.theme.id,
992
+ dark: preset === null ? null : choice.dark,
854
993
  install: result.install,
855
994
  pinnedProfile,
995
+ // Every file this run wrote or merged into, project-relative.
996
+ files: runFiles(result.written, derived),
997
+ // The one command to run next, from where `init` was typed.
998
+ next: deployNextCommand(cdHint === "" ? null : targetArg, needsInstall ? installLine : null, manager),
856
999
  // `--no-install` still names what it added: recorded in package.json,
857
1000
  // not installed, not wired.
858
1001
  ...moduleOutcome === void 0 && deferredModules.length > 0 ? {
@@ -928,14 +1071,14 @@ async function writeDerivedFiles(targetDir, renderIndexWithEnv, toolchain) {
928
1071
  const { readLockFile, writeLockFile } = await import("./io-PGTCBSIQ.js");
929
1072
  const { setDiagnosticSink } = await import("./diagnostics-OMN5Y2AH.js");
930
1073
  const { planRouteManifest } = await import("./routes-manifest-YR4ZIMLM.js");
931
- const { renderManifestFile, reportModuleFailures } = await import("./routes-manifest-file-UALYSZLY.js");
932
- const { isEnabled } = await import("./toolchain-modules-VU7SURVJ.js");
1074
+ const { renderManifestFile, reportModuleFailures } = await import("./routes-manifest-file-LCIKPDAG.js");
1075
+ const { isEnabled } = await import("./toolchain-modules-OTNSKK52.js");
933
1076
  const existing = existsSync(lockPath) ? readLockFile(lockPath) : void 0;
934
1077
  resetLockOverrides();
935
1078
  if (existing !== void 0) seedLockOverrides(existing);
936
1079
  const ctx = createLockContext(existing);
937
1080
  const { envNamesRead } = await import("./guards-KYEOCVHN.js");
938
- const { refreshEnvExample } = await import("./env-example-refresh-CQP3ZMKM.js");
1081
+ const { refreshEnvExample } = await import("./env-example-refresh-WNSOH534.js");
939
1082
  const def = await loadDefault(join(targetDir, XANO_DIR, "index.ts"));
940
1083
  if (!Xano.isXano(def)) return { written, env: declaredEnv };
941
1084
  const previousSink = setDiagnosticSink(() => {
@@ -994,15 +1137,15 @@ async function refuseUnknownProfileFlag(args, targetDir) {
994
1137
  const name = args.profile ?? (fromEnv ? envRaw : void 0);
995
1138
  if (name === void 0) return;
996
1139
  if (fromEnv && targetDir !== void 0) {
997
- const { POINTER_FILE } = await import("./profile-pointer-PDA5XBIB.js");
1140
+ const { POINTER_FILE } = await import("./profile-pointer-KTYXL6FU.js");
998
1141
  if (existsSync(join(targetDir, POINTER_FILE))) return;
999
1142
  }
1000
- const { readCredentialFile, resolveAuthFilePath, profileNames, loginHint } = await import("./store-X6ZH7EC3.js");
1143
+ const { readCredentialFile, resolveAuthFilePath, profileNames, loginHint } = await import("./store-VJ3OS6VO.js");
1001
1144
  const path = resolveAuthFilePath(args, "read");
1002
1145
  const file = readCredentialFile(path);
1003
1146
  const stored = file === null ? [] : profileNames(file);
1004
1147
  if (stored.includes(name)) return;
1005
- const { ProfileNotFoundError } = await import("./token-7AWSJLKO.js");
1148
+ const { ProfileNotFoundError } = await import("./token-DJJUW5HY.js");
1006
1149
  const have = stored.length === 0 ? "Nothing is signed in on this machine." : `Stored profiles: ${quotedNames(stored)}.`;
1007
1150
  throw new ProfileNotFoundError(
1008
1151
  `No credential profile "${name}" in ${path} (from ${fromEnv ? `$${ENV_PROFILE}` : "--profile"}), so there is nothing to pin this project to. ${have} Run ${loginHint(name)} to add it, or name a stored one${fromEnv ? ` (or unset ${ENV_PROFILE})` : ""}.`,
@@ -1011,13 +1154,22 @@ async function refuseUnknownProfileFlag(args, targetDir) {
1011
1154
  );
1012
1155
  }
1013
1156
  async function envCredentialSet() {
1014
- const { envMetaCredentialVarsSet } = await import("./token-7AWSJLKO.js");
1157
+ const { envMetaCredentialVarsSet } = await import("./token-DJJUW5HY.js");
1015
1158
  return envMetaCredentialVarsSet().length > 0;
1016
1159
  }
1017
1160
  function loginNextStep(pin, projectDir) {
1018
1161
  return pin.signedIn ? "" : ` ${projectCli(projectDir)} login # authenticate with Xano
1019
1162
  `;
1020
1163
  }
1164
+ function ephemeralNextStep(frontend) {
1165
+ return frontend ? ` npm run xano:deploy:ephemeral # build the frontend, then deploy \u2192 live ephemeral URL` : ` npm run xano:deploy:ephemeral # deploy the backend \u2192 live ephemeral URL`;
1166
+ }
1167
+ function deployNextCommand(cdArg, install, manager) {
1168
+ return (cdArg === null ? "" : `cd ${shellWord(cdArg)} && `) + (install === null ? "" : `${install} && `) + `${manager} run xano:deploy`;
1169
+ }
1170
+ function runFiles(...groups) {
1171
+ return [...new Set(groups.flat())].sort();
1172
+ }
1021
1173
  function projectCli(projectDir) {
1022
1174
  const prefix = cliPrefixAt(projectDir);
1023
1175
  return prefix === "xanosdk" || prefix === "npx @xano/sdk" ? "npx xanosdk" : prefix;
@@ -1026,8 +1178,8 @@ function runFromHere(text, targetDir) {
1026
1178
  return text.replace(/`npx xanosdk /g, `\`${inProject(targetDir)}xanosdk `);
1027
1179
  }
1028
1180
  async function planProfilePin(args, targetDir, opts = {}) {
1029
- const { POINTER_FILE, readPointerFile } = await import("./profile-pointer-PDA5XBIB.js");
1030
- const { readCredentialFile, resolveAuthFilePath, profileNames, loginHint } = await import("./store-X6ZH7EC3.js");
1181
+ const { POINTER_FILE, readPointerFile } = await import("./profile-pointer-KTYXL6FU.js");
1182
+ const { readCredentialFile, resolveAuthFilePath, profileNames, loginHint } = await import("./store-VJ3OS6VO.js");
1031
1183
  const credentialPath = resolveAuthFilePath(args, "read");
1032
1184
  const file = readCredentialFile(credentialPath);
1033
1185
  const signedIn = file !== null && profileNames(file).length > 0 || await envCredentialSet();
@@ -1057,7 +1209,7 @@ async function planProfilePin(args, targetDir, opts = {}) {
1057
1209
  };
1058
1210
  }
1059
1211
  if (opts.credentialRead === true) {
1060
- const { environmentCredentialVars } = await import("./token-7AWSJLKO.js");
1212
+ const { environmentCredentialVars } = await import("./token-DJJUW5HY.js");
1061
1213
  const env = environmentCredentialVars();
1062
1214
  if (env.complete) {
1063
1215
  return {
@@ -1080,7 +1232,7 @@ async function planProfilePin(args, targetDir, opts = {}) {
1080
1232
  });
1081
1233
  const stored = file === null ? [] : profileNames(file);
1082
1234
  if (!stored.includes(selection.name)) {
1083
- const env = stored.length === 0 ? (await import("./token-7AWSJLKO.js")).environmentCredentialVars() : void 0;
1235
+ const env = stored.length === 0 ? (await import("./token-DJJUW5HY.js")).environmentCredentialVars() : void 0;
1084
1236
  const storeEnv = env?.complete === true ? await storeEnvCredentialCommand(credentialPath, targetDir) : "";
1085
1237
  return {
1086
1238
  name: null,
@@ -1104,7 +1256,7 @@ async function planProfilePin(args, targetDir, opts = {}) {
1104
1256
  };
1105
1257
  }
1106
1258
  }
1107
- const { writePointerFile } = await import("./profile-pointer-PDA5XBIB.js");
1259
+ const { writePointerFile } = await import("./profile-pointer-KTYXL6FU.js");
1108
1260
  return {
1109
1261
  name: selection.name,
1110
1262
  signedIn,
@@ -1121,7 +1273,7 @@ async function envAddressesElsewhere(file, name, credentialPath) {
1121
1273
  const instance = readEnvVar("XANO_INSTANCE_URL")?.trim();
1122
1274
  const workspace = readEnvVar("XANO_WORKSPACE_ID")?.trim();
1123
1275
  if (instance === void 0 || workspace === void 0 || readEnvVar("XANO_META_TOKEN") === void 0) return null;
1124
- const { readProfile, sameOriginAs } = await import("./store-X6ZH7EC3.js");
1276
+ const { readProfile, sameOriginAs } = await import("./store-VJ3OS6VO.js");
1125
1277
  let record;
1126
1278
  try {
1127
1279
  record = readProfile(file, name, credentialPath);
@@ -1137,7 +1289,7 @@ async function envAddressesElsewhere(file, name, credentialPath) {
1137
1289
  };
1138
1290
  }
1139
1291
  async function storeEnvCredentialCommand(credentialPath, targetDir) {
1140
- const { credentialFileFlag, profileAddCommand } = await import("./store-X6ZH7EC3.js");
1292
+ const { credentialFileFlag, profileAddCommand } = await import("./store-VJ3OS6VO.js");
1141
1293
  const { DEFAULT_PROFILE } = await import("./profile-select-45G5VPJK.js");
1142
1294
  const instance = readEnvVar("XANO_INSTANCE_URL");
1143
1295
  const workspaceId = readEnvVar("XANO_WORKSPACE_ID");
@@ -1151,6 +1303,7 @@ function sdkResolves(dir) {
1151
1303
 
1152
1304
  export {
1153
1305
  resolveThemeChoice,
1306
+ resolveFrameworkValue,
1154
1307
  resolveFrontendPreset,
1155
1308
  projectInstallOf,
1156
1309
  workflowPlacementNote,
@@ -1159,10 +1312,17 @@ export {
1159
1312
  templateVarsFor,
1160
1313
  sanitizeAppName,
1161
1314
  projectShellFiles,
1315
+ backendShellFiles,
1162
1316
  resolveFromSource,
1317
+ refuseFrontendOnlyFlags,
1318
+ resolveInitFrontend,
1319
+ settleClashes,
1163
1320
  runInitCommand,
1164
1321
  loginNextStep,
1322
+ ephemeralNextStep,
1323
+ deployNextCommand,
1324
+ runFiles,
1165
1325
  projectCli,
1166
1326
  planProfilePin
1167
1327
  };
1168
- //# sourceMappingURL=chunk-ATJ2W7DC.js.map
1328
+ //# sourceMappingURL=chunk-SGK3PTTM.js.map