@supatype/cli 0.1.1 → 0.1.3

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 (334) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +126 -99
  3. package/.turbo/turbo-typecheck.log +2 -2
  4. package/dist/binary-cache.d.ts +2 -0
  5. package/dist/binary-cache.d.ts.map +1 -1
  6. package/dist/binary-cache.js +36 -0
  7. package/dist/binary-cache.js.map +1 -1
  8. package/dist/binary-download-lock.d.ts +12 -0
  9. package/dist/binary-download-lock.d.ts.map +1 -0
  10. package/dist/binary-download-lock.js +106 -0
  11. package/dist/binary-download-lock.js.map +1 -0
  12. package/dist/cli-package-version.d.ts +3 -0
  13. package/dist/cli-package-version.d.ts.map +1 -0
  14. package/dist/cli-package-version.js +15 -0
  15. package/dist/cli-package-version.js.map +1 -0
  16. package/dist/cli.d.ts.map +1 -1
  17. package/dist/cli.js +5 -2
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/add.js +25 -19
  20. package/dist/commands/add.js.map +1 -1
  21. package/dist/commands/admin.d.ts +12 -0
  22. package/dist/commands/admin.d.ts.map +1 -1
  23. package/dist/commands/admin.js +116 -26
  24. package/dist/commands/admin.js.map +1 -1
  25. package/dist/commands/cache.d.ts +1 -1
  26. package/dist/commands/cache.d.ts.map +1 -1
  27. package/dist/commands/cache.js +98 -5
  28. package/dist/commands/cache.js.map +1 -1
  29. package/dist/commands/dev.d.ts.map +1 -1
  30. package/dist/commands/dev.js +26 -22
  31. package/dist/commands/dev.js.map +1 -1
  32. package/dist/commands/init.d.ts +3 -4
  33. package/dist/commands/init.d.ts.map +1 -1
  34. package/dist/commands/init.js +296 -121
  35. package/dist/commands/init.js.map +1 -1
  36. package/dist/commands/link-helpers.d.ts.map +1 -1
  37. package/dist/commands/link-helpers.js +26 -25
  38. package/dist/commands/link-helpers.js.map +1 -1
  39. package/dist/compose-local-server-image.d.ts +13 -0
  40. package/dist/compose-local-server-image.d.ts.map +1 -0
  41. package/dist/compose-local-server-image.js +57 -0
  42. package/dist/compose-local-server-image.js.map +1 -0
  43. package/dist/compose-rename.d.ts.map +1 -1
  44. package/dist/compose-rename.js +5 -8
  45. package/dist/compose-rename.js.map +1 -1
  46. package/dist/config.d.ts.map +1 -1
  47. package/dist/config.js +12 -1
  48. package/dist/config.js.map +1 -1
  49. package/dist/dev-compose.d.ts.map +1 -1
  50. package/dist/dev-compose.js +113 -56
  51. package/dist/dev-compose.js.map +1 -1
  52. package/dist/dev-log-bus.d.ts +5 -0
  53. package/dist/dev-log-bus.d.ts.map +1 -1
  54. package/dist/dev-log-bus.js +16 -0
  55. package/dist/dev-log-bus.js.map +1 -1
  56. package/dist/dev-log-filter.d.ts +4 -0
  57. package/dist/dev-log-filter.d.ts.map +1 -1
  58. package/dist/dev-log-filter.js +52 -0
  59. package/dist/dev-log-filter.js.map +1 -1
  60. package/dist/dev-ports.d.ts.map +1 -1
  61. package/dist/dev-ports.js +19 -12
  62. package/dist/dev-ports.js.map +1 -1
  63. package/dist/dev-ready-panel.d.ts +21 -0
  64. package/dist/dev-ready-panel.d.ts.map +1 -0
  65. package/dist/dev-ready-panel.js +67 -0
  66. package/dist/dev-ready-panel.js.map +1 -0
  67. package/dist/dev-session-lock.d.ts.map +1 -1
  68. package/dist/dev-session-lock.js +5 -8
  69. package/dist/dev-session-lock.js.map +1 -1
  70. package/dist/dev-session.d.ts +18 -5
  71. package/dist/dev-session.d.ts.map +1 -1
  72. package/dist/dev-session.js +91 -18
  73. package/dist/dev-session.js.map +1 -1
  74. package/dist/dev-shutdown.d.ts +2 -0
  75. package/dist/dev-shutdown.d.ts.map +1 -1
  76. package/dist/dev-shutdown.js +29 -15
  77. package/dist/dev-shutdown.js.map +1 -1
  78. package/dist/dev-task-colors.d.ts +3 -1
  79. package/dist/dev-task-colors.d.ts.map +1 -1
  80. package/dist/dev-task-colors.js +23 -3
  81. package/dist/dev-task-colors.js.map +1 -1
  82. package/dist/docker-runtime.js +1 -1
  83. package/dist/docker-runtime.js.map +1 -1
  84. package/dist/engine-push-output.d.ts +1 -0
  85. package/dist/engine-push-output.d.ts.map +1 -1
  86. package/dist/engine-push-output.js +4 -1
  87. package/dist/engine-push-output.js.map +1 -1
  88. package/dist/ensure-binary.d.ts.map +1 -1
  89. package/dist/ensure-binary.js +14 -2
  90. package/dist/ensure-binary.js.map +1 -1
  91. package/dist/ensure-component-binaries.d.ts +17 -0
  92. package/dist/ensure-component-binaries.d.ts.map +1 -0
  93. package/dist/ensure-component-binaries.js +45 -0
  94. package/dist/ensure-component-binaries.js.map +1 -0
  95. package/dist/ensure-dev-api-config.d.ts +3 -0
  96. package/dist/ensure-dev-api-config.d.ts.map +1 -0
  97. package/dist/ensure-dev-api-config.js +17 -0
  98. package/dist/ensure-dev-api-config.js.map +1 -0
  99. package/dist/init-dependency-versions.d.ts +13 -0
  100. package/dist/init-dependency-versions.d.ts.map +1 -0
  101. package/dist/init-dependency-versions.js +53 -0
  102. package/dist/init-dependency-versions.js.map +1 -0
  103. package/dist/init-package-json.d.ts +21 -0
  104. package/dist/init-package-json.d.ts.map +1 -0
  105. package/dist/init-package-json.js +46 -0
  106. package/dist/init-package-json.js.map +1 -0
  107. package/dist/init-project-detect.d.ts +14 -0
  108. package/dist/init-project-detect.d.ts.map +1 -0
  109. package/dist/init-project-detect.js +89 -0
  110. package/dist/init-project-detect.js.map +1 -0
  111. package/dist/postgres-ctl.d.ts.map +1 -1
  112. package/dist/postgres-ctl.js +2 -1
  113. package/dist/postgres-ctl.js.map +1 -1
  114. package/dist/required-host-components.d.ts +11 -0
  115. package/dist/required-host-components.d.ts.map +1 -0
  116. package/dist/required-host-components.js +25 -0
  117. package/dist/required-host-components.js.map +1 -0
  118. package/dist/resolve-api-url.d.ts +6 -0
  119. package/dist/resolve-api-url.d.ts.map +1 -0
  120. package/dist/resolve-api-url.js +39 -0
  121. package/dist/resolve-api-url.js.map +1 -0
  122. package/dist/rest-cache-admin.d.ts +33 -0
  123. package/dist/rest-cache-admin.d.ts.map +1 -0
  124. package/dist/rest-cache-admin.js +96 -0
  125. package/dist/rest-cache-admin.js.map +1 -0
  126. package/dist/scripts/postinstall.d.ts +4 -6
  127. package/dist/scripts/postinstall.d.ts.map +1 -1
  128. package/dist/scripts/postinstall.js +8 -41
  129. package/dist/scripts/postinstall.js.map +1 -1
  130. package/dist/self-host-compose.d.ts.map +1 -1
  131. package/dist/self-host-compose.js +23 -13
  132. package/dist/self-host-compose.js.map +1 -1
  133. package/dist/studio-dev-server.d.ts +4 -2
  134. package/dist/studio-dev-server.d.ts.map +1 -1
  135. package/dist/studio-dev-server.js +3 -2
  136. package/dist/studio-dev-server.js.map +1 -1
  137. package/dist/ui/brand.d.ts +2 -5
  138. package/dist/ui/brand.d.ts.map +1 -1
  139. package/dist/ui/brand.js +2 -7
  140. package/dist/ui/brand.js.map +1 -1
  141. package/dist/ui/clack-api.d.ts +44 -0
  142. package/dist/ui/clack-api.d.ts.map +1 -0
  143. package/dist/ui/clack-api.js +76 -0
  144. package/dist/ui/clack-api.js.map +1 -0
  145. package/dist/ui/clack.d.ts +14 -0
  146. package/dist/ui/clack.d.ts.map +1 -0
  147. package/dist/ui/clack.js +147 -0
  148. package/dist/ui/clack.js.map +1 -0
  149. package/dist/ui/components/FlowSpinner.d.ts +5 -0
  150. package/dist/ui/components/FlowSpinner.d.ts.map +1 -0
  151. package/dist/ui/components/FlowSpinner.js +8 -0
  152. package/dist/ui/components/FlowSpinner.js.map +1 -0
  153. package/dist/ui/components/LogoWordmark.d.ts +9 -0
  154. package/dist/ui/components/LogoWordmark.d.ts.map +1 -0
  155. package/dist/ui/components/LogoWordmark.js +17 -0
  156. package/dist/ui/components/LogoWordmark.js.map +1 -0
  157. package/dist/ui/components/PromptPanel.d.ts +5 -0
  158. package/dist/ui/components/PromptPanel.d.ts.map +1 -0
  159. package/dist/ui/components/PromptPanel.js +7 -0
  160. package/dist/ui/components/PromptPanel.js.map +1 -0
  161. package/dist/ui/components/SelectField.d.ts +11 -0
  162. package/dist/ui/components/SelectField.d.ts.map +1 -0
  163. package/dist/ui/components/SelectField.js +19 -0
  164. package/dist/ui/components/SelectField.js.map +1 -0
  165. package/dist/ui/confirm.d.ts +2 -1
  166. package/dist/ui/confirm.d.ts.map +1 -1
  167. package/dist/ui/confirm.js +4 -4
  168. package/dist/ui/confirm.js.map +1 -1
  169. package/dist/ui/dev/DevDashboard.d.ts +8 -0
  170. package/dist/ui/dev/DevDashboard.d.ts.map +1 -0
  171. package/dist/ui/dev/DevDashboard.js +158 -0
  172. package/dist/ui/dev/DevDashboard.js.map +1 -0
  173. package/dist/ui/dev/DevReadyPanelView.d.ts +8 -0
  174. package/dist/ui/dev/DevReadyPanelView.d.ts.map +1 -0
  175. package/dist/ui/dev/DevReadyPanelView.js +48 -0
  176. package/dist/ui/dev/DevReadyPanelView.js.map +1 -0
  177. package/dist/ui/fatal.d.ts.map +1 -1
  178. package/dist/ui/fatal.js +5 -11
  179. package/dist/ui/fatal.js.map +1 -1
  180. package/dist/ui/flows/FlowApp.d.ts +8 -0
  181. package/dist/ui/flows/FlowApp.d.ts.map +1 -0
  182. package/dist/ui/flows/FlowApp.js +44 -0
  183. package/dist/ui/flows/FlowApp.js.map +1 -0
  184. package/dist/ui/flows/prompt-fields.d.ts +48 -0
  185. package/dist/ui/flows/prompt-fields.d.ts.map +1 -0
  186. package/dist/ui/flows/prompt-fields.js +92 -0
  187. package/dist/ui/flows/prompt-fields.js.map +1 -0
  188. package/dist/ui/flows/types.d.ts +41 -0
  189. package/dist/ui/flows/types.d.ts.map +1 -0
  190. package/dist/ui/flows/types.js +2 -0
  191. package/dist/ui/flows/types.js.map +1 -0
  192. package/dist/ui/index.d.ts +1 -1
  193. package/dist/ui/index.js +1 -1
  194. package/dist/ui/messages.d.ts +1 -0
  195. package/dist/ui/messages.d.ts.map +1 -1
  196. package/dist/ui/messages.js +48 -8
  197. package/dist/ui/messages.js.map +1 -1
  198. package/dist/ui/progress.d.ts +5 -1
  199. package/dist/ui/progress.d.ts.map +1 -1
  200. package/dist/ui/progress.js +12 -3
  201. package/dist/ui/progress.js.map +1 -1
  202. package/dist/ui/prompts.d.ts +7 -5
  203. package/dist/ui/prompts.d.ts.map +1 -1
  204. package/dist/ui/prompts.js +15 -8
  205. package/dist/ui/prompts.js.map +1 -1
  206. package/dist/ui/runtime/cancel.d.ts +4 -0
  207. package/dist/ui/runtime/cancel.d.ts.map +1 -0
  208. package/dist/ui/runtime/cancel.js +6 -0
  209. package/dist/ui/runtime/cancel.js.map +1 -0
  210. package/dist/ui/runtime/command-chrome.d.ts +17 -0
  211. package/dist/ui/runtime/command-chrome.d.ts.map +1 -0
  212. package/dist/ui/runtime/command-chrome.js +123 -0
  213. package/dist/ui/runtime/command-chrome.js.map +1 -0
  214. package/dist/ui/runtime/dev-prompt-queue.d.ts +30 -0
  215. package/dist/ui/runtime/dev-prompt-queue.d.ts.map +1 -0
  216. package/dist/ui/runtime/dev-prompt-queue.js +57 -0
  217. package/dist/ui/runtime/dev-prompt-queue.js.map +1 -0
  218. package/dist/ui/runtime/flow-session.d.ts +4 -0
  219. package/dist/ui/runtime/flow-session.d.ts.map +1 -0
  220. package/dist/ui/runtime/flow-session.js +8 -0
  221. package/dist/ui/runtime/flow-session.js.map +1 -0
  222. package/dist/ui/runtime/run-clack-flow.d.ts +5 -0
  223. package/dist/ui/runtime/run-clack-flow.d.ts.map +1 -0
  224. package/dist/ui/runtime/run-clack-flow.js +46 -0
  225. package/dist/ui/runtime/run-clack-flow.js.map +1 -0
  226. package/dist/ui/runtime/stdin-after-ink.d.ts +3 -0
  227. package/dist/ui/runtime/stdin-after-ink.d.ts.map +1 -0
  228. package/dist/ui/runtime/stdin-after-ink.js +16 -0
  229. package/dist/ui/runtime/stdin-after-ink.js.map +1 -0
  230. package/dist/ui/theme.d.ts +24 -0
  231. package/dist/ui/theme.d.ts.map +1 -0
  232. package/dist/ui/theme.js +34 -0
  233. package/dist/ui/theme.js.map +1 -0
  234. package/dist/valkey-sidecar.d.ts +17 -0
  235. package/dist/valkey-sidecar.d.ts.map +1 -0
  236. package/dist/valkey-sidecar.js +94 -0
  237. package/dist/valkey-sidecar.js.map +1 -0
  238. package/package.json +9 -3
  239. package/src/binary-cache.ts +61 -0
  240. package/src/binary-download-lock.ts +124 -0
  241. package/src/cli-package-version.ts +15 -0
  242. package/src/cli.ts +6 -2
  243. package/src/commands/add.ts +26 -19
  244. package/src/commands/admin.ts +156 -29
  245. package/src/commands/cache.ts +105 -5
  246. package/src/commands/dev.ts +26 -21
  247. package/src/commands/init.ts +473 -247
  248. package/src/commands/link-helpers.ts +30 -29
  249. package/src/compose-local-server-image.ts +68 -0
  250. package/src/compose-rename.ts +5 -8
  251. package/src/config.ts +13 -1
  252. package/src/dev-compose.ts +139 -54
  253. package/src/dev-log-bus.ts +20 -0
  254. package/src/dev-log-filter.ts +42 -0
  255. package/src/dev-ports.ts +22 -11
  256. package/src/dev-ready-panel.ts +80 -0
  257. package/src/dev-session-lock.ts +5 -8
  258. package/src/dev-session.ts +98 -18
  259. package/src/dev-shutdown.ts +29 -17
  260. package/src/dev-task-colors.ts +22 -3
  261. package/src/docker-runtime.ts +1 -1
  262. package/src/engine-push-output.ts +5 -1
  263. package/src/ensure-binary.ts +21 -1
  264. package/src/ensure-component-binaries.ts +71 -0
  265. package/src/ensure-dev-api-config.ts +18 -0
  266. package/src/init-dependency-versions.ts +69 -0
  267. package/src/init-package-json.ts +63 -0
  268. package/src/init-project-detect.ts +99 -0
  269. package/src/postgres-ctl.ts +2 -1
  270. package/src/required-host-components.ts +37 -0
  271. package/src/resolve-api-url.ts +43 -0
  272. package/src/rest-cache-admin.ts +135 -0
  273. package/src/scripts/postinstall.ts +9 -46
  274. package/src/self-host-compose.ts +22 -12
  275. package/src/studio-dev-server.ts +5 -4
  276. package/src/ui/README.md +13 -9
  277. package/src/ui/brand.ts +2 -8
  278. package/src/ui/clack-api.ts +123 -0
  279. package/src/ui/clack.ts +153 -0
  280. package/src/ui/components/FlowSpinner.tsx +15 -0
  281. package/src/ui/components/LogoWordmark.tsx +36 -0
  282. package/src/ui/components/PromptPanel.tsx +17 -0
  283. package/src/ui/components/SelectField.tsx +58 -0
  284. package/src/ui/confirm.ts +5 -4
  285. package/src/ui/dev/DevDashboard.tsx +223 -0
  286. package/src/ui/dev/DevReadyPanelView.tsx +134 -0
  287. package/src/ui/fatal.ts +5 -10
  288. package/src/ui/flows/FlowApp.tsx +69 -0
  289. package/src/ui/flows/prompt-fields.tsx +198 -0
  290. package/src/ui/flows/types.ts +50 -0
  291. package/src/ui/index.ts +1 -1
  292. package/src/ui/messages.ts +50 -8
  293. package/src/ui/progress.ts +14 -3
  294. package/src/ui/prompts.ts +17 -9
  295. package/src/ui/runtime/cancel.ts +6 -0
  296. package/src/ui/runtime/command-chrome.ts +147 -0
  297. package/src/ui/runtime/dev-prompt-queue.ts +84 -0
  298. package/src/ui/runtime/flow-session.ts +11 -0
  299. package/src/ui/runtime/run-clack-flow.tsx +65 -0
  300. package/src/ui/runtime/stdin-after-ink.ts +18 -0
  301. package/src/ui/theme.ts +41 -0
  302. package/src/valkey-sidecar.ts +126 -0
  303. package/tests/admin-ensure.test.ts +80 -0
  304. package/tests/binary-cache-cloud-overrides.test.ts +2 -2
  305. package/tests/binary-download-lock.test.ts +41 -0
  306. package/tests/cli-help.test.ts +7 -4
  307. package/tests/cli-package-version.test.ts +15 -0
  308. package/tests/command-chrome-coverage.test.ts +149 -0
  309. package/tests/command-chrome-wrap.test.ts +51 -0
  310. package/tests/config.test.ts +27 -4
  311. package/tests/dev-ready-panel.test.ts +37 -0
  312. package/tests/dev-ui.test.ts +42 -2
  313. package/tests/docker-runtime.test.ts +9 -20
  314. package/tests/ensure-dev-api-config.test.ts +22 -0
  315. package/tests/init-dependency-versions.test.ts +62 -0
  316. package/tests/init-package-json.test.ts +18 -0
  317. package/tests/init-project-detect.test.ts +53 -0
  318. package/tests/init.test.ts +30 -3
  319. package/tests/required-host-components.test.ts +51 -0
  320. package/tests/resolve-api-url.test.ts +23 -0
  321. package/tests/rest-cache-admin.test.ts +28 -0
  322. package/tests/runtime-contract.test.ts +12 -3
  323. package/tests/stdin-after-ink.test.ts +8 -0
  324. package/tests/tsconfig.json +8 -2
  325. package/tests/ui-confirm.test.ts +13 -9
  326. package/tests/ui-messages.test.ts +4 -18
  327. package/tsconfig.json +1 -0
  328. package/tsconfig.tsbuildinfo +1 -1
  329. package/vitest.config.ts +3 -0
  330. package/dist/dev-tui.d.ts +0 -24
  331. package/dist/dev-tui.d.ts.map +0 -1
  332. package/dist/dev-tui.js +0 -188
  333. package/dist/dev-tui.js.map +0 -1
  334. package/src/dev-tui.ts +0 -232
