@xanots/sdk 0.0.3-beta.0 → 0.0.4

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 (88) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +35 -2
  3. package/dist/agent-file-refresh-IJ7GN2FJ.js +17 -0
  4. package/dist/bin.js +12 -153
  5. package/dist/{capture-HUV5BNTC.js → capture-7PO6SGB4.js} +2 -2
  6. package/dist/{chunk-WRYT2PAX.js → chunk-7SISR3CS.js} +24 -36
  7. package/dist/{chunk-7DKX2SPN.js → chunk-ACQCK4DT.js} +4 -4
  8. package/dist/{chunk-XQ22GLYS.js → chunk-AJ7JQ4OU.js} +5 -5
  9. package/dist/{chunk-EWFHDJY5.js → chunk-ALNQCWAW.js} +2 -2
  10. package/dist/{chunk-55VHDNW5.js → chunk-BPEEGJJA.js} +108 -3
  11. package/dist/{chunk-U3G2UW65.js → chunk-CYJ7R3AD.js} +3 -3
  12. package/dist/{agent-file-refresh-J3KY54E5.js → chunk-D6OGU2AI.js} +5 -6
  13. package/dist/{chunk-VVXPK6SE.js → chunk-DUC3PXDG.js} +150 -45
  14. package/dist/{chunk-4HKZH6YK.js → chunk-EAIR6VUL.js} +235 -10
  15. package/dist/chunk-ERQZFWIW.js +22 -0
  16. package/dist/{chunk-TQUO2OXY.js → chunk-FN4OQT2J.js} +4 -4
  17. package/dist/{chunk-FY6LXRR6.js → chunk-KGNJM4LN.js} +2 -2
  18. package/dist/{chunk-HJPTWBLH.js → chunk-MFIHIS6B.js} +2 -2
  19. package/dist/{chunk-F6JCFRKO.js → chunk-PXXLBXOP.js} +2 -2
  20. package/dist/{chunk-YZ4GU6F5.js → chunk-QUUB7HYK.js} +5 -838
  21. package/dist/{chunk-HKAX756N.js → chunk-SWIXWJIY.js} +3 -3
  22. package/dist/{chunk-76QBEIGO.js → chunk-T4XPCJRF.js} +3 -2
  23. package/dist/chunk-T6N3VMMO.js +173 -0
  24. package/dist/{chunk-CBL57QBQ.js → chunk-VKD3EBKG.js} +112 -21
  25. package/dist/{chunk-MWLNBSTY.js → chunk-VWGJQTNA.js} +3 -3
  26. package/dist/chunk-WGDAOOXG.js +845 -0
  27. package/dist/{chunk-4YMD2OOZ.js → chunk-XHEXOES3.js} +1 -1
  28. package/dist/{chunk-4HT3BNZ7.js → chunk-YUBJLB6G.js} +10 -2
  29. package/dist/{chunk-5L4X5LS6.js → chunk-YUPQOLFX.js} +77 -2
  30. package/dist/{chunk-QO4I5OYF.js → chunk-YYSJAAJM.js} +36 -3
  31. package/dist/{chunk-P3TTMWUP.js → chunk-ZOYMZZ3S.js} +8 -1
  32. package/dist/chunk-ZSYZTGJH.js +81 -0
  33. package/dist/cli.d.ts +15 -0
  34. package/dist/cli.js +8 -8
  35. package/dist/{codegen-command-EXLKZ2ZI.js → codegen-command-Z7WQMOJ7.js} +21 -20
  36. package/dist/{completion-2PVZK6YX.js → completion-4GYN752B.js} +2 -2
  37. package/dist/{deploy-command-SXX6RJWM.js → deploy-command-M2S4HHLC.js} +26 -26
  38. package/dist/{env-target-3EGIPR4D.js → env-target-GSFCYHKZ.js} +6 -6
  39. package/dist/{ephemeral-command-OGOYP7D6.js → ephemeral-command-6WJW7LP6.js} +24 -24
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.js +13 -7
  42. package/dist/init-command-GJUPWTKA.js +30 -0
  43. package/dist/internal.d.ts +2 -2
  44. package/dist/internal.js +53 -7
  45. package/dist/{io-AMIKRLPC.js → io-7VIA5SON.js} +3 -3
  46. package/dist/{live-diff-RXSJCVJ7.js → live-diff-FP4SFNT4.js} +2 -2
  47. package/dist/{lock-3CVKALKT.js → lock-KXOJIGCG.js} +2 -2
  48. package/dist/{lock-commands-R22J54XV.js → lock-commands-7IH7RSSP.js} +9 -9
  49. package/dist/{login-command-ACJF6KWQ.js → login-command-QM5SBBI2.js} +2 -2
  50. package/dist/{logout-command-MX3MJS5U.js → logout-command-THPASOHM.js} +2 -2
  51. package/dist/{loop-SAWAOUFO.js → loop-7SAIGRCZ.js} +3 -3
  52. package/dist/{marketplace-command-XJIWL4YP.js → marketplace-command-463DT7O7.js} +11 -25
  53. package/dist/meta-client-OW5WKWW7.js +1 -1
  54. package/dist/node.d.ts +2 -2
  55. package/dist/node.js +18 -12
  56. package/dist/onboard-command-EHOHKQQU.js +36 -0
  57. package/dist/{profile-command-SWJ3SPKR.js → profile-command-EUWPVWED.js} +6 -6
  58. package/dist/{release-command-6PLMLGDK.js → release-command-M4CVNTWL.js} +25 -25
  59. package/dist/{sandbox-details-command-HJE5SPVG.js → sandbox-details-command-BRII3QHG.js} +5 -5
  60. package/dist/{sandbox-export-command-QCJY4GMV.js → sandbox-export-command-PCZ5FL4U.js} +8 -8
  61. package/dist/scaffold.js +4 -2
  62. package/dist/{store-g45zwB33.d.ts → store-BJONDJoZ.d.ts} +171 -2
  63. package/dist/{test-command-LLPXKT35.js → test-command-U4G5Y3UM.js} +10 -10
  64. package/dist/upgrade-command-CKJ4BS2P.js +177 -0
  65. package/dist/{validate-command-WAT3ZJT3.js → validate-command-S5N37JRP.js} +12 -12
  66. package/dist/{workspace-command-JKMI7RZ4.js → workspace-command-RALSEJSW.js} +28 -27
  67. package/dist/workspace-export-AJMGN3CQ.js +1 -1
  68. package/guides/README.md +30 -0
  69. package/guides/authoring.md +642 -0
  70. package/guides/cli.md +191 -0
  71. package/guides/codegen.md +83 -0
  72. package/guides/coverage.md +67 -0
  73. package/guides/deploying.md +340 -0
  74. package/guides/environment.md +132 -0
  75. package/guides/object-kinds.md +376 -0
  76. package/guides/project-structure.md +43 -0
  77. package/guides/scaffold.md +198 -0
  78. package/guides/typed-frontend.md +201 -0
  79. package/llms/kinds-agent-mcp.md +2 -1
  80. package/llms/kinds-knowledge.md +20 -0
  81. package/llms/object-kinds.md +1 -0
  82. package/llms-full.txt +27 -3
  83. package/llms.txt +3 -2
  84. package/manifest.json +30 -3
  85. package/package.json +5 -2
  86. package/dist/.build-fingerprint +0 -1
  87. package/dist/chunk-47WDWMBJ.js +0 -14
  88. package/dist/init-command-6DGXEVZD.js +0 -29
