@xano/sdk 1.0.12 → 1.0.13
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.
- package/CHANGELOG.md +13 -0
- package/README.md +8 -8
- package/dist/.build-fingerprint +1 -1
- package/dist/{agent-file-refresh-YM5VRRHE.js → agent-file-refresh-DAFGNMQX.js} +4 -4
- package/dist/{agent-skill-command-GVVCBAGF.js → agent-skill-command-6M46ZGOL.js} +13 -13
- package/dist/{backend-dir-NZOLU7TL.js → backend-dir-J2J7JNS6.js} +4 -4
- package/dist/bin.js +13 -13
- package/dist/{branch-commands-Q46PCVHU.js → branch-commands-BUKVE637.js} +3 -3
- package/dist/{chunk-2PAVJ3QD.js → chunk-5ONWBQ2C.js} +2 -2
- package/dist/{chunk-ETMP7SJ3.js → chunk-5SMUND4J.js} +3 -3
- package/dist/{chunk-UZ55F3UK.js → chunk-5XDKKE5Y.js} +2 -2
- package/dist/{chunk-WXLZCBPG.js → chunk-6HTXQAMG.js} +2 -2
- package/dist/{chunk-PBIV4DE2.js → chunk-6OOZJQJK.js} +39 -39
- package/dist/{chunk-2RDZDDPR.js → chunk-CGZSF756.js} +12 -12
- package/dist/{chunk-G3A3XKCS.js → chunk-DPSR5GRE.js} +20 -20
- package/dist/{chunk-DH32QXVI.js → chunk-EKS7SAZS.js} +16 -16
- package/dist/{chunk-2K2G5TSR.js → chunk-ENAUSLMP.js} +3 -3
- package/dist/{chunk-5RSPMSSQ.js → chunk-ENBGJJJH.js} +3 -3
- package/dist/{chunk-5SZSLAAC.js → chunk-FBWMKHLO.js} +1 -1
- package/dist/{chunk-MFEO3EHL.js → chunk-GRWYO2MS.js} +2 -2
- package/dist/{chunk-OKR66IGL.js → chunk-H6VVSGKN.js} +2 -2
- package/dist/{chunk-SAKWZG5I.js → chunk-HDANNK4A.js} +2 -2
- package/dist/{chunk-RNVGXJJZ.js → chunk-HEMWBHQS.js} +7 -7
- package/dist/{chunk-HA5Y645X.js → chunk-MLKJUEG3.js} +12 -12
- package/dist/{chunk-ANBIMJPM.js → chunk-NMHTB346.js} +3 -3
- package/dist/{chunk-RFB4EXM5.js → chunk-O6PWEJUV.js} +2 -2
- package/dist/{chunk-CPFWVB3V.js → chunk-P6HXDOFG.js} +6 -6
- package/dist/{chunk-7XOQXZ6W.js → chunk-QWWQM4XZ.js} +2 -2
- package/dist/{chunk-OK7CBTFW.js → chunk-RAGFXELQ.js} +2 -2
- package/dist/{chunk-4GSXWOBS.js → chunk-RQHXYL77.js} +2 -2
- package/dist/{chunk-HJSAGGHU.js → chunk-SBS2IYTN.js} +2 -2
- package/dist/{chunk-AMHAGMJM.js → chunk-TANWE2ZY.js} +53 -53
- package/dist/{chunk-EC5P4W2D.js → chunk-U4BGBU3R.js} +15 -15
- package/dist/{chunk-4COXXP55.js → chunk-UDCKYLBW.js} +2 -2
- package/dist/{chunk-EMAFZROF.js → chunk-UECNKDDA.js} +2 -2
- package/dist/{chunk-6IOBEJWA.js → chunk-UKC65HBQ.js} +2 -2
- package/dist/{chunk-JPAUQ7MK.js → chunk-VFRL4G72.js} +2 -2
- package/dist/{chunk-74NRFGL7.js → chunk-WQZCFVAD.js} +2 -2
- package/dist/{chunk-TOW4EJON.js → chunk-XL7EA62X.js} +2 -2
- package/dist/{chunk-SAYHY2N3.js → chunk-XYVPF63S.js} +2 -2
- package/dist/{chunk-WQNN6WLB.js → chunk-ZACMAKZE.js} +5 -5
- package/dist/{chunk-U5CTYBAN.js → chunk-ZGNWMGN3.js} +4 -4
- package/dist/{chunk-3XZ44H2E.js → chunk-ZISPEBNM.js} +5 -2
- package/dist/{chunk-LDSZPRGV.js → chunk-ZSMHS7BU.js} +2 -2
- package/dist/cli.js +12 -12
- package/dist/{codegen-command-H3HO7UFA.js → codegen-command-BAFON45M.js} +19 -19
- package/dist/{deploy-command-7PWQJ4VV.js → deploy-command-JW7R3BPW.js} +16 -16
- package/dist/{deploy-source-CJHEVGOS.js → deploy-source-ZUPLAL7L.js} +7 -7
- package/dist/{dev-env-sync-VVLYQUPR.js → dev-env-sync-W7OTV7OD.js} +13 -13
- package/dist/{env-example-refresh-GLFC2FTE.js → env-example-refresh-TS7WBVZQ.js} +20 -20
- package/dist/{env-pull-command-OY3SXNJC.js → env-pull-command-5IYXQ2WK.js} +13 -13
- package/dist/{env-target-PDDDAA5I.js → env-target-TQBPLU2S.js} +2 -2
- package/dist/{env-var-command-UTYDJN24.js → env-var-command-AKCWYZPB.js} +13 -13
- package/dist/{ephemeral-command-ALIHUF7G.js → ephemeral-command-SJYH6XRS.js} +14 -14
- package/dist/{generate-command-S37XFYPD.js → generate-command-FSCFZPOJ.js} +23 -23
- package/dist/{gitignore-DKDWGWPS.js → gitignore-6IJ66XME.js} +6 -6
- package/dist/{impersonate-command-HPCSKJAV.js → impersonate-command-IH4HMSS3.js} +9 -9
- package/dist/{init-command-RWXBXJPG.js → init-command-STB4YSAK.js} +15 -15
- package/dist/{init-modules-LFLW2PQC.js → init-modules-YIZYPCMM.js} +2 -2
- package/dist/internal.js +4 -4
- package/dist/{keep-data-merge-7JGGZKDM.js → keep-data-merge-VRKS64JK.js} +4 -4
- package/dist/{landing-record-QJV7KNS4.js → landing-record-5EFK7RI6.js} +5 -5
- package/dist/{local-engine-choice-NNSHE5FO.js → local-engine-choice-TRTEJVMV.js} +8 -8
- package/dist/{local-engine-command-UGIZ4UO6.js → local-engine-command-2FK2PE2P.js} +9 -9
- package/dist/{local-engine-mcp-command-YUSZC7MF.js → local-engine-mcp-command-FB7EOGG6.js} +9 -9
- package/dist/{lock-commands-VT4R2DEE.js → lock-commands-7PBZIRWR.js} +13 -13
- package/dist/{login-command-4D3KPQUY.js → login-command-2O6GRMTH.js} +9 -9
- package/dist/{logout-command-ALKHCJKS.js → logout-command-RZXGW3O2.js} +3 -3
- package/dist/{marketplace-command-64TE2NGV.js → marketplace-command-NCMLGIMS.js} +13 -13
- package/dist/{meta-client-7MLLUZB4.js → meta-client-DYYM5F5G.js} +2 -2
- package/dist/node.js +14 -14
- package/dist/{operation-outcome-TYAOVNOM.js → operation-outcome-SHNROAFA.js} +4 -4
- package/dist/{output-target-63ECBUX2.js → output-target-PSSR3E4N.js} +7 -7
- package/dist/plugin.d.ts +2 -1
- package/dist/{preflight-command-OUVAX5IJ.js → preflight-command-6F7JF3YQ.js} +18 -18
- package/dist/{profile-command-NUO5U2HQ.js → profile-command-5AOGD6GV.js} +10 -10
- package/dist/{promote-command-MGLAYQDY.js → promote-command-O2NRRFLK.js} +26 -26
- package/dist/{publish-command-KVGNFBSU.js → publish-command-6VVSJPLI.js} +16 -16
- package/dist/{pull-command-OVXIMVUB.js → pull-command-GE2WUEUF.js} +21 -21
- package/dist/{release-command-E54WUJKB.js → release-command-55RTR674.js} +18 -18
- package/dist/{release-ns-command-SLRL3O3W.js → release-ns-command-5XPZ2B6N.js} +31 -31
- package/dist/{routes-manifest-file-IX4TOZCO.js → routes-manifest-file-42FTJHRY.js} +2 -2
- package/dist/{secrets-file-4NQWGCJG.js → secrets-file-N5IF265R.js} +5 -5
- package/dist/{secrets-fill-command-5NNHSYFX.js → secrets-fill-command-35WKBURT.js} +15 -15
- package/dist/{source-resolve-HSJSVKUC.js → source-resolve-JXGOVJD3.js} +3 -3
- package/dist/{status-command-UFIMW7SZ.js → status-command-G3DFRMU7.js} +12 -12
- package/dist/{sync-contributions-35ZAYBUH.js → sync-contributions-7T4CSPVQ.js} +2 -2
- package/dist/{tables-command-TISOU6DR.js → tables-command-7NUOZBHX.js} +10 -10
- package/dist/{tenant-command-ITCPN43T.js → tenant-command-JGEHRKN7.js} +32 -32
- package/dist/{test-command-7SFAJ6HX.js → test-command-2LNEA6GK.js} +10 -10
- package/dist/{token-OXGOA6WE.js → token-DWNH44NW.js} +2 -2
- package/dist/{toolchain-modules-Q3Z6APPF.js → toolchain-modules-F4DUMWTO.js} +2 -2
- package/dist/{tracked-backend-IYTIZZYV.js → tracked-backend-ZFXVLBBJ.js} +9 -9
- package/dist/{update-check-LSCQRDRR.js → update-check-KBHT63GJ.js} +14 -14
- package/dist/{upgrade-command-RQEQJO5Y.js → upgrade-command-CI543AZP.js} +16 -16
- package/dist/{whoami-command-NT3FVBZM.js → whoami-command-77DXENWD.js} +4 -4
- package/dist/{workspace-5RHOJC7K.js → workspace-RI5C77BZ.js} +2 -2
- package/dist/{workspace-binding-YUU6KB53.js → workspace-binding-PR57NBGH.js} +3 -3
- package/dist/{workspace-command-QSJHX5RS.js → workspace-command-6HHVFQKW.js} +27 -27
- package/dist/{workspace-env-M7RYVJB3.js → workspace-env-2APJEASO.js} +5 -5
- package/dist/{xanosdk-import-4TLNYFKC.js → xanosdk-import-HBQH3ZBS.js} +2 -2
- package/dist/{xanosdk-project-4NH6332J.js → xanosdk-project-W45IR3Q7.js} +5 -5
- package/guides/authoring.md +13 -7
- package/guides/bundle.md +1 -1
- package/guides/cli.md +28 -18
- package/guides/codegen.md +3 -2
- package/guides/coverage.md +4 -3
- package/guides/deploying.md +17 -10
- package/guides/environment.md +12 -12
- package/guides/marketplace.md +12 -6
- package/guides/module-contract.md +11 -6
- package/guides/object-kinds.md +8 -5
- package/guides/scaffold.md +24 -12
- package/guides/typed-frontend.md +7 -6
- package/llms/kinds-knowledge.md +2 -2
- package/llms/object-kinds.md +2 -2
- package/llms-full.txt +6 -6
- package/llms.txt +2 -2
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/skills/xano-backend/SKILL.md +2 -2
|
@@ -128,9 +128,12 @@ your module is only correct against the SDK versions whose shapes it understands
|
|
|
128
128
|
range out with a floor and a ceiling, as above: the ceiling is the next major, so a module
|
|
129
129
|
built for 1.x loads on every 1.x SDK and is refused on 2.0.
|
|
130
130
|
|
|
131
|
-
That range is **enforced at load
|
|
131
|
+
That range is **enforced at load**. On `export`, `deploy`, `preflight` and `init`, an SDK outside it
|
|
132
132
|
is refused by name before your plugin file is imported, naming the range you asked for and the
|
|
133
|
-
version it got.
|
|
133
|
+
version it got. The `routes.gen.ts` writers (`routes --emit`, the marketplace's route refresh,
|
|
134
|
+
`pull`, `generate`) and the marketplace reconcile skip the module with a warning instead: it is
|
|
135
|
+
never imported, a routes writer keeps its previous block, and `routes --emit --strict` still
|
|
136
|
+
fails. So the floor is the version whose shapes your hooks understand, not an
|
|
134
137
|
aspiration — declare it accurately and the SDK will never quietly run your module against a
|
|
135
138
|
contract it was not built for. Ranges are read as `>=` / `>` / `<=` / `<` / `=` comparators,
|
|
136
139
|
`^`, `~`, exact pins and `||` unions of those; a shape outside that subset is not refused, it
|
|
@@ -394,7 +397,7 @@ read than it is slow.
|
|
|
394
397
|
| `BundleContext` | What it carries |
|
|
395
398
|
|---|---|
|
|
396
399
|
| `bundle.payload` | The compiled payload, keyed by payload key (`table`, `query`, `app`, ...). |
|
|
397
|
-
| `entry` | The entry file the bundle came from. **Absent** on the `--bundle <path>` branch. |
|
|
400
|
+
| `entry` | The entry file the bundle came from. **Absent** on the `--bundle <path>` branch, and when `deploy` fetches a remote source (`release:main`). |
|
|
398
401
|
| `cwd` | The project root every relative path resolves against. |
|
|
399
402
|
| `command` | `"export"` or `"deploy"`. |
|
|
400
403
|
| `frozen` | The run is `--frozen-lock` (or `export --check` / `deploy --to … --dry-run`, which imply it): a verification, not a write. |
|
|
@@ -403,7 +406,7 @@ read than it is slow.
|
|
|
403
406
|
|
|
404
407
|
**`entry` is optional rather than a made-up path** so a plugin may decline the
|
|
405
408
|
`--bundle <path>` branch, where the input is already-serialized text with no entry and no
|
|
406
|
-
registry behind it. A tree rendered from a bundle the project did not compile describes
|
|
409
|
+
registry behind it, and a `deploy` from a fetched source, where nothing local was compiled. A tree rendered from a bundle the project did not compile describes
|
|
407
410
|
something other than the source beside it.
|
|
408
411
|
|
|
409
412
|
**Under `frozen` a plugin must compare and report, never write.** It is also the mode in which
|
|
@@ -470,8 +473,10 @@ const plugin: ToolchainPlugin = {
|
|
|
470
473
|
|
|
471
474
|
Your module's section of the route manifest, `xano/routes.gen.ts`. It runs wherever that file
|
|
472
475
|
is written: `xanosdk routes ./xano/index.ts --emit xano/routes.gen.ts` (the scaffold's
|
|
473
|
-
`xano:routes`), `
|
|
474
|
-
`remove` make, so your
|
|
476
|
+
`xano:routes`), `init --marketplace` when it writes the project's first manifest, `pull`,
|
|
477
|
+
`generate`, and the refresh `marketplace install`, `reinstall` and `remove` make, so your
|
|
478
|
+
block lands with your module. Not `init --from`: a project it creates has no module installed
|
|
479
|
+
yet, and the first `xano:routes` after an install adds your section.
|
|
475
480
|
|
|
476
481
|
| `RoutesManifestContext` | What it carries |
|
|
477
482
|
|---|---|
|
package/guides/object-kinds.md
CHANGED
|
@@ -14,11 +14,14 @@ and the seven trigger factories below. Signatures and payload keys are in
|
|
|
14
14
|
the types don't tell you.
|
|
15
15
|
|
|
16
16
|
**A knowledge item's body is a file, and `mode` is a running cost.** `knowledge()` is the
|
|
17
|
-
markdown
|
|
17
|
+
markdown shared by every AI that builds this backend — Xano's AI builder, people authoring in
|
|
18
|
+
XanoScript, and your local coding agent, which reads the same `.md` files in the repo (deploy
|
|
19
|
+
and `pull` keep them in sync). An `agent()` run never reads it; put what that agent needs in
|
|
20
|
+
its `llm.systemPrompt`. It is the one kind whose payload
|
|
18
21
|
is prose — so the body is named by path (`knowledgeFile("./runbook.md", import.meta.url)`)
|
|
19
|
-
rather than written as a string, and `refs: knowledgeDir(...)` ships a whole folder
|
|
20
|
-
|
|
21
|
-
symlink is not followed. What the
|
|
22
|
+
rather than written as a string, and `refs: knowledgeDir(...)` ships a whole folder Xano's AI
|
|
23
|
+
builder searches on demand — UTF-8 text files only (other content is refused), and a
|
|
24
|
+
symlink is not followed. What the builder actually receives is decided by `type` and `mode`,
|
|
22
25
|
and nothing in the types warns you: an `agents.md` item is injected in full on every turn
|
|
23
26
|
whatever `mode` says, `mode: "always"` spends the body's whole length on every request, and
|
|
24
27
|
the default `mode: "auto"` sends only the name and `description` until a request matches.
|
|
@@ -173,7 +176,7 @@ realtimeMessage({
|
|
|
173
176
|
name: "send", // `input` types the message PAYLOAD
|
|
174
177
|
channel: room, // the handle carries the server too
|
|
175
178
|
input: { body: input.text({ required: true }) },
|
|
176
|
-
deliverTo: "channel", // or "sender" (request/response) / "others"
|
|
179
|
+
deliverTo: "channel", // or "sender" (request/response) / "others" / "explicit"
|
|
177
180
|
stack: [s.debug.log({ value: inp("body") })],
|
|
178
181
|
});
|
|
179
182
|
```
|
package/guides/scaffold.md
CHANGED
|
@@ -9,7 +9,10 @@ backend alone — see [No frontend, and existing apps](#no-frontend-and-existing
|
|
|
9
9
|
(default: the folder name), `--theme <id>` / `--radius <len>` / `--dark <mode>` /
|
|
10
10
|
`--font <id>` / `--font-mono <id>` / `--font-heading <id>` / `--icons <id>`
|
|
11
11
|
(the look — see [Theming](#theming)), `--no-agents-md` (skip the `AGENTS.md`
|
|
12
|
-
agent brief, which every coding agent reads and `init` writes by default
|
|
12
|
+
agent brief, which every coding agent reads and `init` writes by default, and the
|
|
13
|
+
`.mcp.json` / `.cursor/mcp.json` configs that connect agents to the `xano-local`
|
|
14
|
+
MCP server), `--ai <preset|none>` (for scripted callers: `none` is `--no-agents-md`, and
|
|
15
|
+
any other value writes the one `AGENTS.md` every agent reads),
|
|
13
16
|
`--marketplace <pkg>` (repeatable, comma-separated; installs add-ons and
|
|
14
17
|
registers them — below), `--force` (write over what clashes when adding the backend to
|
|
15
18
|
a non-empty folder; it lists the files and scripts it would overwrite and asks, `--yes`
|
|
@@ -109,11 +112,12 @@ the add-on puts on your workspace, what you have to supply, and the
|
|
|
109
112
|
`xano/index.ts` registration to copy. Piped, it emits JSON; `--prompt` emits
|
|
110
113
|
instructions written to be handed straight to a coding agent.
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
and
|
|
115
|
+
`install` resolves its argument through the marketplace before npm runs — a module's
|
|
116
|
+
package or its slug (`auth`), keeping any version or tag — and refuses a name the
|
|
117
|
+
marketplace does not list with **exit 8**; local paths, `file:`, tarball and git specs
|
|
118
|
+
install as given. It also refuses before npm runs when you are not standing in a project,
|
|
119
|
+
and reconciles afterwards, asking any toolchain module that arrived its questions. See
|
|
120
|
+
[Installing](marketplace.md#installing).
|
|
117
121
|
|
|
118
122
|
## No frontend, and existing apps
|
|
119
123
|
|
|
@@ -123,7 +127,8 @@ is a **new** project, and `--framework` decides its frontend. Any other director
|
|
|
123
127
|
|
|
124
128
|
**A new project with `--framework none`** (or "No frontend" at the prompt) gets everything
|
|
125
129
|
above except the frontend: `xano/`, a `package.json` with only the backend's scripts and
|
|
126
|
-
dependencies, `.gitignore`, `.gitattributes`, the CI check, a README
|
|
130
|
+
dependencies, `.gitignore`, `.gitattributes`, the CI check, a README, `AGENTS.md`, and the
|
|
131
|
+
`.mcp.json` / `.cursor/mcp.json` agent configs. There is
|
|
127
132
|
no `frontend/` and no root `tsconfig.json`; `xano/` type-checks under its own
|
|
128
133
|
`xano/tsconfig.json`, and `npm run xano:typecheck` checks it and its lambdas.
|
|
129
134
|
`xano:deploy:ephemeral` deploys the backend alone, and there is no `dev`, `build` or
|
|
@@ -143,6 +148,11 @@ no `frontend/` and no root `tsconfig.json`; `xano/` type-checks under its own
|
|
|
143
148
|
- A marked block in `.gitignore` (created when missing) and in `AGENTS.md`, added or
|
|
144
149
|
refreshed in place; the rest of each file is left as it was. A symlinked `AGENTS.md` is left
|
|
145
150
|
alone, and `--no-agents-md` skips it.
|
|
151
|
+
- The `xano-local` MCP server merged by key into `.mcp.json` and `.cursor/mcp.json` (created
|
|
152
|
+
when missing): the other servers a config declares are kept. A config that already declares
|
|
153
|
+
`xano-local`, or is not valid JSON, is left alone and is not a clash; a symlinked one is
|
|
154
|
+
skipped. `--no-agents-md` skips both. See
|
|
155
|
+
[Connecting a coding agent](deploying.md#connecting-a-coding-agent).
|
|
146
156
|
- No frontend, README, CI workflow or root `tsconfig.json`. The line-ending rule goes in
|
|
147
157
|
`xano/.gitattributes`, scoped to `xano/`, so the project's own files are not renormalized.
|
|
148
158
|
|
|
@@ -177,17 +187,19 @@ The workflow installs with the project's package manager (npm, pnpm, yarn or bun
|
|
|
177
187
|
`init` detected it), frozen to the committed lockfile, then runs `xano:check` on every push
|
|
178
188
|
and pull request. In a monorepo workspace member it installs at the workspace root and checks
|
|
179
189
|
in the member's directory; move the file to the repository root's `.github/workflows/`, the
|
|
180
|
-
only place GitHub reads it. That script
|
|
181
|
-
|
|
190
|
+
only place GitHub reads it. That script runs three steps in order:
|
|
191
|
+
`xanosdk routes ./xano/index.ts --emit xano/routes.gen.ts --strict`, which fails when the
|
|
192
|
+
committed route manifest the frontend takes its paths from is stale or missing; the project's
|
|
193
|
+
typecheck (`tsc` on React, `svelte-kit sync && svelte-check` on Svelte, `tsc -p xano` with no
|
|
194
|
+
frontend, each followed by `tsc -p xano/lambdas`); and
|
|
195
|
+
`xanosdk export ./xano/index.ts --check --strict`: every check an export runs (a build warning fails it), under
|
|
182
196
|
`--frozen-lock`, writing nothing — no bundle, no lock. Because nothing is written, it
|
|
183
197
|
reads no `xano/.env` or `xano/.secrets.json`, so the workflow needs no repository
|
|
184
198
|
secrets, even for an API group whose docs are token-gated. It fails instead of
|
|
185
199
|
rewriting when `xano.lock` disagrees with the source, naming what would change. A
|
|
186
200
|
project with nothing to record yet (a fresh scaffold) passes without a lock. It also fails while the lock
|
|
187
201
|
carries an entry no exported object matches — the state a rename leaves until
|
|
188
|
-
`lock rename` moves the identity across, or `lock prune` drops it.
|
|
189
|
-
`xanosdk routes ./xano/index.ts --emit xano/routes.gen.ts --strict`, which fails when
|
|
190
|
-
the committed route manifest the frontend takes its paths from is stale or missing.
|
|
202
|
+
`lock rename` moves the identity across, or `lock prune` drops it.
|
|
191
203
|
`dev`, `build` and `typecheck` regenerate that file, so after adding or renaming an
|
|
192
204
|
endpoint run `npm run xano:routes` (or any of them) and commit it. `init --from` and
|
|
193
205
|
`pull` write it with the decoded backend, and `init --marketplace` writes it (and
|
package/guides/typed-frontend.md
CHANGED
|
@@ -36,6 +36,9 @@ Every type and helper a frontend gets from a deployed def — path resolution, i
|
|
|
36
36
|
one group and verb that a single path can reach (`query.route-shadowed`). Make the paths
|
|
37
37
|
disjoint (`"runs/by-id/{id}"`), or declare a numeric param `input.int({ required: true })`:
|
|
38
38
|
only a REQUIRED int/decimal segment matches digits only, and an optional one matches any text.
|
|
39
|
+
|
|
40
|
+
## Inferring the response type
|
|
41
|
+
|
|
39
42
|
- **`InferRow<typeof post>`** → the table's row type. Rename or retype a column and every
|
|
40
43
|
consumer breaks at compile time — exactly where you want it.
|
|
41
44
|
- **`InferResponse<typeof someQuery>`** → the endpoint's **response** type, closing the round
|
|
@@ -46,9 +49,6 @@ Every type and helper a frontend gets from a deployed def — path resolution, i
|
|
|
46
49
|
yielding null — `NotFound`/404 for `edit`/`patch`, a unique-constraint error for `add`, while
|
|
47
50
|
`add_or_edit` upserts and never misses), `Row | null` for `db.get` (it binds
|
|
48
51
|
`null` on a miss rather than throwing — handle the not-found path), a row list for
|
|
49
|
-
|
|
50
|
-
## Inferring the response type
|
|
51
|
-
|
|
52
52
|
`db.query`/`db.bulk.patch` (→ `Row[]`), a `boolean` for `db.has`, a `number` count for
|
|
53
53
|
`db.bulk.delete`, and a `get`/`query` `output: [...]` selection narrows to a `Pick` (still
|
|
54
54
|
`| null` for `get`). A dotted entry selects sub-keys of an object column
|
|
@@ -64,7 +64,7 @@ Every type and helper a frontend gets from a deployed def — path resolution, i
|
|
|
64
64
|
`response: { user: obj({ id: ref("row.id") }) }` and the raw literal
|
|
65
65
|
`response: { user: { id: ref("row.id") } }` both derive `{ user: { id: number | null } }`.
|
|
66
66
|
A **call** carries the shape across: `s.function.call`/`s.function.run`, `s.tool.call` and
|
|
67
|
-
`s.api.call` (workflow-test only
|
|
67
|
+
`s.api.call` (workflow-test only — see [Object kinds](object-kinds.md)) given a def **handle** bind their `as` with the
|
|
68
68
|
target's own `InferResponse`,
|
|
69
69
|
so `ref("discount_result.discount_cents")` in the caller types to that field instead of
|
|
70
70
|
`unknown`. What the target resolves to is what propagates, so declaring `responseShape` on
|
|
@@ -89,7 +89,7 @@ For a **computed or multi-key object response**, author it as a *record of value
|
|
|
89
89
|
`response: { success: c.bool(true), id: inp("id") }` — **not** `c.obj({ ... })`. `c.obj` builds a
|
|
90
90
|
*constant*, so a tagged value nested inside it would serialize as internal representation the
|
|
91
91
|
engine can't decode (a runtime 500); nesting one is now a compile error that points you at the
|
|
92
|
-
record form
|
|
92
|
+
record form. A **nested plain object** in a record
|
|
93
93
|
response (`response: { user: { id: ref("u"), age: 3 } }`) is auto-wrapped for you — no manual
|
|
94
94
|
`obj({ ... })` — and raw literals in a call/agent `input` map coerce too
|
|
95
95
|
(`s.function.run({ fn, input: { max_age_days: 3 } })` — no `c.int(3)`).
|
|
@@ -250,7 +250,8 @@ const connectUrl = mcpUrl("notes_mcp", XANO_HOST); // https://host/x2/mcp/<canon
|
|
|
250
250
|
```
|
|
251
251
|
|
|
252
252
|
Run `xanosdk routes ./xano/index.ts` without `--emit` to see every address the file carries:
|
|
253
|
-
each route, socket, channel and MCP server
|
|
253
|
+
each route in its `api:<canonical>/<name>` form, and each socket, channel and MCP server with
|
|
254
|
+
the call that builds it.
|
|
254
255
|
|
|
255
256
|
**Request types come from the same file.** It exports four types-only maps, keyed exactly
|
|
256
257
|
like the runtime tables they sit beside, so a frontend types what it sends without importing a
|
package/llms/kinds-knowledge.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Knowledge def shape
|
|
2
2
|
|
|
3
|
-
> Read when the workspace defines a `knowledge()` item
|
|
3
|
+
> Read when the workspace defines a `knowledge()` item.
|
|
4
4
|
|
|
5
|
-
- `knowledge({ name, description?, type?, mode?, enabled?, body, refs?, guid?, tags? })` — markdown Xano's own AI reads before it acts — the workspace's builder agent, and outside agents reading the workspace through the Meta API or MCP. It does NOT reach an `agent()` run by `s.ai.agent.run`, whatever its `type` or `mode`: put what such an agent must know in its `llm.systemPrompt`. Takes `registerKnowledge`.
|
|
5
|
+
- `knowledge({ name, description?, type?, mode?, enabled?, body, refs?, guid?, tags? })` — markdown shared by every AI that builds the backend: Xano's own AI reads it before it acts — the workspace's builder agent, and outside agents reading the workspace through the Meta API or MCP — and a local coding agent reads the same `.md` files in the repo; deploy and `pull` keep the copies in sync. It does NOT reach an `agent()` run by `s.ai.agent.run`, whatever its `type` or `mode`: put what such an agent must know in its `llm.systemPrompt`. Takes `registerKnowledge`.
|
|
6
6
|
- `body` (REQUIRED): `knowledgeFile("./runbook.md", import.meta.url)` — a path to a real markdown FILE. There is no inline-string form. The path resolves relative to the MODULE THAT DECLARES the item, not the process working directory and not the workspace entry; `import.meta.url` is required and is what makes that true.
|
|
7
7
|
- `refs?`: `knowledgeDir("./runbook", import.meta.url)` — a directory whose WHOLE tree ships, recursively, paths preserved: UTF-8 text only (else refused; binary `.DS_Store` skipped), symlinks not followed. Keep the body OUT of it, or it ships as a reference file.
|
|
8
8
|
- `type?`: `"skill"` (default) | `"doc"` | `"agents.md"`. `skill` and `doc` differ in how they are filed, not in what an agent receives.
|
package/llms/object-kinds.md
CHANGED
|
@@ -12,7 +12,7 @@ Choose by who or what starts the work. Each rule names the kind that fits and th
|
|
|
12
12
|
- **Work on a timer** → `task` (cron or interval). **Work a request starts but does not wait for** → `s.function.run({ fn, runtime: { mode: "async-shared" } })`, which binds a job id, not the result (collect with `s.await`). **Work that follows a row change** → `tableTrigger`: it fires on every insert/update/delete of the table, whichever stack writes it, so the same side effect placed in one endpoint's stack misses every other write path.
|
|
13
13
|
- **The same steps before or after many objects** (an auth check, a rate limit, logging) → `middleware`, attached per host (`middleware: { pre, post }` on a query, function, task, tool or API group) or to every host of a kind with `workspaceConfig({ middleware: { query, function, task, tool } })` — not a function call repeated at the top of each stack.
|
|
14
14
|
- **Related rows on returned rows** → an `addon` attached to the read through its `addon: [{ addon, as, input }]` option (`db.query`/`get`/`add`/`edit`/`patch`), merged onto each row under `as` and typed in `InferResponse` — not a second read plus a loop that stitches rows together.
|
|
15
|
-
- **AI.** An LLM running inside the backend → `agent()`, started from a stack with `s.ai.agent.run`; it has no public endpoint. An external AI client (Claude, Cursor, any MCP client) calling the backend → `mcpServer()`. Standing instructions for Xano's own builder AI → `knowledge()
|
|
15
|
+
- **AI.** An LLM running inside the backend → `agent()`, started from a stack with `s.ai.agent.run`; it has no public endpoint. An external AI client (Claude, Cursor, any MCP client) calling the backend → `mcpServer()`. Standing instructions for Xano's own builder AI → `knowledge()` (a local coding agent reads the same files in the repo); an `agent()` run never reads it. The actions either one calls → `tool()`. What an MCP server serves besides tools (`prompt()`, `resource()`) and when each fits: `llms/kinds-agent-mcp.md`.
|
|
16
16
|
- **Pushing to connected clients** → `realtimeServer` → `realtimeChannel` → `realtimeMessage` (the handler for a frame a client sends — the realtime analogue of a query). A server-side push from any stack is `s.realtime.publish`; a client polling a `query` is the substitute this replaces.
|
|
17
17
|
- **Code the typed surface cannot express** → a lambda (`s.lambda`, `fl.lambda`) for a short JavaScript body, LAST, after native filters and expressions (`llms/lambda.md`); a `microservice` for a long-running container or another language; `s.api.request` for a service that already has an HTTP API.
|
|
18
18
|
- **Tests** → `tests` on a `query`/`defineFunction`/`middleware` for that one object's input → output; a `workflowTest` for a flow across objects (`s.function.call`, `s.api.call`, `s.task.call`) asserted with `s.expect.*`.
|
|
@@ -44,5 +44,5 @@ Choose by who or what starts the work. Each rule names the kind that fits and th
|
|
|
44
44
|
- channel: `realtimeChannel` → `Xano.registerRealtimeChannels` → payload `channel` — A realtime channel: a joinable path on a realtime server (`rooms/{room_id}`) with typed path params, join/publish policy, a client-visible conversation transcript, and delivery semantics. Owns message handlers. Returns a handle with `getChannel(params)` for the path a client joins.
|
|
45
45
|
- message: `realtimeMessage` → `Xano.registerRealtimeMessages` → payload `message` — A realtime message handler: a named message type on a channel with its own typed payload and stack — the realtime analogue of a query. Pass the `realtimeChannel()` handle as `channel` and the owning server comes with it.
|
|
46
46
|
- microservice: `microservice` → `Xano.registerMicroservices` → payload `microservice` — A container workload deployed alongside the workspace, called from a stack with `s.microservice.request`. Def shapes (`builtin` containers vs a `helm` chart) and the SECRET-handling rules its config carries: `llms/statements-calls.md`.
|
|
47
|
-
- knowledge: `knowledge` → `Xano.registerKnowledge` → payload `knowledge` — Markdown Xano's own AI (the builder agent,
|
|
47
|
+
- knowledge: `knowledge` → `Xano.registerKnowledge` → payload `knowledge` — Markdown shared by every AI that builds the backend — Xano's own AI (the builder agent, Meta API / MCP readers) and a local coding agent reading the same files — never an `agent()` run: an `agents.md` of standing instructions, a `skill`, or a `doc`. The body is a real markdown FILE via `knowledgeFile("./x.md", import.meta.url)`, and `mode` decides how much of it reaches the agent.
|
|
48
48
|
- workspace: `workspaceConfig` → `Xano.registerWorkspace` → payload `workspace` — Workspace-level configuration such as default middleware chains and request-history defaults per host kind.
|
package/llms-full.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# xanosdk v1.0.
|
|
1
|
+
# xanosdk v1.0.13
|
|
2
2
|
|
|
3
3
|
> TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.
|
|
4
4
|
|
|
@@ -45,7 +45,7 @@ plain file read resolves them at the version you have.
|
|
|
45
45
|
- [Error index](llms/errors.md): Read when a request, test, build, or pull fails with a message you did not write — the string, its cause, and where the fix is.
|
|
46
46
|
- [Saved unit tests, assertions, and mocks](llms/tests.md): Read when authoring a `workflowTest()` stack, when a query/function/middleware carries `tests`, when a statement needs a `mock`, or when running a deployed environment's tests.
|
|
47
47
|
- [Agent and MCP def shapes](llms/kinds-agent-mcp.md): Read when building an MCP server (tools, prompts, resources) or an `agent()`.
|
|
48
|
-
- [Knowledge def shape](llms/kinds-knowledge.md): Read when the workspace defines a `knowledge()` item
|
|
48
|
+
- [Knowledge def shape](llms/kinds-knowledge.md): Read when the workspace defines a `knowledge()` item.
|
|
49
49
|
- [Realtime def shapes](llms/kinds-realtime.md): Read when the workspace defines a `realtimeServer()`, `realtimeChannel()`, or `realtimeMessage()` handler.
|
|
50
50
|
- [Triggers](llms/triggers.md): Read when authoring any trigger. A trigger's `stack` is a callback rather than the plain array every other kind takes, so the shape does not carry over.
|
|
51
51
|
- [Array and database statements](llms/statements-data.md): Read when the stack reads or writes rows (`s.db.*`), or transforms an array in place (`s.array.map`, `s.array.union`).
|
|
@@ -507,7 +507,7 @@ Choose by who or what starts the work. Each rule names the kind that fits and th
|
|
|
507
507
|
- **Work on a timer** → `task` (cron or interval). **Work a request starts but does not wait for** → `s.function.run({ fn, runtime: { mode: "async-shared" } })`, which binds a job id, not the result (collect with `s.await`). **Work that follows a row change** → `tableTrigger`: it fires on every insert/update/delete of the table, whichever stack writes it, so the same side effect placed in one endpoint's stack misses every other write path.
|
|
508
508
|
- **The same steps before or after many objects** (an auth check, a rate limit, logging) → `middleware`, attached per host (`middleware: { pre, post }` on a query, function, task, tool or API group) or to every host of a kind with `workspaceConfig({ middleware: { query, function, task, tool } })` — not a function call repeated at the top of each stack.
|
|
509
509
|
- **Related rows on returned rows** → an `addon` attached to the read through its `addon: [{ addon, as, input }]` option (`db.query`/`get`/`add`/`edit`/`patch`), merged onto each row under `as` and typed in `InferResponse` — not a second read plus a loop that stitches rows together.
|
|
510
|
-
- **AI.** An LLM running inside the backend → `agent()`, started from a stack with `s.ai.agent.run`; it has no public endpoint. An external AI client (Claude, Cursor, any MCP client) calling the backend → `mcpServer()`. Standing instructions for Xano's own builder AI → `knowledge()
|
|
510
|
+
- **AI.** An LLM running inside the backend → `agent()`, started from a stack with `s.ai.agent.run`; it has no public endpoint. An external AI client (Claude, Cursor, any MCP client) calling the backend → `mcpServer()`. Standing instructions for Xano's own builder AI → `knowledge()` (a local coding agent reads the same files in the repo); an `agent()` run never reads it. The actions either one calls → `tool()`. What an MCP server serves besides tools (`prompt()`, `resource()`) and when each fits: `llms/kinds-agent-mcp.md`.
|
|
511
511
|
- **Pushing to connected clients** → `realtimeServer` → `realtimeChannel` → `realtimeMessage` (the handler for a frame a client sends — the realtime analogue of a query). A server-side push from any stack is `s.realtime.publish`; a client polling a `query` is the substitute this replaces.
|
|
512
512
|
- **Code the typed surface cannot express** → a lambda (`s.lambda`, `fl.lambda`) for a short JavaScript body, LAST, after native filters and expressions (`llms/lambda.md`); a `microservice` for a long-running container or another language; `s.api.request` for a service that already has an HTTP API.
|
|
513
513
|
- **Tests** → `tests` on a `query`/`defineFunction`/`middleware` for that one object's input → output; a `workflowTest` for a flow across objects (`s.function.call`, `s.api.call`, `s.task.call`) asserted with `s.expect.*`.
|
|
@@ -539,7 +539,7 @@ Choose by who or what starts the work. Each rule names the kind that fits and th
|
|
|
539
539
|
- channel: `realtimeChannel` → `Xano.registerRealtimeChannels` → payload `channel` — A realtime channel: a joinable path on a realtime server (`rooms/{room_id}`) with typed path params, join/publish policy, a client-visible conversation transcript, and delivery semantics. Owns message handlers. Returns a handle with `getChannel(params)` for the path a client joins.
|
|
540
540
|
- message: `realtimeMessage` → `Xano.registerRealtimeMessages` → payload `message` — A realtime message handler: a named message type on a channel with its own typed payload and stack — the realtime analogue of a query. Pass the `realtimeChannel()` handle as `channel` and the owning server comes with it.
|
|
541
541
|
- microservice: `microservice` → `Xano.registerMicroservices` → payload `microservice` — A container workload deployed alongside the workspace, called from a stack with `s.microservice.request`. Def shapes (`builtin` containers vs a `helm` chart) and the SECRET-handling rules its config carries: `llms/statements-calls.md`.
|
|
542
|
-
- knowledge: `knowledge` → `Xano.registerKnowledge` → payload `knowledge` — Markdown Xano's own AI (the builder agent,
|
|
542
|
+
- knowledge: `knowledge` → `Xano.registerKnowledge` → payload `knowledge` — Markdown shared by every AI that builds the backend — Xano's own AI (the builder agent, Meta API / MCP readers) and a local coding agent reading the same files — never an `agent()` run: an `agents.md` of standing instructions, a `skill`, or a `doc`. The body is a real markdown FILE via `knowledgeFile("./x.md", import.meta.url)`, and `mode` decides how much of it reaches the agent.
|
|
543
543
|
- workspace: `workspaceConfig` → `Xano.registerWorkspace` → payload `workspace` — Workspace-level configuration such as default middleware chains and request-history defaults per host kind.
|
|
544
544
|
|
|
545
545
|
# Core def shapes
|
|
@@ -901,9 +901,9 @@ The run is isolated in ways that make a correct test fail for reasons the failur
|
|
|
901
901
|
|
|
902
902
|
# Knowledge def shape
|
|
903
903
|
|
|
904
|
-
> Read when the workspace defines a `knowledge()` item
|
|
904
|
+
> Read when the workspace defines a `knowledge()` item.
|
|
905
905
|
|
|
906
|
-
- `knowledge({ name, description?, type?, mode?, enabled?, body, refs?, guid?, tags? })` — markdown Xano's own AI reads before it acts — the workspace's builder agent, and outside agents reading the workspace through the Meta API or MCP. It does NOT reach an `agent()` run by `s.ai.agent.run`, whatever its `type` or `mode`: put what such an agent must know in its `llm.systemPrompt`. Takes `registerKnowledge`.
|
|
906
|
+
- `knowledge({ name, description?, type?, mode?, enabled?, body, refs?, guid?, tags? })` — markdown shared by every AI that builds the backend: Xano's own AI reads it before it acts — the workspace's builder agent, and outside agents reading the workspace through the Meta API or MCP — and a local coding agent reads the same `.md` files in the repo; deploy and `pull` keep the copies in sync. It does NOT reach an `agent()` run by `s.ai.agent.run`, whatever its `type` or `mode`: put what such an agent must know in its `llm.systemPrompt`. Takes `registerKnowledge`.
|
|
907
907
|
- `body` (REQUIRED): `knowledgeFile("./runbook.md", import.meta.url)` — a path to a real markdown FILE. There is no inline-string form. The path resolves relative to the MODULE THAT DECLARES the item, not the process working directory and not the workspace entry; `import.meta.url` is required and is what makes that true.
|
|
908
908
|
- `refs?`: `knowledgeDir("./runbook", import.meta.url)` — a directory whose WHOLE tree ships, recursively, paths preserved: UTF-8 text only (else refused; binary `.DS_Store` skipped), symlinks not followed. Keep the body OUT of it, or it ships as a reference file.
|
|
909
909
|
- `type?`: `"skill"` (default) | `"doc"` | `"agents.md"`. `skill` and `doc` differ in how they are filed, not in what an agent receives.
|
package/llms.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# xanosdk v1.0.
|
|
1
|
+
# xanosdk v1.0.13
|
|
2
2
|
|
|
3
3
|
> TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.
|
|
4
4
|
|
|
@@ -45,7 +45,7 @@ plain file read resolves them at the version you have.
|
|
|
45
45
|
- [Error index](llms/errors.md): Read when a request, test, build, or pull fails with a message you did not write — the string, its cause, and where the fix is.
|
|
46
46
|
- [Saved unit tests, assertions, and mocks](llms/tests.md): Read when authoring a `workflowTest()` stack, when a query/function/middleware carries `tests`, when a statement needs a `mock`, or when running a deployed environment's tests.
|
|
47
47
|
- [Agent and MCP def shapes](llms/kinds-agent-mcp.md): Read when building an MCP server (tools, prompts, resources) or an `agent()`.
|
|
48
|
-
- [Knowledge def shape](llms/kinds-knowledge.md): Read when the workspace defines a `knowledge()` item
|
|
48
|
+
- [Knowledge def shape](llms/kinds-knowledge.md): Read when the workspace defines a `knowledge()` item.
|
|
49
49
|
- [Realtime def shapes](llms/kinds-realtime.md): Read when the workspace defines a `realtimeServer()`, `realtimeChannel()`, or `realtimeMessage()` handler.
|
|
50
50
|
- [Triggers](llms/triggers.md): Read when authoring any trigger. A trigger's `stack` is a callback rather than the plain array every other kind takes, so the shape does not carry over.
|
|
51
51
|
- [Array and database statements](llms/statements-data.md): Read when the stack reads or writes rows (`s.db.*`), or transforms an array in place (`s.array.map`, `s.array.union`).
|
package/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xanosdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.",
|
|
5
5
|
"coverage": {
|
|
6
6
|
"objectKinds": {
|
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
"kind": "knowledge",
|
|
383
383
|
"payloadKey": "knowledge",
|
|
384
384
|
"authorFactory": "knowledge",
|
|
385
|
-
"description": "Markdown Xano's own AI (the builder agent,
|
|
385
|
+
"description": "Markdown shared by every AI that builds the backend — Xano's own AI (the builder agent, Meta API / MCP readers) and a local coding agent reading the same files — never an `agent()` run: an `agents.md` of standing instructions, a `skill`, or a `doc`. The body is a real markdown FILE via `knowledgeFile(\"./x.md\", import.meta.url)`, and `mode` decides how much of it reaches the agent.",
|
|
386
386
|
"registerMethod": "registerKnowledge",
|
|
387
387
|
"registered": true
|
|
388
388
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xano/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "The official TypeScript SDK for Xano, one platform to build, run and govern AI-built software. Your coding agent writes the backend in TypeScript, you run it on the Xano Engine on your machine, then deploy it to Xano.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"xanosdk",
|
|
@@ -14,8 +14,8 @@ description: >-
|
|
|
14
14
|
FastAPI) unless the user asks for Xano.
|
|
15
15
|
license: MIT
|
|
16
16
|
metadata:
|
|
17
|
-
xanosdk-version: "1.0.
|
|
18
|
-
xanosdk-digest: "sha256:
|
|
17
|
+
xanosdk-version: "1.0.13"
|
|
18
|
+
xanosdk-digest: "sha256:5af311994df498c279a5f24b3f605468a690f046d8bddf612c938142ee46c759"
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
# Xano backend
|