@@ -1,27 +1,18 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { resolve, join, dirname, basename } from "node:path";
3
- import { fileURLToPath } from "node:url";
2
+ import { resolve, join, basename } from "node:path";
4
3
  import { spawnSync } from "node:child_process";
5
- import * as p from "@clack/prompts";
6
- import { ensureNotCancelled, printLogo } from "../ui/prompts.js";
4
+ import { p, runClackFlow } from "../ui/clack.js";
5
+ import { ensureNotCancelled } from "../ui/prompts.js";
7
6
  import { generateAndWriteKeys } from "./keys.js";
8
7
  import { file, error, info, plain, warn } from "../ui/messages.js";
9
8
  import { nextSteps } from "../ui/next-steps.js";
10
9
  import { probeDockerDaemon, reportDockerUnavailable } from "../docker-runtime.js";
11
- export { scaffold };
12
- // ─── Markers used by `supatype app add / remove` (app.ts) ────────────────────
13
- export const APP_COMPOSE_MARKER = " # ─── App service (run: supatype app add) ───";
14
- export const KONG_APP_MARKER = " # ─── App fallback route (run: supatype app add) ───";
15
- const CLI_PACKAGE_JSON = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json");
16
- function cliPackageVersion() {
17
- try {
18
- const pkg = JSON.parse(readFileSync(CLI_PACKAGE_JSON, "utf8"));
19
- return pkg.version ?? "0.1.0";
20
- }
21
- catch {
22
- return "0.1.0";
23
- }
24
- }
10
+ import { loadConfig } from "../config.js";
11
+ import { ensureComponentBinaries, reportComponentBinaryFailures, } from "../ensure-component-binaries.js";
12
+ import { mergeSupatypePackageJson } from "../init-package-json.js";
13
+ import { cliPackageVersion } from "../cli-package-version.js";
14
+ import { initDependencyVersionsFallback, resolveInitDependencyVersions, } from "../init-dependency-versions.js";
15
+ import { detectProjectSetup } from "../init-project-detect.js";
25
16
  const STORAGE_PROVIDER_OPTIONS = [
26
17
  { value: "local", label: "Local", hint: "storage you host yourself (MinIO)" },
27
18
  { value: "s3", label: "S3", hint: "external bucket (AWS S3 or compatible)" },
@@ -77,8 +68,14 @@ export function registerInit(program) {
77
68
  const modeTarget = productionTargetFromMode(opts.mode);
78
69
  let result;
79
70
  if (interactive) {
80
- printLogo();
81
- result = await runWizard(defaultName, modeTarget);
71
+ await runInteractiveInit({
72
+ name,
73
+ dir,
74
+ defaultName,
75
+ modeTarget,
76
+ opts,
77
+ });
78
+ return;
82
79
  }
83
80
  else {
84
81
  result = {
@@ -110,27 +107,117 @@ export function registerInit(program) {
110
107
  const doKeys = opts.keys !== false && result.generateKeys;
111
108
  if (name)
112
109
  mkdirSync(dir, { recursive: true });
113
- scaffold(dir, result);
114
- if (doInstall)
115
- runInstall(dir, result.packageManager);
110
+ const deps = await resolveInitDependencyVersions();
111
+ const runningCli = cliPackageVersion();
112
+ if (deps.cli !== runningCli || deps.types !== runningCli) {
113
+ info(`Using published npm versions: @supatype/cli ^${deps.cli}, @supatype/types ^${deps.types}`);
114
+ }
115
+ scaffold(dir, result, deps);
116
+ const installOk = doInstall ? runInstall(dir, result.packageManager) : false;
116
117
  const keysGenerated = doKeys ? writeKeys(dir) : false;
118
+ const binariesReady = doInstall && installOk ? await ensureInitBinaries(dir) : false;
119
+ if (doInstall && !installOk) {
120
+ error(`Dependency install failed. Run "${result.packageManager} install" in the project directory, then "supatype update".`);
121
+ process.exit(1);
122
+ }
123
+ if (doKeys && !keysGenerated) {
124
+ error("Could not generate API keys. Check .env has JWT_SECRET, then run `supatype keys`.");
125
+ process.exit(1);
126
+ }
127
+ if (doInstall && installOk && !binariesReady) {
128
+ error("Component binaries could not be downloaded. Run `supatype update` in the project directory.");
129
+ process.exit(1);
130
+ }
117
131
  warnDockerUnavailableForProvider(result.provider);
118
132
  printNextSteps({
119
133
  name,
120
134
  result,
121
- installed: doInstall,
135
+ installed: doInstall && installOk,
122
136
  keysGenerated,
137
+ binariesReady,
123
138
  });
124
139
  });
125
140
  }
141
+ /** Interactive init — one Ink session for wizard + scaffold + install + finish. */
142
+ async function runInteractiveInit(args) {
143
+ const { name, dir, defaultName, modeTarget, opts } = args;
144
+ await runClackFlow(async () => {
145
+ p.intro("Create a new Supatype project");
146
+ const detected = detectProjectSetup(dir);
147
+ if (detected.hasExistingFiles && detected.summaryLines.length > 0) {
148
+ p.note(["Existing project detected:", ...detected.summaryLines.map((line) => ` • ${line}`)].join("\n"));
149
+ }
150
+ let result = await collectWizardAnswers(defaultName, modeTarget, dir, detected);
151
+ if (opts.admin === false) {
152
+ delete result.adminEmail;
153
+ delete result.adminPassword;
154
+ }
155
+ else if (opts.adminEmail && opts.adminPassword) {
156
+ result.adminEmail = opts.adminEmail;
157
+ result.adminPassword = opts.adminPassword;
158
+ }
159
+ const doInstall = opts.install !== false && result.install;
160
+ const doKeys = opts.keys !== false && result.generateKeys;
161
+ if (name)
162
+ mkdirSync(dir, { recursive: true });
163
+ const deps = await resolveInitDependencyVersions();
164
+ const runningCli = cliPackageVersion();
165
+ if (deps.cli !== runningCli || deps.types !== runningCli) {
166
+ info(`Using published npm versions: @supatype/cli ^${deps.cli}, @supatype/types ^${deps.types}`);
167
+ }
168
+ const setupSpinner = p.spinner();
169
+ setupSpinner.start("Setting up your project...");
170
+ scaffold(dir, result, deps);
171
+ let installOk = !doInstall;
172
+ if (doInstall) {
173
+ setupSpinner.start(`Installing dependencies with ${result.packageManager}...`);
174
+ installOk = runInstall(dir, result.packageManager);
175
+ setupSpinner.stop(installOk ? "Dependencies installed." : "Dependency install failed.");
176
+ }
177
+ let keysGenerated = !doKeys;
178
+ if (doKeys) {
179
+ setupSpinner.start("Generating API keys...");
180
+ keysGenerated = writeKeys(dir);
181
+ setupSpinner.stop(keysGenerated ? "API keys generated." : "Could not generate API keys.");
182
+ }
183
+ let binariesReady = false;
184
+ if (doInstall && installOk) {
185
+ setupSpinner.start("Preparing component binaries...");
186
+ binariesReady = await ensureInitBinaries(dir);
187
+ setupSpinner.stop(binariesReady ? "Component binaries ready." : "Some binaries are missing.");
188
+ }
189
+ if (doInstall && !installOk) {
190
+ error(`Dependency install failed. Run "${result.packageManager} install" in the project directory, then "supatype update".`);
191
+ process.exit(1);
192
+ }
193
+ if (doKeys && !keysGenerated) {
194
+ error("Could not generate API keys. Check .env has JWT_SECRET, then run `supatype keys`.");
195
+ process.exit(1);
196
+ }
197
+ if (doInstall && installOk && !binariesReady) {
198
+ error("Component binaries could not be downloaded. Run `supatype update` in the project directory.");
199
+ process.exit(1);
200
+ }
201
+ warnDockerUnavailableForProvider(result.provider);
202
+ p.outro(`Supatype project ready${name ? ` in ${name}/` : ""}.`);
203
+ printNextSteps({
204
+ name,
205
+ result,
206
+ installed: doInstall && installOk,
207
+ keysGenerated,
208
+ binariesReady,
209
+ });
210
+ });
211
+ process.exit(0);
212
+ }
126
213
  // ─── Wizard ──────────────────────────────────────────────────────────────────
127
- async function runWizard(defaultName, defaultTarget) {
128
- p.intro("Create a new Supatype project");
214
+ async function collectWizardAnswers(defaultName, defaultTarget, dir, detected) {
129
215
  const projectName = ensureNotCancelled(await p.text({
130
216
  message: "Project name",
131
217
  defaultValue: defaultName,
132
218
  placeholder: defaultName,
133
219
  })).trim() || defaultName;
220
+ const admin = await promptAdminUser();
134
221
  const packageManager = ensureNotCancelled(await p.select({
135
222
  message: "Package manager",
136
223
  initialValue: detectInvokingPackageManager(),
@@ -180,12 +267,15 @@ async function runWizard(defaultName, defaultTarget) {
180
267
  const { promptKongPortChoice } = await import("../dev-ports.js");
181
268
  kongPort = await promptKongPortChoice();
182
269
  }
270
+ const defaultSchemaPath = existsSync(join(dir, "schema/index.ts"))
271
+ ? "schema/index.ts"
272
+ : "schema/index.ts";
183
273
  const schemaPath = ensureNotCancelled(await p.text({
184
274
  message: "Where should your schema live?",
185
- defaultValue: "schema/index.ts",
275
+ defaultValue: defaultSchemaPath,
186
276
  placeholder: "schema/index.ts",
187
- })).trim() || "schema/index.ts";
188
- const app = await promptApp();
277
+ })).trim() || defaultSchemaPath;
278
+ const app = await promptApp(detected, productionTarget);
189
279
  const email = ensureNotCancelled(await p.select({
190
280
  message: "Email provider",
191
281
  initialValue: "console",
@@ -210,39 +300,6 @@ async function runWizard(defaultName, defaultTarget) {
210
300
  message: "Create a hello-world edge function?",
211
301
  initialValue: false,
212
302
  }));
213
- const install = ensureNotCancelled(await p.confirm({
214
- message: `Install dependencies with ${packageManager} now?`,
215
- initialValue: true,
216
- }));
217
- const generateKeys = ensureNotCancelled(await p.confirm({
218
- message: "Generate ANON_KEY and SERVICE_ROLE_KEY now?",
219
- initialValue: true,
220
- }));
221
- let adminEmail;
222
- let adminPassword;
223
- const createAdmin = ensureNotCancelled(await p.confirm({
224
- message: "Create an admin user for /admin?",
225
- initialValue: true,
226
- }));
227
- if (createAdmin) {
228
- adminEmail =
229
- ensureNotCancelled(await p.text({
230
- message: "Admin email",
231
- placeholder: "you@example.com",
232
- defaultValue: "",
233
- })).trim() || undefined;
234
- if (adminEmail) {
235
- adminPassword =
236
- ensureNotCancelled(await p.text({
237
- message: "Admin password (min 8 chars)",
238
- defaultValue: "",
239
- })).trim() || undefined;
240
- if (adminPassword && adminPassword.length < 8) {
241
- adminPassword = undefined;
242
- }
243
- }
244
- }
245
- p.outro("Setting up your project...");
246
303
  return {
247
304
  projectName,
248
305
  provider,
@@ -257,15 +314,42 @@ async function runWizard(defaultName, defaultTarget) {
257
314
  storageProduction,
258
315
  helloFunction,
259
316
  packageManager,
260
- install,
261
- generateKeys,
262
- ...(adminEmail && adminPassword ? { adminEmail, adminPassword } : {}),
317
+ install: true,
318
+ generateKeys: true,
319
+ ...admin,
263
320
  };
264
321
  }
265
- async function promptApp() {
322
+ async function promptAdminUser() {
323
+ const createAdmin = ensureNotCancelled(await p.confirm({
324
+ message: "Create an admin user for /admin?",
325
+ initialValue: true,
326
+ }));
327
+ if (!createAdmin)
328
+ return {};
329
+ p.note("First sign-in at /admin — created automatically on supatype dev or push.");
330
+ const adminEmail = ensureNotCancelled(await p.text({
331
+ message: "Admin email",
332
+ placeholder: "you@example.com",
333
+ validate: (value) => (value.trim() ? undefined : "Email is required"),
334
+ })).trim();
335
+ let adminPassword = "";
336
+ while (true) {
337
+ adminPassword = ensureNotCancelled(await p.password({ message: "Admin password (min 8 characters)" })).trim();
338
+ if (adminPassword.length >= 8)
339
+ break;
340
+ p.log.warn("Password must be at least 8 characters.");
341
+ }
342
+ return { adminEmail, adminPassword };
343
+ }
344
+ async function promptApp(detected, productionTarget) {
345
+ const initialMode = detected.hasVite && productionTarget !== "later"
346
+ ? "static"
347
+ : detected.hasVite
348
+ ? "proxy"
349
+ : "none";
266
350
  const mode = ensureNotCancelled(await p.select({
267
351
  message: "Host a frontend app at /?",
268
- initialValue: "none",
352
+ initialValue: initialMode,
269
353
  options: [
270
354
  { value: "none", label: "No app", hint: "API only" },
271
355
  { value: "static", label: "Static site", hint: "serve a built directory" },
@@ -275,40 +359,44 @@ async function promptApp() {
275
359
  if (mode === "static") {
276
360
  const staticDir = ensureNotCancelled(await p.text({
277
361
  message: "Directory to serve",
278
- defaultValue: "./public",
279
- placeholder: "./public",
280
- })).trim() || "./public";
281
- const viteDevUrl = await promptViteDevUrl();
362
+ defaultValue: detected.staticDir,
363
+ placeholder: detected.staticDir,
364
+ })).trim() || detected.staticDir;
365
+ const viteDevUrl = await promptViteDevUrl(detected, productionTarget);
282
366
  return { mode, staticDir, ...(viteDevUrl ? { viteDevUrl } : {}) };
283
367
  }
284
368
  if (mode === "proxy") {
285
369
  const upstream = ensureNotCancelled(await p.text({
286
370
  message: "URL of your running dev server",
287
- defaultValue: "http://localhost:3000",
288
- placeholder: "http://localhost:3000",
289
- })).trim() || "http://localhost:3000";
371
+ defaultValue: detected.hasVite ? detected.viteDevUrl : "http://localhost:3000",
372
+ placeholder: detected.hasVite ? detected.viteDevUrl : "http://localhost:3000",
373
+ })).trim() || (detected.hasVite ? detected.viteDevUrl : "http://localhost:3000");
290
374
  const start = ensureNotCancelled(await p.text({
291
375
  message: "package.json script that starts your dev server",
292
- defaultValue: "dev",
293
- placeholder: "dev",
294
- })).trim() || "dev";
295
- const viteDevUrl = await promptViteDevUrl();
376
+ defaultValue: detected.hasVite ? "vite" : "dev",
377
+ placeholder: detected.hasVite ? "vite" : "dev",
378
+ })).trim() || (detected.hasVite ? "vite" : "dev");
379
+ const viteDevUrl = await promptViteDevUrl(detected, productionTarget);
296
380
  return { mode, upstream, start, ...(viteDevUrl ? { viteDevUrl } : {}) };
297
381
  }
298
382
  return { mode: "none" };
299
383
  }
300
- async function promptViteDevUrl() {
384
+ async function promptViteDevUrl(detected, productionTarget) {
385
+ const defaultYes = detected.hasVite || productionTarget !== "later";
301
386
  const useVite = ensureNotCancelled(await p.confirm({
302
- message: "Enable live reload from a separate Vite dev server?",
303
- initialValue: false,
387
+ message: detected.hasVite
388
+ ? "Use Vite for local development?"
389
+ : "Develop locally with Vite (live reload)?",
390
+ initialValue: defaultYes,
304
391
  }));
305
392
  if (!useVite)
306
393
  return undefined;
394
+ p.note(`Press Enter for ${detected.viteDevUrl}, or type a custom URL.`);
307
395
  return (ensureNotCancelled(await p.text({
308
396
  message: "Vite dev server URL",
309
- defaultValue: "http://127.0.0.1:5173",
310
- placeholder: "http://127.0.0.1:5173",
311
- })).trim() || "http://127.0.0.1:5173");
397
+ defaultValue: detected.viteDevUrl,
398
+ placeholder: detected.viteDevUrl,
399
+ })).trim() || detected.viteDevUrl);
312
400
  }