@@ -0,0 +1,845 @@
1
+ import {
2
+ renderThemeScript
3
+ } from "./chunk-QUUB7HYK.js";
4
+ import {
5
+ defaultThemeChoice,
6
+ iconLibraryOf,
7
+ reactPreset
8
+ } from "./chunk-6DHJVLYP.js";
9
+
10
+ // src/emit/frontend-svelte.ts
11
+ var CODE_CLASS = "bg-muted rounded px-1.5 py-0.5 font-mono text-sm";
12
+ function htmlText(s) {
13
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
14
+ }
15
+ function svelteText(s) {
16
+ return htmlText(s).replace(/\{/g, "&#123;").replace(/\}/g, "&#125;");
17
+ }
18
+ function renderNode(node) {
19
+ return "code" in node ? `<code class="${CODE_CLASS}">${svelteText(node.code)}</code>` : svelteText(node.text);
20
+ }
21
+ function renderNodes(nodes) {
22
+ return nodes.map(renderNode).join("");
23
+ }
24
+ function renderApp(landing, choice) {
25
+ const steps = landing.steps.map((step) => ` <li>${renderNodes(step)}</li>`).join("\n");
26
+ const toggle = choice.dark === "toggle";
27
+ const icons = iconLibraryOf(choice.icons).svelte;
28
+ return `<script lang="ts">
29
+ ${icons.arrowImport}
30
+
31
+ import { Button } from "$lib/components/ui/button/index.js";
32
+ import * as Card from "$lib/components/ui/card/index.js";${toggle ? `
33
+ import ModeToggle from "$lib/components/mode-toggle.svelte";` : ""}
34
+ </script>
35
+
36
+ <main class="mx-auto flex min-h-screen max-w-2xl flex-col justify-center p-8">${toggle ? `
37
+ <div class="mb-4 flex justify-end">
38
+ <ModeToggle />
39
+ </div>` : ""}
40
+ <Card.Root>
41
+ <Card.Header>
42
+ <Card.Title class="text-3xl tracking-tight">${svelteText(landing.title)}</Card.Title>
43
+ <Card.Description class="text-base">
44
+ ${renderNodes(landing.lead)}
45
+ </Card.Description>
46
+ </Card.Header>
47
+ <Card.Content>
48
+ <ol class="text-muted-foreground list-inside list-decimal space-y-2">
49
+ ${steps}
50
+ </ol>
51
+ </Card.Content>
52
+ <Card.Footer>
53
+ <!-- Components come from shadcn-svelte \u2014 add more with
54
+ \`npx shadcn-svelte@latest add <name>\`. -->
55
+ <Button href="${landing.cta.href}" target="_blank" rel="noreferrer">
56
+ ${svelteText(landing.cta.label)}
57
+ <${icons.arrowComponent} />
58
+ </Button>
59
+ </Card.Footer>
60
+ </Card.Root>
61
+ </main>
62
+ `;
63
+ }
64
+ function renderSvelteKitPlugin() {
65
+ return `sveltekit({
66
+ // RUNES MODE, FORCED \u2014 not left to Svelte 5's per-component detection.
67
+ //
68
+ // By default a component that uses \`export let\` and \`<slot>\` simply
69
+ // compiles in legacy mode and works, so the Svelte 4 API an assistant
70
+ // reaches for from older training data produces no error at all. Pinning
71
+ // runes here turns that into a compile failure naming the file, which is
72
+ // the same guidance the agent brief gives, enforced instead of stated.
73
+ //
74
+ // \`node_modules\` is exempted (returning undefined restores detection):
75
+ // an installed library compiles under whatever mode ITS author wrote for,
76
+ // and forcing ours onto it would break dependencies this project does not
77
+ // own. Removable in Svelte 6, where runes stop being opt-in.
78
+ compilerOptions: {
79
+ runes: ({ filename }) =>
80
+ filename.split(/[/\\\\]/).includes("node_modules") ? undefined : true,
81
+ },
82
+ // No \`preprocess\`. vite-plugin-svelte 7 compiles \`<script lang="ts">\`
83
+ // itself, so \`vitePreprocess()\` is the no-op it looks like \u2014 \`sv create\`
84
+ // emits none either. Verified against a real build: components typecheck
85
+ // and compile without it.
86
+ //
87
+ // The deploy target is a static host with NO server runtime \u2014 Xano is the
88
+ // backend. Routes are PRERENDERED (see frontend/src/routes/+layout.ts):
89
+ // each becomes its own HTML file at build time, and the host resolves a URL
90
+ // to it by trying the exact key, then \`{path}.html\`, then
91
+ // \`{path}/index.html\`. That is why no \`trailingSlash\` is configured \u2014 both
92
+ // output shapes resolve, so this stays on SvelteKit's default.
93
+ //
94
+ // NO \`fallback\`. It looks harmless \u2014 it used to be how every URL got served
95
+ // \u2014 but adapter-static writes the fallback shell AT index.html, overwriting
96
+ // the prerendered home page with an empty document. Measured on a real
97
+ // build: 1936 bytes of empty shell instead of 4920 bytes of rendered page,
98
+ // on the most-visited route in the app.
99
+ //
100
+ // Dropping it also gets the better failure. With no fallback, adapter-static
101
+ // is \`strict\` by default, so a route it cannot prerender (a dynamic \`[id]\`
102
+ // with no \`entries\`) FAILS THE BUILD with a message naming the route \u2014
103
+ // instead of shipping and 404ing for real users.
104
+ //
105
+ // \`xanots deploy --static-env\` still finds its anchor: every prerendered
106
+ // route renders from app.html, so each document has a <head> and each one
107
+ // gets the injected globals.
108
+ adapter: adapter({
109
+ pages: "frontend/dist",
110
+ assets: "frontend/dist",
111
+ precompress: false,
112
+ }),
113
+ // Absolute asset URLs, pinned rather than left to the default. Prerendered
114
+ // pages live at varying URL depths, and a relative \`../_app/\u2026\` computed for
115
+ // one depth 404s at another.
116
+ paths: { relative: false },
117
+ prerender: {
118
+ // A hash link in the shared layout \u2014 \`<a href="#services">\`, the default
119
+ // shape of a one-page site's nav \u2014 renders into EVERY prerendered route,
120
+ // including the scaffold's own /404. There it resolves to /404#services,
121
+ // an anchor that by definition is not on that page, and SvelteKit's
122
+ // default handler THROWS: the vite build succeeds and the prerender pass
123
+ // after it kills the build, with a stack trace naming only files inside
124
+ // node_modules and a route the author never wrote.
125
+ //
126
+ // So ignore a missing id on /404 specifically, rather than reaching for a
127
+ // blanket \`handleMissingId: "warn"\`. A hash link that is genuinely broken
128
+ // on a real route still fails the build, which is the check worth keeping.
129
+ handleMissingId: ({ path, message }) => {
130
+ if (path === "/404") return;
131
+ throw new Error(message);
132
+ },
133
+ },
134
+ // SvelteKit's project layout, redirected under frontend/ so this stays a
135
+ // single-root project: one package.json, one tsconfig.json, and xano/
136
+ // sitting alongside as the backend half. NOTE these are what make
137
+ // frontend/src/routes the routes directory \u2014 a file added under a
138
+ // top-level src/routes/ is not a route and will not be served.
139
+ files: {
140
+ routes: "frontend/src/routes",
141
+ lib: "frontend/src/lib",
142
+ appTemplate: "frontend/src/app.html",
143
+ assets: "frontend/static",
144
+ },
145
+ })`;
146
+ }
147
+ function renderAppHtml({ appName }, choice) {
148
+ return `<!doctype html>
149
+ <html lang="en">
150
+ <head>
151
+ <meta charset="utf-8" />
152
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
153
+ <title>${htmlText(appName)}</title>
154
+ ${renderThemeScript(choice.dark)}
155
+ <!-- Drop a favicon.png into frontend/static/ and link it here:
156
+ <link rel="icon" href="%sveltekit.assets%/favicon.png" />
157
+ Everything in that directory is copied to the site root verbatim. -->
158
+ <!-- Keep this inside <head>: \`xanots deploy --static-env\` injects the
159
+ backend URL here as a window global that frontend/src/lib/api.ts reads. -->
160
+ %sveltekit.head%
161
+ </head>
162
+ <body data-sveltekit-preload-data="hover">
163
+ <div style="display: contents">%sveltekit.body%</div>
164
+ </body>
165
+ </html>
166
+ `;
167
+ }
168
+ function renderModeToggleSvelte(icons) {
169
+ return `<script lang="ts">
170
+ ${icons.modeImports.join("\n ")}
171
+
172
+ import { Button } from "$lib/components/ui/button/index.js";
173
+ import { getMode, setMode, watchMode, type Mode } from "$lib/theme.js";
174
+
175
+ /** system \u2192 light \u2192 dark \u2192 system. */
176
+ const next: Record<Mode, Mode> = { system: "light", light: "dark", dark: "system" };
177
+
178
+ const icons = {
179
+ system: ${icons.modeComponents.system},
180
+ light: ${icons.modeComponents.light},
181
+ dark: ${icons.modeComponents.dark},
182
+ };
183
+
184
+ // Starts at "system" so the prerendered HTML is deterministic; the effect
185
+ // corrects it in the browser, after the inline script has already applied
186
+ // the right class.
187
+ let mode = $state<Mode>("system");
188
+
189
+ $effect(() => {
190
+ mode = getMode();
191
+ return watchMode((m) => (mode = m));
192
+ });
193
+
194
+ function change() {
195
+ const target = next[mode];
196
+ setMode(target);
197
+ mode = target;
198
+ }
199
+
200
+ const Icon = $derived(icons[mode]);
201
+ </script>
202
+
203
+ <Button variant="ghost" size="icon" onclick={change} aria-label="Switch to {next[mode]} theme">
204
+ <Icon />
205
+ </Button>
206
+ `;
207
+ }
208
+ function renderAppDts() {
209
+ return `// See https://svelte.dev/docs/kit/types#app.d.ts
210
+ declare global {
211
+ namespace App {
212
+ // interface Error {}
213
+ // interface Locals {}
214
+ // interface PageData {}
215
+ // interface PageState {}
216
+ // interface Platform {}
217
+ }
218
+ }
219
+
220
+ export {};
221
+ `;
222
+ }
223
+ function renderLayoutTs() {
224
+ return `// There is no server. The backend is Xano, reached through $lib/api.ts,
225
+ // and \`npm run xano:deploy\` ships this app to a static host with no runtime.
226
+ //
227
+ // prerender: true \u2014 every route is rendered to its own HTML file AT BUILD TIME
228
+ // and served as a real document. That is what makes each page load as itself
229
+ // rather than as an empty shell that fills in afterwards.
230
+ //
231
+ // Prerendering IS server-rendering, just at build time rather than per request.
232
+ // So module-scope \`window\`/\`document\` access now fails the BUILD instead of the
233
+ // browser \u2014 which is the better place to find out. Reach for browser globals
234
+ // inside onMount, or guard with \`import { browser } from "$app/environment"\`.
235
+ //
236
+ // A route with dynamic segments (e.g. /posts/[id]) cannot be prerendered unless
237
+ // the build knows which ones exist, so THE BUILD FAILS and names the route.
238
+ // That is deliberate \u2014 better than shipping a page that 404s for real users.
239
+ // Give it entries, in that route's +page.ts:
240
+ //
241
+ // export const entries = () => [{ id: "1" }, { id: "2" }];
242
+ //
243
+ // Inherited by every route below this one.
244
+ export const prerender = true;
245
+ `;
246
+ }
247
+ function renderErrorState() {
248
+ return `<script lang="ts">
249
+ // Shared by the prerendered /404 route and +error.svelte.
250
+ let { status = 404, message = "" }: { status?: number; message?: string } = $props();
251
+ </script>
252
+
253
+ <main class="grid min-h-screen place-items-center p-8">
254
+ <div class="max-w-md space-y-4 text-center">
255
+ <p class="text-6xl font-semibold tracking-tight">{status}</p>
256
+ <h1 class="text-xl font-medium">
257
+ {status === 404 ? "We can't find that page." : "Something went wrong."}
258
+ </h1>
259
+ <p class="text-muted-foreground text-sm">
260
+ {message !== "" ? message : "The link may be broken, or the page may have moved."}
261
+ </p>
262
+ <a
263
+ href="/"
264
+ class="bg-primary text-primary-foreground ring-offset-background focus-visible:ring-ring inline-flex h-10 items-center rounded-md px-5 text-sm font-medium transition-opacity hover:opacity-90 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
265
+ >
266
+ Back to safety
267
+ </a>
268
+ </div>
269
+ </main>
270
+ `;
271
+ }
272
+ function renderNotFoundRoute() {
273
+ return `<script lang="ts">
274
+ // Prerendered to 404.html, which is what tells the static host to answer an
275
+ // unmatched path with a real 404 instead of quietly serving the app shell
276
+ // with a 200 (a missing asset would then reach the browser as HTML, which it
277
+ // reports as "Unexpected token '<'").
278
+ //
279
+ // It must be a route, not +error.svelte: SvelteKit never prerenders the error
280
+ // component to a file, so relying on it would ship no 404.html at all.
281
+ //
282
+ // Delete this directory and an unmatched path serves the home page with a 200
283
+ // instead \u2014 which is worse, not better, so keep it unless you have a reason.
284
+ import ErrorState from "$lib/components/error-state.svelte";
285
+ </script>
286
+
287
+ <svelte:head>
288
+ <title>Page not found</title>
289
+ </svelte:head>
290
+
291
+ <ErrorState status={404} />
292
+ `;
293
+ }
294
+ function renderErrorSvelte() {
295
+ return `<script lang="ts">
296
+ // Rendered when a client-side navigation or load fails inside the running
297
+ // app. The static host never sees these \u2014 for a path that matched no
298
+ // document at all, it serves the prerendered routes/404 page instead.
299
+ import { page } from "$app/state";
300
+ import ErrorState from "$lib/components/error-state.svelte";
301
+ </script>
302
+
303
+ <svelte:head>
304
+ <title>{page.status === 404 ? "Page not found" : "Something went wrong"}</title>
305
+ </svelte:head>
306
+
307
+ <ErrorState status={page.status} message={page.error?.message ?? ""} />
308
+ `;
309
+ }
310
+ function renderLayoutSvelte() {
311
+ return `<script lang="ts">
312
+ // The shared token stylesheet \u2014 semantic colors (bg-primary,
313
+ // text-muted-foreground) plus the Tailwind v4 theme. Imported once here so
314
+ // every route gets it.
315
+ import "../index.css";
316
+
317
+ let { children } = $props();
318
+ </script>
319
+
320
+ {@render children()}
321
+ `;
322
+ }
323
+ function renderComponentsJson(choice) {
324
+ const config = {
325
+ $schema: "https://shadcn-svelte.com/schema.json",
326
+ tailwind: {
327
+ // v4 has no config file; the theme lives in the stylesheet — the same
328
+ // shared one the React preset points at.
329
+ css: "frontend/src/index.css",
330
+ // Tracks the theme the stylesheet was rendered from — see the React
331
+ // preset's note; the shadcn-svelte CLI reads it the same way.
332
+ baseColor: choice.theme.baseColor ?? "neutral"
333
+ },
334
+ aliases: {
335
+ components: "$lib/components",
336
+ utils: "$lib/utils",
337
+ ui: "$lib/components/ui",
338
+ hooks: "$lib/hooks",
339
+ lib: "$lib"
340
+ },
341
+ typescript: true,
342
+ registry: "https://shadcn-svelte.com/registry"
343
+ };
344
+ return JSON.stringify(config, null, 2) + "\n";
345
+ }
346
+ function renderButtonSvelte() {
347
+ return `<script lang="ts" module>
348
+ import { type VariantProps, tv } from "tailwind-variants";
349
+
350
+ export const buttonVariants = tv({
351
+ base: "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
352
+ variants: {
353
+ variant: {
354
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
355
+ destructive:
356
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
357
+ outline:
358
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
359
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
360
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
361
+ link: "text-primary underline-offset-4 hover:underline",
362
+ },
363
+ size: {
364
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
365
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
366
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
367
+ icon: "size-9",
368
+ },
369
+ },
370
+ defaultVariants: {
371
+ variant: "default",
372
+ size: "default",
373
+ },
374
+ });
375
+
376
+ export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
377
+ export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
378
+
379
+ export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
380
+ WithElementRef<HTMLAnchorAttributes> & {
381
+ variant?: ButtonVariant;
382
+ size?: ButtonSize;
383
+ };
384
+ </script>
385
+
386
+ <script lang="ts">
387
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
388
+ import type { WithElementRef } from "bits-ui";
389
+ import { cn } from "$lib/utils.js";
390
+
391
+ let {
392
+ class: className,
393
+ variant = "default",
394
+ size = "default",
395
+ ref = $bindable(null),
396
+ href = undefined,
397
+ type = "button",
398
+ children,
399
+ ...restProps
400
+ }: ButtonProps = $props();
401
+ </script>
402
+
403
+ {#if href}
404
+ <a
405
+ bind:this={ref}
406
+ data-slot="button"
407
+ class={cn(buttonVariants({ variant, size }), className)}
408
+ {href}
409
+ {...restProps}
410
+ >
411
+ {@render children?.()}
412
+ </a>
413
+ {:else}
414
+ <button
415
+ bind:this={ref}
416
+ data-slot="button"
417
+ class={cn(buttonVariants({ variant, size }), className)}
418
+ {type}
419
+ {...restProps}
420
+ >
421
+ {@render children?.()}
422
+ </button>
423
+ {/if}
424
+ `;
425
+ }
426
+ function renderButtonIndex() {
427
+ return `export {
428
+ default as Button,
429
+ buttonVariants,
430
+ type ButtonProps,
431
+ type ButtonSize,
432
+ type ButtonVariant,
433
+ } from "./button.svelte";
434
+ `;
435
+ }
436
+ function cardPart(slot, tag, classes) {
437
+ return `<script lang="ts">
438
+ import type { HTMLAttributes } from "svelte/elements";
439
+ import type { WithElementRef } from "bits-ui";
440
+ import { cn } from "$lib/utils.js";
441
+
442
+ let {
443
+ class: className,
444
+ ref = $bindable(null),
445
+ children,
446
+ ...restProps
447
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
448
+ </script>
449
+
450
+ <${tag}
451
+ bind:this={ref}
452
+ data-slot="${slot}"
453
+ class={cn("${classes}", className)}
454
+ {...restProps}
455
+ >
456
+ {@render children?.()}
457
+ </${tag}>
458
+ `;
459
+ }
460
+ function renderCardIndex() {
461
+ return `import Root from "./card.svelte";
462
+ import Content from "./card-content.svelte";
463
+ import Description from "./card-description.svelte";
464
+ import Footer from "./card-footer.svelte";
465
+ import Header from "./card-header.svelte";
466
+ import Title from "./card-title.svelte";
467
+
468
+ export {
469
+ Root,
470
+ Content,
471
+ Description,
472
+ Footer,
473
+ Header,
474
+ Title,
475
+ //
476
+ Root as Card,
477
+ Content as CardContent,
478
+ Description as CardDescription,
479
+ Footer as CardFooter,
480
+ Header as CardHeader,
481
+ Title as CardTitle,
482
+ };
483
+ `;
484
+ }
485
+ var sveltePreset = {
486
+ id: "svelte",
487
+ label: "SvelteKit",
488
+ dependencies: {
489
+ // shadcn-svelte's runtime surface. `bits-ui` is the headless primitive
490
+ // library its components are built on (the Radix equivalent), and
491
+ // `tailwind-variants` types the variants (the cva equivalent). clsx +
492
+ // tailwind-merge back `cn()` exactly as in the React preset. Pre-installed
493
+ // so `npx shadcn-svelte@latest add <component>` works without a separate
494
+ // npm i.
495
+ //
496
+ // The icon package is `--icons`, merged in by renderPackageJson from
497
+ // `iconBinding` below — see the React preset's note.
498
+ "bits-ui": "^2.18.1",
499
+ clsx: "^2.1.1",
500
+ "tailwind-merge": "^3.0.1",
501
+ "tailwind-variants": "^3.3.1"
502
+ },
503
+ devDependencies: {
504
+ // Writes the static bundle `deploy --static` ships. Peer-depends on kit ^2.
505
+ "@sveltejs/adapter-static": "^3.0.10",
506
+ // 2.70 peer-accepts vite ^8 and vite-plugin-svelte ^7 — the versions
507
+ // pinned below. Bump this line and those two together.
508
+ "@sveltejs/kit": "^2.70.2",
509
+ // 7.x, matching what `sv create` installs. It peer-requires vite ^8, so
510
+ // this line and the `vite` pin move together or not at all — and the React
511
+ // preset's plugin has the same constraint, which is why the two presets
512
+ // share one Vite major rather than each choosing.
513
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
514
+ "@tailwindcss/vite": "^4.1.5",
515
+ "@types/node": "^20.19.43",
516
+ svelte: "^5.56.9",
517
+ "svelte-check": "^4.7.6",
518
+ tailwindcss: "^4.1.5",
519
+ "tw-animate-css": "^1.2.4",
520
+ tsx: "^4.19.2",
521
+ // 6.x, the major `sv create` pins. svelte-check peer-accepts `^5 || ^6`;
522
+ // 7 is out but not yet in that range, so this tracks the canonical
523
+ // scaffold rather than latest.
524
+ typescript: "^6.0.3",
525
+ vite: "^8.0.16"
526
+ },
527
+ // svelte-check REPLACES `tsc --noEmit` here rather than joining it.
528
+ //
529
+ // It is a superset: reading the same tsconfig, it checks `xano/`'s TypeScript
530
+ // exactly as `tsc` would AND the components `tsc` cannot parse at all. Running
531
+ // both is not merely redundant — `tsc` fails outright on the UI kit's barrels,
532
+ // which re-export types from `.svelte` modules it only knows as default
533
+ // exports. Verified against a real scaffold: a type error planted in
534
+ // `xano/index.ts` and one planted in `App.svelte` are each caught by this
535
+ // command alone.
536
+ //
537
+ // `svelte-kit sync` runs first, and is not optional: it generates
538
+ // `.svelte-kit/tsconfig.json` (which the project's tsconfig extends) and the
539
+ // route types. Without it svelte-check fails on a missing extends target
540
+ // rather than on anything the user wrote.
541
+ checkCmd: "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
542
+ // SvelteKit supplies `$lib` on both sides — the Vite alias from its plugin
543
+ // and the tsconfig path from the config it generates. Declaring either by
544
+ // hand would be a second source of truth that can silently disagree.
545
+ aliasName: null,
546
+ aliasTarget: "frontend/src/lib",
547
+ tsconfigPaths: {},
548
+ tsconfigExtends: "./.svelte-kit/tsconfig.json",
549
+ // What `svelte-kit sync` generates and the extended config lists — re-added
550
+ // because our `include` replaces that config's rather than merging with it.
551
+ // These are the declarations behind `$app/*`, `$env/*`, and `./$types`.
552
+ tsconfigInclude: [
553
+ ".svelte-kit/ambient.d.ts",
554
+ ".svelte-kit/env.d.ts",
555
+ ".svelte-kit/non-ambient.d.ts",
556
+ ".svelte-kit/types/**/$types.d.ts"
557
+ ],
558
+ // `prepare` runs on `npm install`, so a fresh clone has `.svelte-kit/`
559
+ // before anything reads tsconfig.json.
560
+ extraScripts: { prepare: "svelte-kit sync" },
561
+ // shadcn-svelte's generated components import these from `$lib/utils.js`
562
+ // alongside `cn()`. Without them the scaffold type-checks until the first
563
+ // `npx shadcn-svelte@latest add <name>` — which the agent guidance tells
564
+ // assistants to run — and then fails inside components the user never wrote,
565
+ // with an error naming a file they have no reason to suspect.
566
+ //
567
+ // Verbatim from shadcn-svelte's own utils.ts, so a component the CLI writes
568
+ // resolves against exactly what upstream expects.
569
+ libUtilsExtra: `
570
+ export type WithoutChild<T> = T extends { child?: any } ? Omit<T, "child"> : T;
571
+ export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, "children"> : T;
572
+ export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
573
+ export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
574
+ `,
575
+ gitignoreEntries: [".svelte-kit/"],
576
+ // No `jsx`. `verbatimModuleSyntax` is what svelte-check expects so that
577
+ // type-only imports in components are erased rather than emitted.
578
+ tsconfigOptions: { verbatimModuleSyntax: true },
579
+ viteImports: [
580
+ `import { sveltekit } from "@sveltejs/kit/vite";`,
581
+ `import adapter from "@sveltejs/adapter-static";`,
582
+ `import tailwindcss from "@tailwindcss/vite";`
583
+ ],
584
+ // tailwindcss() before sveltekit() — the order Tailwind v4 documents for
585
+ // SvelteKit, so the stylesheet is processed before Kit consumes the graph.
586
+ //
587
+ // The whole SvelteKit config rides in the sveltekit() call. There is no
588
+ // svelte.config.js by design — see renderSvelteKitPlugin().
589
+ vitePlugins: ["tailwindcss()", renderSvelteKitPlugin()],
590
+ // SvelteKit resolves its own paths from this file's directory and redirects
591
+ // them into frontend/ via `files`; moving Vite's root under it puts the two
592
+ // into disagreement. Output is the adapter's job, not `build.outDir`.
593
+ viteRoot: null,
594
+ viteBuild: null,
595
+ // SvelteKit owns the page template — frontend/src/app.html. No `entryScript`
596
+ // follows: there is no shared index.html for it to point at.
597
+ ownsHtmlEntry: true,
598
+ files(vars, landing, choice = defaultThemeChoice()) {
599
+ const ui = "frontend/src/lib/components/ui";
600
+ return [
601
+ { path: "components.json", content: renderComponentsJson(choice) },
602
+ { path: "frontend/src/app.html", content: renderAppHtml(vars, choice) },
603
+ // Only for `--dark toggle` — see the React preset's note.
604
+ ...choice.dark === "toggle" ? [
605
+ {
606
+ path: "frontend/src/lib/components/mode-toggle.svelte",
607
+ content: renderModeToggleSvelte(iconLibraryOf(choice.icons).svelte)
608
+ }
609
+ ] : [],
610
+ { path: "frontend/src/app.d.ts", content: renderAppDts() },
611
+ { path: "frontend/src/routes/+layout.ts", content: renderLayoutTs() },
612
+ { path: "frontend/src/routes/+layout.svelte", content: renderLayoutSvelte() },
613
+ { path: "frontend/src/routes/+page.svelte", content: renderApp(landing, choice) },
614
+ { path: "frontend/src/routes/+error.svelte", content: renderErrorSvelte() },
615
+ { path: "frontend/src/routes/404/+page.svelte", content: renderNotFoundRoute() },
616
+ { path: "frontend/src/lib/components/error-state.svelte", content: renderErrorState() },
617
+ // `kit.files.assets` points here: static files copied to the site root
618
+ // verbatim. A README rather than a .gitkeep because this one gets
619
+ // PUBLISHED — everything here lands in frontend/dist, so the placeholder
620
+ // that keeps the directory in git is a file real users will see deployed.
621
+ {
622
+ path: "frontend/static/README.md",
623
+ content: `Files here are copied to the site root as-is \u2014 \`favicon.png\` is served
624
+ at \`/favicon.png\`. Reference them from a component with a root-relative
625
+ path, or from \`app.html\` via \`%sveltekit.assets%\`.
626
+
627
+ Delete this file once you add something real.
628
+ `
629
+ },
630
+ { path: `${ui}/button/button.svelte`, content: renderButtonSvelte() },
631
+ { path: `${ui}/button/index.ts`, content: renderButtonIndex() },
632
+ {
633
+ path: `${ui}/card/card.svelte`,
634
+ content: cardPart(
635
+ "card",
636
+ "div",
637
+ "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm"
638
+ )
639
+ },
640
+ {
641
+ path: `${ui}/card/card-header.svelte`,
642
+ content: cardPart(
643
+ "card-header",
644
+ "div",
645
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6"
646
+ )
647
+ },
648
+ {
649
+ path: `${ui}/card/card-title.svelte`,
650
+ content: cardPart("card-title", "div", "leading-none font-semibold")
651
+ },
652
+ {
653
+ path: `${ui}/card/card-description.svelte`,
654
+ content: cardPart("card-description", "div", "text-sm text-muted-foreground")
655
+ },
656
+ {
657
+ path: `${ui}/card/card-content.svelte`,
658
+ content: cardPart("card-content", "div", "px-6")
659
+ },
660
+ {
661
+ path: `${ui}/card/card-footer.svelte`,
662
+ content: cardPart("card-footer", "div", "flex items-center px-6 [.border-t]:pt-6")
663
+ },
664
+ { path: `${ui}/card/index.ts`, content: renderCardIndex() }
665
+ ];
666
+ },
667
+ iconBinding(id) {
668
+ return iconLibraryOf(id).svelte;
669
+ },
670
+ readmeFrontendSection(icons) {
671
+ return `[SvelteKit](https://svelte.dev/docs/kit) with Svelte 5, styled with
672
+ [Tailwind CSS](https://tailwindcss.com) v4 and
673
+ [shadcn-svelte](https://shadcn-svelte.com).
674
+
675
+ Pages live in [\`frontend/src/routes/\`](frontend/src/routes/) \u2014 \`+page.svelte\`
676
+ is a page, a subdirectory is a nested route. Routes are **prerendered**: each
677
+ becomes its own HTML document at build time, so a page loads as itself rather
678
+ than as a shell that fills in afterwards, and an unmatched path returns a real
679
+ 404 from [\`+error.svelte\`](frontend/src/routes/+error.svelte).
680
+
681
+ > **There is no server.** \`npm run xano:deploy\` ships this app to a static host
682
+ > with no runtime of its own; Xano is the backend, reached through
683
+ > [\`frontend/src/lib/api.ts\`](frontend/src/lib/api.ts). So \`+page.server.ts\`,
684
+ > form actions, and server \`load\` have nothing to run on \u2014 and **nothing warns
685
+ > you**: a project using them builds and deploys green, then fails in the
686
+ > browser. Treat them as unavailable. That is the trade \u2014 the backend is
687
+ > authored in [\`xano/\`](xano/) as TypeScript and deployed alongside the
688
+ > frontend, so it is a real backend, just not this one.
689
+ >
690
+ > \`frontend/src/routes/+layout.ts\` sets \`prerender = true\` for the whole app.
691
+ > Because prerendering renders at build time, module-scope \`window\`/\`document\`
692
+ > access now fails the **build** rather than the browser \u2014 use \`onMount\`, or
693
+ > guard with \`import { browser } from "$app/environment"\`.
694
+
695
+ **A dynamic route needs \`entries\`, or the build fails.** A route like
696
+ \`/posts/[id]\` cannot be prerendered unless the build knows which ids exist, so
697
+ the build stops and names it \u2014 deliberately, rather than shipping a page that
698
+ 404s for real users:
699
+
700
+ \`\`\`ts
701
+ // frontend/src/routes/posts/[id]/+page.ts
702
+ export const entries = () => [{ id: "1" }, { id: "2" }];
703
+ \`\`\`
704
+
705
+ [\`frontend/src/routes/404/+page.svelte\`](frontend/src/routes/404/+page.svelte)
706
+ prerenders to \`404.html\`, which is what makes an unmatched path return a real
707
+ 404. It has to be a route: SvelteKit never prerenders \`+error.svelte\` to a file,
708
+ so that alone would ship no \`404.html\` at all.
709
+
710
+ shadcn-svelte is not a dependency \u2014
711
+ its components are copied into
712
+ [\`frontend/src/lib/components/ui/\`](frontend/src/lib/components/ui/) and owned by
713
+ this project, so edit them freely. \`Button\` and \`Card\` are already there; add
714
+ more with:
715
+
716
+ \`\`\`bash
717
+ npx shadcn-svelte@latest add dialog input form
718
+ \`\`\`
719
+
720
+ [\`components.json\`](components.json) is pre-configured, so that works with no
721
+ \`shadcn-svelte init\` step. ${iconLibraryOf(icons).guidance.svelte}
722
+
723
+ \`\`\`ts
724
+ ${iconLibraryOf(icons).svelte.arrowImport}
725
+ \`\`\`
726
+
727
+ [\`frontend/src/routes/+page.svelte\`](frontend/src/routes/+page.svelte) already
728
+ does, and that is the form \`npx shadcn-svelte@latest add\` writes too.
729
+
730
+ Components import through the \`$lib\` alias
731
+ (\`$lib/components/ui/button\`, \`$lib/utils\`), which SvelteKit points at
732
+ \`frontend/src/lib/\` via \`kit.files\` in
733
+ [\`vite.config.ts\`](vite.config.ts) \u2014 there is no \`paths\` entry to keep in
734
+ sync, and adding one would just be a second answer that can disagree.
735
+
736
+ Colors come from the theme tokens in
737
+ [\`frontend/src/index.css\`](frontend/src/index.css) \u2014 see **Theming** below.
738
+
739
+ > \`npm run typecheck\` runs \`svelte-kit sync && svelte-check\`, not \`tsc\`. It
740
+ > checks both halves \u2014 the backend's TypeScript and the components \u2014 where
741
+ > \`tsc\` cannot read \`.svelte\` files at all. Keep it in the script: it is what
742
+ > makes the frontend unable to drift from the backend defs. \`sync\` regenerates
743
+ > \`.svelte-kit/\`, which \`tsconfig.json\` extends; \`npm install\` runs it too.`;
744
+ },
745
+ agentGuidanceSection(icons) {
746
+ return `- \`frontend/src/\` \u2014 the SvelteKit app. Svelte 5 + Tailwind v4 + shadcn-svelte.
747
+ - **There is no server.** This deploys to a static host with no runtime, and
748
+ Xano is the backend. Never write \`+page.server.ts\`, \`+layout.server.ts\`,
749
+ form actions, or server \`load\` \u2014 reach the backend through
750
+ \`frontend/src/lib/api.ts\` instead, and never stand up a second backend here.
751
+ - **The build will not stop you.** A project containing \`+page.server.ts\`
752
+ compiles and deploys green, then fails in the browser on the live site. A
753
+ passing build is not evidence that a server feature works \u2014 there is
754
+ nothing to run it.
755
+ - \`frontend/src/routes/\` \u2014 file-based routing. A page is \`+page.svelte\`, a
756
+ nested route is a subdirectory. **Routes live under \`frontend/src/\`, not a
757
+ top-level \`src/\`** \u2014 \`files\` in the \`sveltekit()\` plugin config in
758
+ \`vite.config.ts\` points SvelteKit here. A file added under a top-level
759
+ \`src/routes/\` is not a route and is never served.
760
+ - **Routes are prerendered.** \`frontend/src/routes/+layout.ts\` sets
761
+ \`prerender = true\` for the whole app, so every route is rendered to its own
762
+ HTML document at build time and served as a real page. A static route needs
763
+ nothing registered \u2014 add \`+page.svelte\` and it works.
764
+ - **Prerendering renders at BUILD time**, so module-scope \`window\`/\`document\`
765
+ access now breaks the build, not the browser. Use \`onMount\`, or guard with
766
+ \`import { browser } from "$app/environment"\`. This is a page option, not a
767
+ server \u2014 do not "fix" it by reaching for \`ssr\` or a server file.
768
+ - **A dynamic route needs \`entries\`, or the build fails.** \`/posts/[id]\`
769
+ cannot be prerendered unless the build knows which ids exist, so the build
770
+ stops and names the route. Export
771
+ \`const entries = () => [{ id: "1" }, { id: "2" }]\` from that route's
772
+ \`+page.ts\`. This is the single most likely thing to catch you out when
773
+ adding a detail page \u2014 and it is a build error, not a runtime surprise, so
774
+ you will see it immediately.
775
+ - \`frontend/src/routes/404/+page.svelte\` prerenders to \`404.html\`, which is
776
+ what makes an unmatched path return a real 404 instead of silently serving a
777
+ page with a 200. Keep it: without it a missing asset comes back as HTML and
778
+ the browser reports \`Unexpected token '<'\`. It has to be a route \u2014 SvelteKit
779
+ never prerenders \`+error.svelte\` to a file, so that alone would ship no
780
+ \`404.html\`.
781
+ - Do NOT add \`fallback\` to the adapter config. It writes an empty shell over
782
+ the prerendered home page, and it turns the un-prerenderable-route build
783
+ error into a silent runtime 404.
784
+ - Data loading: call \`api.ts\` from the component, or from a universal
785
+ \`+page.ts\` \`load\` if you need it before render. Both run in the browser.
786
+ - \`frontend/src/lib/components/ui/\` \u2014 shadcn-svelte components, **copied in and
787
+ owned by this project**. Edit them directly; there is no library to configure
788
+ around.
789
+ - Need one that isn't there? \`npx shadcn-svelte@latest add <name>\` \u2014 do not
790
+ hand-roll it, and do not add a different component library. Note the
791
+ \`-svelte\` suffix: the plain \`shadcn\` CLI writes React and will not work here.
792
+ - ${iconLibraryOf(icons).guidance.svelte.replace(/\n/g, "\n ")}
793
+ - That import form is what \`frontend/src/routes/+page.svelte\` already uses and
794
+ what \`npx shadcn-svelte@latest add\` writes, so matching it keeps what you
795
+ write consistent with what the CLI generates beside it. Do not add another
796
+ icon library and do not paste raw inline \`<svg>\` markup.
797
+ - Import via the \`$lib\` alias (\`$lib/components/ui/button\`, \`$lib/utils\`),
798
+ which SvelteKit generates for both TypeScript and the bundler. Do not add a
799
+ \`paths\` entry for it \u2014 a hand-written one is a second source of truth that
800
+ can disagree with the generated one.
801
+ - Components are Svelte 5 **runes** (\`$props()\`, \`$bindable()\`,
802
+ \`{@render children?.()}\`) \u2014 not the Svelte 4 \`export let\` / slot API. Runes
803
+ mode is FORCED in \`vite.config.ts\`, so \`export let\` is a compile error
804
+ naming the file rather than a component that quietly builds in legacy mode.
805
+ Do not "fix" that error by relaxing \`compilerOptions.runes\` \u2014 write the
806
+ rune.
807
+ - \`npm run typecheck\` runs \`svelte-kit sync && svelte-check\`, which checks both
808
+ \`xano/\` and the components. Do not swap it for \`tsc --noEmit\`: \`tsc\` cannot
809
+ read \`.svelte\` files and fails on the UI kit's barrels. \`sync\` regenerates
810
+ \`.svelte-kit/\`, which \`tsconfig.json\` extends \u2014 run it after adding a route.`;
811
+ }
812
+ };
813
+
814
+ // src/emit/frontend-presets.ts
815
+ var FRAMEWORKS = ["react", "svelte"];
816
+ var DEFAULT_FRAMEWORK = "react";
817
+ var PRESETS = {
818
+ react: reactPreset,
819
+ svelte: sveltePreset
820
+ };
821
+ function findFrontendPreset(id) {
822
+ const normalized = id.trim().toLowerCase();
823
+ return FRAMEWORKS.includes(normalized) ? PRESETS[normalized] : void 0;
824
+ }
825
+ function allFrontendPresets() {
826
+ return FRAMEWORKS.map((id) => PRESETS[id]);
827
+ }
828
+ function resolveFrameworkFlag(raw) {
829
+ const preset = findFrontendPreset(raw);
830
+ if (preset === void 0) {
831
+ throw new Error(
832
+ `Unknown --framework "${raw}". Valid frameworks: ${FRAMEWORKS.join(", ")}.`
833
+ );
834
+ }
835
+ return preset;
836
+ }
837
+
838
+ export {
839
+ FRAMEWORKS,
840
+ DEFAULT_FRAMEWORK,
841
+ findFrontendPreset,
842
+ allFrontendPresets,
843
+ resolveFrameworkFlag
844
+ };
845
+ //# sourceMappingURL=chunk-WGDAOOXG.js.map