@xanots/sdk 0.0.9 → 0.0.11

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 (116) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +66 -21
  3. package/dist/.build-fingerprint +1 -1
  4. package/dist/{agent-file-refresh-4W37DGXS.js → agent-file-refresh-QNKN5RYD.js} +3 -3
  5. package/dist/bin.js +10 -8
  6. package/dist/{branch-commands-PBQ36L4A.js → branch-commands-2BLOC2GR.js} +13 -11
  7. package/dist/bundle.d.ts +218 -0
  8. package/dist/bundle.js +143 -0
  9. package/dist/{capture-7PO6SGB4.js → capture-4WVJY4DQ.js} +2 -2
  10. package/dist/{chunk-OW2QZEWL.js → chunk-22TKBSDV.js} +2 -2
  11. package/dist/{chunk-ZOYMZZ3S.js → chunk-3INK4Y4E.js} +1 -1
  12. package/dist/{chunk-NDZFBZHC.js → chunk-3UABJA4X.js} +1 -1
  13. package/dist/{chunk-6Z5CNWFC.js → chunk-4IF54NU5.js} +37 -6
  14. package/dist/{chunk-KSV7VOEX.js → chunk-4Q7ZOHH7.js} +3 -3
  15. package/dist/{chunk-QTNO2WD6.js → chunk-7ZYW652H.js} +1 -1
  16. package/dist/{chunk-4PTSTDIG.js → chunk-AIZKXUNP.js} +2 -2
  17. package/dist/{chunk-P5C2YKAM.js → chunk-ANUDXFEX.js} +18 -27
  18. package/dist/{chunk-4BXJGVZ3.js → chunk-BC2C5GVI.js} +2 -69
  19. package/dist/chunk-BSK7ELHU.js +70 -0
  20. package/dist/chunk-CTD5ZCV6.js +28 -0
  21. package/dist/{chunk-5HCDZ2XN.js → chunk-DBFU47BJ.js} +2 -2
  22. package/dist/{chunk-OKNSR7MT.js → chunk-DIA7CT7J.js} +129 -150
  23. package/dist/chunk-EHP3WPEG.js +21 -0
  24. package/dist/{chunk-JQLR64UC.js → chunk-F6CYJ7TN.js} +21 -6
  25. package/dist/{chunk-BKDJN76G.js → chunk-FE5I6S6N.js} +1 -1
  26. package/dist/{chunk-5YQOIFT4.js → chunk-G4EJMQLD.js} +2 -2
  27. package/dist/{chunk-L6TPHWAU.js → chunk-HYBN4H3F.js} +60 -86
  28. package/dist/{chunk-QIWBCS7N.js → chunk-JGCWTCA7.js} +2 -2
  29. package/dist/{chunk-MDXR5E5Q.js → chunk-K5IOND4K.js} +2 -2
  30. package/dist/{chunk-4PE4ZAB7.js → chunk-KA6G2L7U.js} +5 -5
  31. package/dist/chunk-OHX6MIUZ.js +184 -0
  32. package/dist/{chunk-UDL46O35.js → chunk-OWGCOGKK.js} +155 -3
  33. package/dist/{chunk-QONOJO45.js → chunk-QK7ZQJLP.js} +140 -20
  34. package/dist/{chunk-3QW5NFZJ.js → chunk-QKM4U5UK.js} +3 -3
  35. package/dist/{chunk-7OXFMCTX.js → chunk-QYMAZRAU.js} +7 -7
  36. package/dist/{chunk-K3YSQDXJ.js → chunk-RCT7UX7B.js} +92 -75
  37. package/dist/{chunk-T4XPCJRF.js → chunk-TCFIPDB3.js} +1 -1
  38. package/dist/{chunk-ZZLPTHT5.js → chunk-UOZMSF4C.js} +15 -8
  39. package/dist/{chunk-7JDT4PBU.js → chunk-VAF6A3YD.js} +5 -179
  40. package/dist/{chunk-6DHBYBTO.js → chunk-VNQM3V2C.js} +1 -2
  41. package/dist/chunk-WGPXT2G2.js +22 -0
  42. package/dist/{chunk-6AAT2AYQ.js → chunk-WP4OZZV4.js} +2 -2
  43. package/dist/{chunk-OYMR5AMJ.js → chunk-XEOX6AM7.js} +2 -2
  44. package/dist/{chunk-MU3O43L2.js → chunk-YBC3IKMF.js} +2 -2
  45. package/dist/chunk-ZQ2PKR6R.js +40 -0
  46. package/dist/cli.d.ts +57 -31
  47. package/dist/cli.js +9 -7
  48. package/dist/codegen-command-FUT2KJB6.js +49 -0
  49. package/dist/codegen.d.ts +2 -1
  50. package/dist/{completion-A6BZ3XGU.js → completion-WF46272M.js} +2 -2
  51. package/dist/{config-NL33PN4D.js → config-476F3PT5.js} +1 -1
  52. package/dist/{deploy-command-5TTI4TUP.js → deploy-command-IP7V7GT4.js} +69 -100
  53. package/dist/{ephemeral-command-7TK52YQM.js → ephemeral-command-U4AQ3TXX.js} +25 -28
  54. package/dist/index.d.ts +6 -4
  55. package/dist/index.js +10 -9
  56. package/dist/init-command-NPVL32L6.js +34 -0
  57. package/dist/{onboard-command-EHOHKQQU.js → init-web-3JNFG6GI.js} +10 -10
  58. package/dist/internal.d.ts +4 -4
  59. package/dist/internal.js +86 -73
  60. package/dist/io-P2H75UV2.js +12 -0
  61. package/dist/{live-diff-QK4KC2FJ.js → live-diff-IXKBVG4K.js} +3 -3
  62. package/dist/{lock-GFXD6G2E.js → lock-46FWYE4D.js} +3 -2
  63. package/dist/{lock-commands-ET7NIOLH.js → lock-commands-ZZKZ4LZJ.js} +23 -21
  64. package/dist/{login-command-DFCURZLC.js → login-command-Z6CHTA57.js} +7 -7
  65. package/dist/{logout-command-WXVZQCAV.js → logout-command-ER6IKAYJ.js} +2 -2
  66. package/dist/{loop-7SAIGRCZ.js → loop-D5NPL4VH.js} +3 -3
  67. package/dist/{marketplace-command-BCOAAN2I.js → marketplace-command-P4IPLJ6J.js} +6 -6
  68. package/dist/{meta-client-57ZWVHST.js → meta-client-K2J4XH64.js} +6 -6
  69. package/dist/node.d.ts +5 -4
  70. package/dist/node.js +15 -13
  71. package/dist/{validate-command-SK5FPCV7.js → preflight-command-K346GPTY.js} +20 -18
  72. package/dist/{profile-command-QJAAUZIV.js → profile-command-LJSBDV2L.js} +5 -5
  73. package/dist/{release-command-4EXVLYV2.js → release-command-IMNTIVWK.js} +42 -38
  74. package/dist/response-BQVQ24l1.d.ts +844 -0
  75. package/dist/{routes-manifest-SP3ZXLMR.js → routes-manifest-PWZHDOI5.js} +2 -2
  76. package/dist/scaffold.js +2 -2
  77. package/dist/{static-host-D6KS7X45.js → static-host-3WMV7IZO.js} +1 -1
  78. package/dist/status-command-AL47VG7H.js +162 -0
  79. package/dist/{store-CUCBSYLj.d.ts → store-BLyNeQ8S.d.ts} +21 -8
  80. package/dist/{test-command-2F5LKMI6.js → test-command-YAZLKLGQ.js} +45 -28
  81. package/dist/{upgrade-command-QL523I62.js → upgrade-command-BN3EHAOI.js} +16 -14
  82. package/dist/{workspace-K72NP7SX.js → workspace-2COHDBM3.js} +1 -1
  83. package/dist/{workspace-command-HYA6JEKK.js → workspace-command-MNK7Y7MQ.js} +36 -34
  84. package/dist/{workspace-export-AJMGN3CQ.js → workspace-export-DURY5WYL.js} +2 -2
  85. package/dist/{response-CVAE2kMj.d.ts → xdo-BjJj5W_E.d.ts} +1 -837
  86. package/guides/README.md +2 -2
  87. package/guides/cli.md +17 -19
  88. package/guides/codegen.md +21 -5
  89. package/guides/coverage.md +1 -1
  90. package/guides/deploying.md +31 -34
  91. package/guides/environment.md +4 -4
  92. package/guides/object-kinds.md +3 -3
  93. package/guides/project-structure.md +1 -1
  94. package/guides/scaffold.md +25 -2
  95. package/guides/typed-frontend.md +2 -2
  96. package/llms/filters.md +11 -10
  97. package/llms/kinds-agent-mcp.md +1 -1
  98. package/llms/kinds-core.md +2 -2
  99. package/llms/kinds-realtime.md +1 -1
  100. package/llms/lock.md +5 -5
  101. package/llms/statements-data.md +3 -1
  102. package/llms/tests.md +1 -1
  103. package/llms/values.md +1 -1
  104. package/llms-full.txt +65 -63
  105. package/llms.txt +40 -41
  106. package/manifest.json +96 -427
  107. package/package.json +7 -2
  108. package/dist/chunk-3EYUR3TX.js +0 -100
  109. package/dist/chunk-JQJPFUZI.js +0 -118
  110. package/dist/chunk-YNZFIY4J.js +0 -78
  111. package/dist/codegen-command-YSCSCVT5.js +0 -43
  112. package/dist/env-target-4T7AT347.js +0 -16
  113. package/dist/init-command-OVFFW4QS.js +0 -30
  114. package/dist/io-M7XZEMK7.js +0 -11
  115. package/dist/sandbox-details-command-EDO56IY3.js +0 -18
  116. package/dist/sandbox-export-command-MO6DEZ7Z.js +0 -24