313
401
  // ─── Package manager ───────────────────────────────────────────────────────--
314
402
  function detectInvokingPackageManager() {
@@ -322,14 +410,36 @@ function detectInvokingPackageManager() {
322
410
  return "npm";
323
411
  }
324
412
  function runInstall(dir, pm) {
325
- info(`Installing dependencies with ${pm}...`);
326
413
  const res = spawnSync(pm, ["install"], {
327
414
  cwd: dir,
328
415
  stdio: "inherit",
329
416
  shell: process.platform === "win32",
330
417
  });
331
418
  if (res.status !== 0 || res.error) {
332
- warn(`Dependency install did not complete (run "${pm} install" manually).`);
419
+ return false;
420
+ }
421
+ return true;
422
+ }
423
+ async function ensureInitBinaries(dir) {
424
+ const previousCwd = process.cwd();
425
+ try {
426
+ process.chdir(dir);
427
+ const config = loadConfig(dir);
428
+ const result = await ensureComponentBinaries(config, dir);
429
+ if (!result.ok) {
430
+ reportComponentBinaryFailures(result.failures);
431
+ return false;
432
+ }
433
+ return true;
434
+ }
435
+ catch (err) {
436
+ const message = err instanceof Error ? err.message : String(err);
437
+ warn(`Could not verify component binaries: ${message}`);
438
+ warn("Run manually from your project directory: supatype update");
439
+ return false;
440
+ }
441
+ finally {
442
+ process.chdir(previousCwd);
333
443
  }
334
444
  }
335
445
  function writeKeys(dir) {
@@ -341,7 +451,7 @@ function writeKeys(dir) {
341
451
  return true;
342
452
  }
343
453
  // ─── Scaffold ──────────────────────────────────────────────────────────────--
344
- function scaffold(dir, optsOrName) {
454
+ export function scaffold(dir, optsOrName, deps = initDependencyVersionsFallback()) {
345
455
  const opts = typeof optsOrName === "string" ? defaultScaffoldOptions(optsOrName) : optsOrName;
346
456
  const write = (rel, content) => {
347
457
  const full = join(dir, rel);
@@ -351,10 +461,19 @@ function scaffold(dir, optsOrName) {
351
461
  };
352
462
  const pkgPath = join(dir, "package.json");
353
463
  if (!existsSync(pkgPath)) {
354
- write("package.json", packageJsonTemplate(opts, cliPackageVersion()));
464
+ write("package.json", packageJsonTemplate(opts, deps));
355
465
  }
356
466
  else {
357
- file("skipped", "package.json (already exists)");
467
+ try {
468
+ const existing = JSON.parse(readFileSync(pkgPath, "utf8"));
469
+ const merged = mergeSupatypePackageJson(existing, opts, deps);
470
+ writeFileSync(pkgPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8");
471
+ file("updated", "package.json (added Supatype dependencies)");
472
+ }
473
+ catch {
474
+ warn("Could not merge into package.json — add @supatype/cli and @supatype/types manually.");
475
+ file("skipped", "package.json (invalid JSON)");
476
+ }
358
477
  }
359
478
  write("supatype.config.ts", tsConfigTemplate(opts));
360
479
  if (opts.productionTarget !== "later") {
@@ -364,7 +483,7 @@ function scaffold(dir, optsOrName) {
364
483
  write(".env", envTemplate(opts));
365
484
  write("seed.ts", seedTemplate(opts.projectName));
366
485
  write("seeds/.gitkeep", "");
367
- scaffoldAppAssets(opts, write);
486
+ scaffoldAppAssets(dir, opts, write);
368
487
  if (opts.helloFunction)
369
488
  scaffoldHelloFunction(dir, write);
370
489
  const gitignorePath = join(dir, ".gitignore");
@@ -386,32 +505,50 @@ function staticDirRelative(staticDir) {
386
505
  const raw = (staticDir ?? "./public").trim();
387
506
  return raw.replace(/^\.\//, "").replace(/\/+$/, "") || "public";
388
507
  }
389
- function scaffoldAppAssets(opts, write) {
508
+ function scaffoldAppAssets(dir, opts, write) {
509
+ const writeUnlessExists = (rel, content) => {
510
+ const full = join(dir, rel);
511
+ if (existsSync(full)) {
512
+ file("skipped", `${rel} (already exists)`);
513
+ return;
514
+ }
515
+ write(rel, content);
516
+ };
390
517
  const holding = holdingPageTemplate(opts.projectName);
391
518
  const hasVite = Boolean(opts.app.viteDevUrl);
392
519
  if (opts.app.mode === "static") {
393
520
  const staticRel = staticDirRelative(opts.app.staticDir);
394
- write(`${staticRel}/index.html`, holding);
395
- if (hasVite)
396
- scaffoldVite(opts, write, holding);
521
+ if (opts.app.viteDevUrl && opts.productionTarget !== "later") {
522
+ writeUnlessExists("dist/index.html", holding);
523
+ scaffoldVite(dir, opts, writeUnlessExists, holding);
524
+ return;
525
+ }
526
+ writeUnlessExists(`${staticRel}/index.html`, holding);
527
+ if (opts.app.viteDevUrl)
528
+ scaffoldVite(dir, opts, writeUnlessExists, holding);
397
529
  return;
398
530
  }
399
531
  if (opts.app.mode === "proxy" && opts.productionTarget !== "later") {
400
- write("dist/index.html", holding);
532
+ writeUnlessExists("dist/index.html", holding);
401
533
  if (hasVite)
402
- scaffoldVite(opts, write, holding);
534
+ scaffoldVite(dir, opts, writeUnlessExists, holding);
403
535
  return;
404
536
  }
405
537
  if (opts.app.mode === "proxy" && hasVite) {
406
- scaffoldVite(opts, write, holding);
538
+ scaffoldVite(dir, opts, writeUnlessExists, holding);
407
539
  return;
408
540
  }
409
- write("public/.gitkeep", "");
541
+ writeUnlessExists("public/.gitkeep", "");
410
542
  }
411
- function scaffoldVite(opts, write, holding) {
543
+ function scaffoldVite(dir, opts, write, holding) {
412
544
  if (!opts.app.viteDevUrl)
413
545
  return;
414
546
  write("index.html", holding);
547
+ const viteConfigRel = ["vite.config.ts", "vite.config.js", "vite.config.mjs", "vite.config.cjs"].find((name) => existsSync(join(dir, name)));
548
+ if (viteConfigRel) {
549
+ file("skipped", `${viteConfigRel} (already exists)`);
550
+ return;
551
+ }
415
552
  write("vite.config.ts", viteConfigTemplate(opts.app.viteDevUrl));
416
553
  }
417
554
  function scaffoldHelloFunction(dir, write) {
@@ -424,7 +561,7 @@ function scaffoldHelloFunction(dir, write) {
424
561
  }
425
562
  }
426
563
  // ─── Templates ───────────────────────────────────────────────────────────────
427
- function packageJsonTemplate(opts, cliVersion) {
564
+ function packageJsonTemplate(opts, deps) {
428
565
  const scripts = [
429
566
  ` "dev": "supatype dev"`,
430
567
  ` "push": "supatype push"`,
@@ -448,8 +585,8 @@ function packageJsonTemplate(opts, cliVersion) {
448
585
  ${scripts.join(",\n")}
449
586
  },
450
587
  "dependencies": {
451
- "@supatype/cli": "^${cliVersion}",
452
- "@supatype/types": "^${cliVersion}"
588
+ "@supatype/cli": "^${deps.cli}",
589
+ "@supatype/types": "^${deps.types}"
453
590
  },
454
591
  "devDependencies": {
455
592
  ${devDeps.join(",\n")}
@@ -511,20 +648,47 @@ function localConfigTemplate(app) {
511
648
  `const localConfig: Partial<SupatypeConfig> = {`,
512
649
  ` server: { mode: "dev" },`,
513
650
  ];
514
- if (app.mode === "proxy") {
515
- lines.push(` app: {`);
516
- lines.push(` mode: "proxy",`);
517
- lines.push(` upstream: "${app.upstream ?? "http://localhost:3000"}",`);
518
- lines.push(` start: "${app.start ?? "dev"}",`);
519
- if (app.viteDevUrl)
520
- lines.push(` vite_dev_url: "${app.viteDevUrl}",`);
521
- lines.push(` },`);
651
+ const localApp = localDevAppConfigLines(app);
652
+ if (localApp.length > 0) {
653
+ lines.push(...localApp);
522
654
  }
523
655
  lines.push(`}`, ``, `export default localConfig`, ``);
524
656
  return lines.join("\n");
525
657
  }
658
+ /** App block for supatype.local.config.ts (proxy + Vite during local dev). */
659
+ function localDevAppConfigLines(app) {
660
+ if (app.mode === "proxy") {
661
+ return [
662
+ ` app: {`,
663
+ ` mode: "proxy",`,
664
+ ` upstream: "${app.upstream ?? "http://localhost:3000"}",`,
665
+ ` start: "${app.start ?? "dev"}",`,
666
+ ...(app.viteDevUrl ? [` vite_dev_url: "${app.viteDevUrl}",`] : []),
667
+ ` },`,
668
+ ];
669
+ }
670
+ if (app.viteDevUrl) {
671
+ return [
672
+ ` app: {`,
673
+ ` mode: "proxy",`,
674
+ ` upstream: "${app.viteDevUrl}",`,
675
+ ` start: "vite",`,
676
+ ` vite_dev_url: "${app.viteDevUrl}",`,
677
+ ` },`,
678
+ ];
679
+ }
680
+ return [];
681
+ }
526
682
  function appConfigLines(app, productionTarget) {
527
683
  if (app.mode === "static") {
684
+ if (productionTarget !== "later" && app.viteDevUrl) {
685
+ return [
686
+ ` app: {`,
687
+ ` mode: "static",`,
688
+ ` static_dir: "./dist", // production build output`,
689
+ ` },`,
690
+ ];
691
+ }
528
692
  const out = [
529
693
  ` app: {`,
530
694
  ` mode: "static",`,
@@ -583,7 +747,7 @@ function holdingPageTemplate(projectName) {
583
747
  <meta charset="UTF-8" />
584
748
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
585
749
  <title>${name} — Supatype</title>
586
- <meta name="description" content="A Supatype project. Define your types — we generate your backend." />
750
+ <meta name="description" content="A Supatype project. Define your types — we generate your platform." />
587
751
  <link rel="preconnect" href="https://fonts.googleapis.com" />
588
752
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
589
753
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
@@ -718,6 +882,8 @@ export default defineConfig({
718
882
  host: "127.0.0.1",
719
883
  port: ${port},
720
884
  strictPort: true,
885
+ // Docker Compose app proxy reaches the host as host.docker.internal.
886
+ allowedHosts: ["127.0.0.1", "localhost", "host.docker.internal"],
721
887
  },
722
888
  })
723
889
  `;
@@ -956,27 +1122,36 @@ function warnDockerUnavailableForProvider(provider) {
956
1122
  plain();
957
1123
  }
958
1124
  function printNextSteps(args) {
959
- const { name, result, installed, keysGenerated } = args;
1125
+ const { name, result, installed, keysGenerated, binariesReady } = args;
1126
+ const setupComplete = installed && keysGenerated && binariesReady;
960
1127
  const steps = [];
961
1128
  if (name)
962
1129
  steps.push(`cd ${name}`);
963
- if (!installed)
964
- steps.push(`${result.packageManager} install`);
965
- if (!keysGenerated)
966
- steps.push("supatype keys");
967
1130
  const kongHint = result.provider === "docker" && result.kongPort !== undefined
968
1131
  ? `supatype dev # Docker Compose stack (Kong :${result.kongPort})`
969
1132
  : "supatype dev # Docker Compose stack (Kong :18473)";
970
- steps.push(kongHint);
971
- steps.push("supatype push # apply schema + generate types");
972
- if (result.adminEmail) {
973
- steps.push(" # first admin user is created on dev or push");
1133
+ if (setupComplete) {
1134
+ steps.push(kongHint);
1135
+ steps.push("supatype push # apply schema + generate types");
1136
+ if (result.adminEmail) {
1137
+ steps.push(" # first admin user is created on dev or push");
1138
+ }
1139
+ }
1140
+ else {
1141
+ if (!installed)
1142
+ steps.push(`${result.packageManager} install`);
1143
+ if (!binariesReady)
1144
+ steps.push("supatype update # download component binaries");
1145
+ if (!keysGenerated)
1146
+ steps.push("supatype keys");
1147
+ steps.push(kongHint);
1148
+ steps.push("supatype push # apply schema + generate types");
974
1149
  }
975
1150
  if (result.helloFunction) {
976
1151
  steps.push("supatype functions serve # run edge functions locally");
977
1152
  }
978
1153
  info(`Supatype project ready${name ? ` in ${name}/` : ""}.`);
979
- nextSteps("Next steps:", steps);
1154
+ nextSteps(setupComplete ? "Next steps:" : "Finish setup:", steps);
980
1155
  if (result.app.mode === "none") {
981
1156
  nextSteps("Static frontend (self-host):", [
982
1157
  "supatype app add --static ./public",