package/CHANGELOG.md CHANGED
@@ -11,6 +11,40 @@ listed here.
11
11
 
12
12
  ---
13
13
 
14
+ ## 0.0.10 — The CLI surface pass
15
+
16
+ _2026-08-31_ · [release notes](https://github.com/xanots/sdk/releases/tag/v0.0.10)
17
+
18
+ This release is a CLI surface pass, and it is breaking throughout. Six ways to start a project collapse to `init` plus two flags, the sandbox environment is gone with every surface that named it, and a run of commands and flags were renamed to say what they actually do — including three that each carried two or three unrelated meanings. One command is new: `xanots status` answers where you stand in a single read.
19
+
20
+ - ⚠️ Project creation is one command: `init`, with `--from` and `--web`
21
+ - ⚠️ The sandbox environment is gone
22
+ - ⚠️ `deploy` takes no environment flag
23
+ - `xanots status` — who, where, and which environment
24
+ - ⚠️ `validate` is now `preflight`, and `lock adopt` is now `lock import`
25
+ - ⚠️ `--dest` is now `--env`, and names environments the way `--from` does
26
+ - ⚠️ Flags that carried several meanings were split apart
27
+ - `routes` and `whoami` are the canonical spellings
28
+
29
+ ---
30
+
31
+ ## 0.0.9 — Eight reports from real use
32
+
33
+ _2026-08-31_ · [release notes](https://github.com/xanots/sdk/releases/tag/v0.0.9)
34
+
35
+ Eight reports, all from one round of real-world use, and every one of them a case that type-checks, exports under `--strict` and deploys clean before going wrong. The headline is a deploy that could not succeed at all: any seeded number below `1e-4` failed the import with a signature error that named nothing. The rest correct places where the docs described behavior the engine does not have — a search operator that silently matches nothing, a by-id read that rejects the sentinel the field docs prescribe, and a seeding question whose two possible answers demanded opposite designs.
36
+
37
+ - Seed data holding a number below `1e-4` no longer fails the deploy
38
+ - ⚠️ Every test JSON document puts its per-test array under `tests`
39
+ - `like` and `ilike` match nothing for a bare term — reach for `includes`
40
+ - `db.get_by_id` rejects the `0` optional-FK sentinel, and takes the whole request with it
41
+ - A seeded `f.password()` column IS hashed, so demo credentials work as fixtures
42
+ - Native email is discoverable, and the built-in provider needs no configuration
43
+ - A relative entry path names the directory it resolved against
44
+ - Three fields the docs called plain values take tagged ones
45
+
46
+ ---
47
+
14
48
  ## 0.0.8 — The auth() lookalike
15
49
 
16
50
  _2026-08-30_ · [release notes](https://github.com/xanots/sdk/releases/tag/v0.0.8)
package/README.md CHANGED
@@ -119,17 +119,17 @@ The starter backend is empty but already compiles and deploys — grow it from t
119
119
  in `xano/EXAMPLE.md`. For the flags, the two presets, theming, and add-ons, see
120
120
  [The scaffolded project](https://github.com/xanots/sdk/blob/main/guides/scaffold.md).
121
121
 
122
- Prefer to see the theme before you commit to it? `xanots onboard` picks the framework, the
123
- palette, the typefaces and the add-ons in a browser, against a live preview, and hands the
124
- result back to `init` here in your terminal.
122
+ Prefer to see the theme before you commit to it? `--web` picks the framework, the palette,
123
+ the typefaces and the add-ons in a browser, against a live preview, and hands the result
124
+ back to `init` here in your terminal.
125
125
 
126
126
  ```bash
127
- npx @xanots/sdk onboard my-app
127
+ npx @xanots/sdk init my-app --web
128
128
  ```
129
129
 
130
130
  It is a nicer way to arrive at the flags above, not a second scaffolder — it prints the
131
131
  equivalent `init` command when it is done, so the project stays reproducible from a script.
132
- The configurator is downloaded on demand, so `onboard` needs the registry before it can
132
+ The configurator is downloaded on demand, so `--web` needs the registry before it can
133
133
  start; `init` reaches out only to install the new project's dependencies, which
134
134
  `--no-install` skips.
135
135
 
@@ -263,7 +263,7 @@ statements, values, inputs, and middleware are all in the
263
263
 
264
264
  | Command | Where it goes |
265
265
  |---|---|
266
- | `xanots deploy` | A disposable **ephemeral** environment (default) — create-or-refreshed each run, auto-expiring, with its own URL. `--dest sandbox` targets your throwaway singleton instead. |
266
+ | `xanots deploy` | A disposable **ephemeral** environment — create-or-refreshed each run, auto-expiring, with its own URL. There is no other destination and no flag to choose one. |
267
267
  | `xanots release` | Your **main Xano instance** workspace — the production target. **Merges** by default: objects are updated in place or added, and your table data is never touched unless you ask. |
268
268
 
269
269
  Every `deploy` is a **full replace** of the disposable environment — always fresh, no merge
@@ -277,10 +277,15 @@ change, and asks. `--yes` skips the prompt for CI but never skips the preview. S
277
277
  `xanots release ./xano/index.ts --dry-run` to see the plan without committing to it.
278
278
 
279
279
  > ⚠️ A deploy is a full replace of the target environment, **including its table records**,
280
- > before importing. The blast radius is your own disposable ephemeral or sandbox — but
280
+ > before importing. The blast radius is your own disposable ephemeral — but
281
281
  > anything you only ever created by hand in it is gone. That is exactly why production has a
282
282
  > separate `release` path.
283
283
 
284
+ `xanots status` answers where you stand in one read — who you are signed in as, which
285
+ instance and workspace your credential is bound to, and the environment this project last
286
+ deployed to, including whether it is still alive and when it expires. You never have to
287
+ remember the environment's name; it is tracked with the project.
288
+
284
289
  Every flag, the `--prune` rules, the identity model, and headless CI runs are in
285
290
  [Signing in & deploying](https://github.com/xanots/sdk/blob/main/guides/deploying.md). Environment management is
286
291
  `xanots ephemeral <list|get|delete|export>`.
@@ -291,8 +296,9 @@ The tests you author — a `tests` entry on a query, function, or middleware, or
291
296
  `workflowTest()` — run against a deployed environment:
292
297
 
293
298
  ```bash
294
- npx xanots test run-all # the ephemeral you last deployed to
295
- npx xanots test run-all --dest workspace # or your real workspace (this only reads)
299
+ npx xanots test run-all # the ephemeral you last deployed to
300
+ npx xanots test run-all --env ephemeral:pr-3 # or a named one
301
+ npx xanots test run-all --env workspace # or your real workspace (this only reads)
296
302
  ```
297
303
 
298
304
  `xanots test list` shows what is there without running it, and `xanots test run "<name>"`
@@ -344,7 +350,7 @@ Importing a def carries the SDK runtime with it. When that matters, emit a route
344
350
  instead — plain data plus one interpolator, importing nothing:
345
351
 
346
352
  ```bash
347
- xanots paths ./xano/index.ts --emit xano/routes.gen.ts
353
+ xanots routes ./xano/index.ts --emit xano/routes.gen.ts
348
354
  ```
349
355
 
350
356
  Route names and their `{param}` keys are still checked at compile time, so a backend rename
@@ -356,21 +362,22 @@ rules, endpoint-name constraints, and the realtime helpers are in
356
362
 
357
363
  ## Already have a Xano workspace?
358
364
 
359
- `codegen` runs the loop the other way: it reads a workspace and writes it back out as
365
+ `--from` runs the loop the other way: it reads a workspace and writes it back out as
360
366
  readable XanoTS source — real `s.db.query(...)`, `f.email()`, typed defs — not a JSON dump.
361
- And not a loose pile of files either: you get the same runnable project `xanots init`
362
- scaffolds, with the pulled workspace filling `xano/`. So a pull deploys:
367
+ And not a loose pile of files either: it is the same runnable project `xanots init`
368
+ scaffolds, with the pulled workspace filling `xano/` instead of the starter. So a pull
369
+ deploys:
363
370
 
364
371
  ```bash
365
- xanots workspace codegen my-app # your real workspace (the one your login is scoped to)
372
+ xanots init my-app --from workspace # your real workspace (the one your login is scoped to)
366
373
  cd my-app
367
374
  npm run build
368
- npm run xano:deploy # → a live ephemeral URL
375
+ npm run xano:deploy # → a live ephemeral URL
369
376
  ```
370
377
 
371
- The other three sources are the same command with a different origin`xanots sandbox
372
- codegen`, `xanots ephemeral codegen`, and `xanots codegen ws.json` for a bundle already on
373
- disk (offline, no login).
378
+ The other two sources are the same flag with a different value`--from ephemeral:<name>`,
379
+ and `--from ./ws.json` for a bundle already on disk (offline, no login). Everything else about the project is unchanged, so `--theme`, `--ai` and `--web`
380
+ compose with a pull exactly as they do with a starter.
374
381
 
375
382
  Object identities are preserved, so cross-references stay intact, and a statement this SDK
376
383
  does not model yet round-trips verbatim rather than breaking the pull. Then it checks its own
@@ -379,7 +386,7 @@ from, so "it compiled" and "it means the same thing" are separate claims and you
379
386
 
380
387
  > ⚠️ **`xano/` is a scratch surface.** Regenerating rewrites it, it carries schema only — no
381
388
  > table rows — and deploying it is a *full replace* of the target. Pull from your real
382
- > workspace, edit, and `deploy` to a disposable ephemeral or sandbox. Workspace env var
389
+ > workspace, edit, and `deploy` to a disposable ephemeral. Workspace env var
383
390
  > **values** ride inline in `xano/workspace.ts`, so treat a pulled tree as secret-bearing
384
391
  > before you commit it.
385
392
 
@@ -401,12 +408,50 @@ reference, the guides carry the shape of a project and the behavior that will bi
401
408
  | [Object kinds](https://github.com/xanots/sdk/blob/main/guides/object-kinds.md) | Every authorable kind, and splitting a workspace across microservices |
402
409
  | [Authoring reference](https://github.com/xanots/sdk/blob/main/guides/authoring.md) | Tables and fields, statements, values, inputs, middleware, seed data |
403
410
  | [CLI](https://github.com/xanots/sdk/blob/main/guides/cli.md) | Every command, shell completion, and what failures look like |
404
- | [Signing in & deploying](https://github.com/xanots/sdk/blob/main/guides/deploying.md) | Auth, ephemerals, `--static`, releasing to production, `xanots validate` |
411
+ | [Signing in & deploying](https://github.com/xanots/sdk/blob/main/guides/deploying.md) | Auth, ephemerals, `--static`, releasing to production, `xanots preflight` |
405
412
  | [Environment & identity](https://github.com/xanots/sdk/blob/main/guides/environment.md) | Every environment variable, and how `xano.lock` pins identity |
406
413
  | [The typed frontend surface](https://github.com/xanots/sdk/blob/main/guides/typed-frontend.md) | Path resolution, input/response inference, bundle cost, the route manifest |
407
- | [Pulling an existing workspace](https://github.com/xanots/sdk/blob/main/guides/codegen.md) | What `xanots codegen` writes, how faithful it is, and how to read its report |
414
+ | [Pulling an existing workspace](https://github.com/xanots/sdk/blob/main/guides/codegen.md) | What `xanots init --from` writes, how faithful it is, and how to read its report |
408
415
  | [Coverage & agent grounding](https://github.com/xanots/sdk/blob/main/guides/coverage.md) | What is covered, what is out of scope, and the files agents read |
409
416
 
417
+ ### Reading a compiled bundle
418
+
419
+ `@xanots/sdk` writes a bundle; `@xanots/sdk/bundle` reads one back. It is the surface for
420
+ tools that take compiled JSON as input — a graph view, a diff, a linter, a docs generator —
421
+ so none of them has to reverse-engineer the storage shape and then go quietly wrong when the
422
+ engine grows a new one.
423
+
424
+ ```ts
425
+ import { statementCatalog, walk } from "@xanots/sdk/bundle";
426
+
427
+ const bundle = JSON.parse(await readFile("bundle.json", "utf8"));
428
+ const catalog = statementCatalog();
429
+
430
+ for (const { raw, path, depth } of walk(bundle.payload.query[0].run)) {
431
+ console.log(`${" ".repeat(depth)}${path} ${catalog.get(raw.name)?.sPath ?? raw.name}`);
432
+ }
433
+ // 0 db.query
434
+ // 1 conditional
435
+ // 1.if.0 db.add
436
+ ```
437
+
438
+ - **`walk(run)`** → every statement in the tree, each with a `path` and a `depth`. The path
439
+ format (`2.if.0`) is the shared address: a lint finding, a review comment and a runtime
440
+ error written by three different tools all name the same node.
441
+ - **`subStacks(raw)`** → the nested stacks a statement carries, keyed by where they are
442
+ stored and labelled by what they mean — a try/catch and a conditional share the same three
443
+ storage keys. Found by shape, so a nesting form added later is still walked.
444
+ - **`statementCatalog()`** → the stored `mvp:*` name to its authoring path (`s.db.query`).
445
+ - **`structuralHash(raw)`** → a diff key for a statement and everything under it, with
446
+ engine-filled operands excluded. Without that exclusion, adding one column to a table
447
+ reports every statement that writes it as changed.
448
+ - **`tableRefOf(column)` / `linkedTableOf(column)`** → the table a column points at.
449
+ - **`normalize(value)`** → the normalizer `xanots preflight` compares with, for diffing a
450
+ stored workspace against a compiled one.
451
+
452
+ Everything on the entry is pure — no filesystem, no network, no Node built-ins — so it runs
453
+ in a browser or a worker.
454
+
410
455
  The package also ships two machine-readable descriptions of the same surface, generated from
411
456
  the SDK's own sources so they cannot drift from it: `llms.txt` (the router — the mental model
412
457
  and the gotchas, plus a map of the `llms/*.md` topic files) and `manifest.json` (per-entry
@@ -1 +1 @@
1
- 6be27443d5fbd10d871e0401f52565ed89d47edcc49810206bbf1efb9497f539
1
+ 6e6a4444f6fc73ee75afa9e72fb57b1ac2592d33d6b9a99205023fcbaccf8ed8
@@ -3,8 +3,8 @@ import {
3
3
  codingAgentDetected,
4
4
  isCI,
5
5
  refreshAgentFiles
6
- } from "./chunk-QIWBCS7N.js";
7
- import "./chunk-4PE4ZAB7.js";
6
+ } from "./chunk-JGCWTCA7.js";
7
+ import "./chunk-KA6G2L7U.js";
8
8
  import "./chunk-ZSYZTGJH.js";
9
9
  import "./chunk-Q77KNEUL.js";
10
10
  import "./chunk-EZG76F7R.js";
@@ -14,4 +14,4 @@ export {
14
14
  isCI,
15
15
  refreshAgentFiles
16
16
  };
17
- //# sourceMappingURL=agent-file-refresh-4W37DGXS.js.map
17
+ //# sourceMappingURL=agent-file-refresh-QNKN5RYD.js.map
package/dist/bin.js CHANGED
@@ -1,27 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  maybeNotifyUpdate
4
- } from "./chunk-OW2QZEWL.js";
4
+ } from "./chunk-22TKBSDV.js";
5
5
  import {
6
6
  readVersion,
7
7
  run
8
- } from "./chunk-K3YSQDXJ.js";
8
+ } from "./chunk-RCT7UX7B.js";
9
+ import "./chunk-CTD5ZCV6.js";
10
+ import "./chunk-XEOX6AM7.js";
9
11
  import {
10
12
  exitCodeOf,
11
13
  reportFailure
12
- } from "./chunk-JQLR64UC.js";
13
- import "./chunk-OYMR5AMJ.js";
14
+ } from "./chunk-F6CYJ7TN.js";
14
15
  import "./chunk-GNPVYOPB.js";
15
16
  import {
16
17
  clearProgress,
17
18
  error
18
19
  } from "./chunk-EZG76F7R.js";
19
- import "./chunk-UDL46O35.js";
20
- import "./chunk-OKNSR7MT.js";
21
- import "./chunk-QONOJO45.js";
20
+ import "./chunk-OWGCOGKK.js";
21
+ import "./chunk-DIA7CT7J.js";
22
+ import "./chunk-QK7ZQJLP.js";
22
23
  import "./chunk-WHOJWOSV.js";
24
+ import "./chunk-VAF6A3YD.js";
23
25
  import "./chunk-5XZ744TS.js";
24
- import "./chunk-7JDT4PBU.js";
26
+ import "./chunk-OHX6MIUZ.js";
25
27
 
26
28
  // src/emit/interrupt.ts
27
29
  var EXIT_SIGINT = 130;
@@ -6,19 +6,20 @@ import {
6
6
  } from "./chunk-EQW3YT5U.js";
7
7
  import {
8
8
  confirm
9
- } from "./chunk-4PTSTDIG.js";
10
- import {
11
- getAccessToken
12
- } from "./chunk-3QW5NFZJ.js";
13
- import "./chunk-BKDJN76G.js";
9
+ } from "./chunk-AIZKXUNP.js";
14
10
  import {
15
11
  isMachineOutput,
16
12
  writeJson
17
13
  } from "./chunk-NUQCEOKA.js";
14
+ import {
15
+ getAccessToken
16
+ } from "./chunk-QKM4U5UK.js";
17
+ import "./chunk-FE5I6S6N.js";
18
18
  import "./chunk-3IGNIP6R.js";
19
19
  import {
20
- UsageError
21
- } from "./chunk-JQLR64UC.js";
20
+ UsageError,
21
+ assertNoForce
22
+ } from "./chunk-F6CYJ7TN.js";
22
23
  import "./chunk-GNPVYOPB.js";
23
24
  import {
24
25
  blank,
@@ -28,7 +29,7 @@ import {
28
29
  success,
29
30
  warn
30
31
  } from "./chunk-EZG76F7R.js";
31
- import "./chunk-OKNSR7MT.js";
32
+ import "./chunk-DIA7CT7J.js";
32
33
 
33
34
  // src/emit/branch-commands.ts
34
35
  var VERBS = ["list", "set-live", "delete"];
@@ -60,6 +61,7 @@ function renderList(branches, workspaceId) {
60
61
  detail("Branches scope logic. Tables and microservices are shared by every branch.");
61
62
  }
62
63
  async function runBranchCommand(args) {
64
+ assertNoForce(args.force, "workspace", "branch");
63
65
  const verb = assertVerb(args.positionals[0]);
64
66
  const auth = await getAccessToken(args);
65
67
  const workspaceId = auth.workspaceId;
@@ -87,7 +89,7 @@ async function runBranchCommand(args) {
87
89
  if (outgoing !== void 0) detail(`The runtime stops serving "${outgoing}" and starts serving "${label}".`);
88
90
  detail("Table data is unaffected \u2014 it is shared by every branch either way.");
89
91
  blank();
90
- if (!args.yes && !args.force) {
92
+ if (!args.yes) {
91
93
  const ok = await confirm(`Make "${label}" the live branch?`, {
92
94
  flag: "--yes",
93
95
  helpFor: { command: "workspace", subcommand: "branch" }
@@ -114,7 +116,7 @@ Promote another branch first (\`xanots workspace branch set-live <other>\`), the
114
116
  { helpFor: { command: "workspace", subcommand: "branch" } }
115
117
  );
116
118
  }
117
- if (!args.yes && !args.force) {
119
+ if (!args.yes) {
118
120
  const ok = await confirm(`Delete branch "${label}" from workspace #${workspaceId}?`, {
119
121
  flag: "--yes",
120
122
  helpFor: { command: "workspace", subcommand: "branch" }
@@ -131,4 +133,4 @@ Promote another branch first (\`xanots workspace branch set-live <other>\`), the
131
133
  export {
132
134
  runBranchCommand
133
135
  };
134
- //# sourceMappingURL=branch-commands-PBQ36L4A.js.map
136
+ //# sourceMappingURL=branch-commands-2BLOC2GR.js.map
@@ -0,0 +1,218 @@
1
+ import { S as StackItemXdo, g as FieldXdo } from './xdo-BjJj5W_E.js';
2
+ export { b as ConditionalContext, c as ConditionalElifContext, E as ExprGroup, d as ExprNode, e as ExprOperand, f as ExprStatement, h as FilterXdo, I as InputXdo, M as MethodXdo, k as ResultItemXdo, l as StatementInputXdo, o as TaggedValue } from './xdo-BjJj5W_E.js';
3
+
4
+ /**
5
+ * The statement catalog, keyed the way a bundle reader needs it.
6
+ *
7
+ * A compiled statement identifies itself by its STORED name (`mvp:dbo_view`);
8
+ * everything a person reads — a docs link, a lint message, a graph node label —
9
+ * wants the authoring path (`s.db.query`). The mapping is SDK metadata, so a
10
+ * third-party tool must not have to keep its own copy: a new statement kind
11
+ * would then need a release in every tool before it stopped rendering as an
12
+ * unknown node.
13
+ */
14
+ /** One stored statement name and the authoring surface(s) that compile to it. */
15
+ interface StatementCatalogEntry {
16
+ /** The stored `mvp:` name, as it appears on a compiled statement's `name`. */
17
+ readonly storedName: string;
18
+ /** The primary surface key — the engine's own schema name, e.g. `db.query`. */
19
+ readonly surface: string;
20
+ /** The dotted accessor under `s.`, e.g. `db.query` is reachable as `s.db.query`. */
21
+ readonly sPath: string;
22
+ /**
23
+ * Every surface key stored under this name, in catalog order. Almost always
24
+ * one; the mapping is NOT injective (`util.get_raw_input` and `util.get_input`
25
+ * both store `mvp:get_input`), so a reader that must not lose a surface reads
26
+ * this rather than {@link StatementCatalogEntry.surface}.
27
+ */
28
+ readonly surfaces: readonly string[];
29
+ }
30
+ /**
31
+ * Every stored statement name the SDK knows, mapped to its authoring surface.
32
+ *
33
+ * Built once and shared — the returned map is frozen in the sense that it is the
34
+ * same instance on every call, so a caller must not mutate it.
35
+ *
36
+ * `raw()` is deliberately absent: it is the passthrough for stored statements
37
+ * the catalog cannot model, so a `name` that misses here is exactly the set a
38
+ * tool should render as opaque.
39
+ */
40
+ declare function statementCatalog(): ReadonlyMap<string, StatementCatalogEntry>;
41
+
42
+ /**
43
+ * Statement-tree traversal for a compiled bundle.
44
+ *
45
+ * A stack is a `run[]` of {@link StackItemXdo} envelopes, and a statement that
46
+ * nests carries its children under `context` — never under a single key. A
47
+ * conditional stores `if.run` / `elif.run` / `else.run`, a try/catch reuses the
48
+ * same three keys for `try` / `catch` / `finally`, a switch stores its cases
49
+ * under `elif.run` and its default under `else.run`, and every loop, group and
50
+ * transaction stores a bare `context.run`.
51
+ *
52
+ * A tool that hardcodes that key set drops a subtree silently the day the engine
53
+ * adds a nesting shape, so {@link subStacks} does not hardcode it: it finds a
54
+ * sub-stack by SHAPE — any `context` member that is a `{run: [...]}` object,
55
+ * plus `context.run` itself. {@link SUB_STACK_KEYS} is exported as the set known
56
+ * today, and it fixes the ORDER discovery reports; a key outside it is still
57
+ * found, reported after the known ones, in `context` order.
58
+ */
59
+
60
+ /**
61
+ * The `context` keys that hold a nested stack today, in the order
62
+ * {@link subStacks} reports them. The order is the authoring order for every
63
+ * statement that nests: `if` before `elif` before `else` for a conditional,
64
+ * try before catch before finally for a try/catch, cases before default for a
65
+ * switch.
66
+ *
67
+ * This is a reference set, not a filter — see the module note.
68
+ */
69
+ declare const SUB_STACK_KEYS: readonly string[];
70
+ /** One nested stack hanging off a statement's `context`. */
71
+ interface SubStack {
72
+ /** The `context` key the stack is stored under (`if`, `elif`, `else`, `then`, `run`). */
73
+ readonly key: string;
74
+ /**
75
+ * What the branch means at the authoring surface — `try`/`catch`/`finally` for
76
+ * a try/catch, `cases`/`default` for a switch, `body` for a loop. Falls back
77
+ * to the key for a statement with no recorded mapping.
78
+ */
79
+ readonly label: string;
80
+ /** The nested statements, in run order. */
81
+ readonly run: readonly StackItemXdo[];
82
+ }
83
+ /** A statement reached by {@link walk}, with its address and nesting depth. */
84
+ interface WalkedStatement {
85
+ /** The statement envelope, by reference — not a copy. */
86
+ readonly raw: StackItemXdo;
87
+ /**
88
+ * The statement's address within the stack it was walked from — see
89
+ * {@link statementPath}. `"2"` is the third top-level statement; `"2.if.0"` is
90
+ * the first statement of its `if` branch.
91
+ */
92
+ readonly path: string;
93
+ /** Nesting depth: `0` for a top-level statement, `1` inside one sub-stack, and so on. */
94
+ readonly depth: number;
95
+ }
96
+ /**
97
+ * Every nested stack a statement carries, in canonical order.
98
+ *
99
+ * Returns an empty array for a leaf statement. A sub-stack stored empty
100
+ * (`elif: {run: []}`, which the engine always persists on a conditional) is
101
+ * REPORTED with an empty `run` rather than skipped — the branch exists in the
102
+ * bytes, and a tool that renders branches wants to know the difference between
103
+ * "no elif" and "an elif that does nothing".
104
+ */
105
+ declare function subStacks(raw: StackItemXdo): SubStack[];
106
+ /**
107
+ * Join path segments into a statement path.
108
+ *
109
+ * The format is dot-separated, alternating an index with the `context` key that
110
+ * contains the next level: `2` is the third top-level statement, `2.if.0` is the
111
+ * first statement of its `if` branch, `2.elif.0.if.1` is the second statement of
112
+ * its first elif branch. The KEY is used, not the label, so the path addresses
113
+ * the stored bytes and stays stable if an authoring name changes.
114
+ *
115
+ * One shared address is the point: a lint finding, a review comment and a
116
+ * runtime error written by three different tools all name the same node.
117
+ */
118
+ declare function statementPath(segments: readonly (string | number)[]): string;
119
+ /**
120
+ * Walk a stack depth-first in pre-order — every statement, then its sub-stacks
121
+ * in {@link subStacks} order.
122
+ *
123
+ * A statement that is itself a branch carrier (`mvp:conditional_elif`,
124
+ * `mvp:switch_case`) is a stack item like any other, so it is VISITED and then
125
+ * descended into. A tool counting statements should filter those out; a tool
126
+ * addressing nodes wants them present.
127
+ *
128
+ * Iterative rather than recursive: a generated stack can nest deep enough to
129
+ * blow the call stack, and a bundle reader must not be the thing that crashes.
130
+ */
131
+ declare function walk(run: readonly StackItemXdo[]): WalkedStatement[];
132
+
133
+ /**
134
+ * A structural fingerprint for a compiled statement — the thing a diff, a cache
135
+ * key or a "did this change" check wants, and the thing a byte comparison is
136
+ * not.
137
+ *
138
+ * Two reductions run before the hash:
139
+ *
140
+ * 1. {@link normalize}, the same normalizer the SDK uses for fixture comparison
141
+ * and for the `xanots preflight` round-trip diff. It strips server-assigned
142
+ * identity (`_xsid`, `id`, timestamps, `market_item`) and canonicalizes the
143
+ * spellings the engine persists two ways.
144
+ * 2. Engine-filled `input[]` slots — the entries carrying `ignore: true`.
145
+ *
146
+ * The second one is the whole reason this is not just `sha1(normalize(x))`. A
147
+ * "full" statement (`db.add`, `db.edit`, `api.request`) persists one `input[]`
148
+ * entry per column of the table it writes, and the ones the author did not set
149
+ * carry `ignore: true`. Add a column to a table and EVERY statement that writes
150
+ * it gains an entry — so an unfiltered diff reports that every one of them
151
+ * changed, when what changed was the table. Filtered, the same diff reports the
152
+ * one object that actually changed.
153
+ *
154
+ * The normalizer deliberately KEEPS `ignore: true` (it is meaningful bytes on a
155
+ * system column, and the normalizer's job is byte fidelity — it must not drop
156
+ * what it cannot prove inert). That is not a contradiction: byte fidelity and
157
+ * structural identity are different questions, so they get different reductions.
158
+ * If you need the byte-level answer, hash `normalize()` yourself.
159
+ */
160
+
161
+ /**
162
+ * JSON with every object's keys sorted — so two statements that differ only in
163
+ * the order the engine happened to serialize their members hash the same.
164
+ */
165
+ declare function canonicalJson(value: unknown): string;
166
+ /**
167
+ * A stable hex fingerprint of a statement AND everything nested under it.
168
+ *
169
+ * Equal hashes mean the two statements do the same thing; different hashes mean
170
+ * something an author wrote differs. The value is stable across SDK versions
171
+ * only as far as the normalizer is — treat it as a comparison key computed in
172
+ * one pass over both sides, not as a value to persist and compare next year.
173
+ */
174
+ declare function structuralHash(raw: StackItemXdo): string;
175
+
176
+ /**
177
+ * Reading table relationships out of a stored column.
178
+ *
179
+ * Both are storage details a schema view needs and nothing else states, so they
180
+ * have been reverse-engineered once per tool up to now.
181
+ */
182
+
183
+ /**
184
+ * The table a foreign-key column points at, as a guid — or `null` if the column
185
+ * is not a reference.
186
+ *
187
+ * A reference is an `int` or `uuid` column whose LAST method is `@` with a
188
+ * single `dbo=<guid>` argument. The position matters: `@` is an annotation the
189
+ * engine appends, and reading any `@` in the list would misread a column that
190
+ * carries one for another reason.
191
+ *
192
+ * A bare `dbo=` returns `null`. That is what the editor writes when a reference
193
+ * is CLEARED — an FK annotation pointing at nothing, which is not a reference.
194
+ */
195
+ declare function tableRefOf(column: FieldXdo): string | null;
196
+ /**
197
+ * The table a db-link column expands, as a guid — or `null` if the column is not
198
+ * one.
199
+ *
200
+ * The other table relationship, and a different shape entirely: the column's
201
+ * TYPE is the table's identity with `_mvpschema` appended, and the engine
202
+ * expands the link into one input per column of the named table. A schema view
203
+ * that only reads {@link tableRefOf} misses these edges.
204
+ */
205
+ declare function linkedTableOf(column: FieldXdo): string | null;
206
+
207
+ /**
208
+ * Structural deep-equal for comparing an engine-default subtree to a frozen
209
+ * default — and, exported, for comparing two normalized objects.
210
+ *
211
+ * Exported so a caller that has already normalized both sides does not carry its
212
+ * own copy of the same walk; a second implementation is a second set of rules
213
+ * about what "equal" means.
214
+ */
215
+ declare function deepEqual(a: unknown, b: unknown): boolean;
216
+ declare function normalize<T>(value: T): T;
217
+
218
+ export { FieldXdo, SUB_STACK_KEYS, StackItemXdo, type StatementCatalogEntry, type SubStack, type WalkedStatement, canonicalJson, deepEqual, linkedTableOf, normalize, statementCatalog, statementPath, structuralHash, subStacks, tableRefOf, walk };