@xanots/sdk 0.0.6 → 0.0.8

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 (63) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/{agent-file-refresh-6XT23SLU.js → agent-file-refresh-4W37DGXS.js} +3 -3
  4. package/dist/bin.js +6 -6
  5. package/dist/{branch-commands-R4FR75UW.js → branch-commands-PBQ36L4A.js} +3 -3
  6. package/dist/{chunk-JRGDLAEA.js → chunk-2ROR3AZC.js} +2 -2
  7. package/dist/{chunk-OR43PDCW.js → chunk-3EYUR3TX.js} +2 -2
  8. package/dist/{chunk-GC7ZQHW7.js → chunk-3MDKV2VA.js} +5 -4
  9. package/dist/{chunk-SG4UBJ47.js → chunk-3QW5NFZJ.js} +26 -5
  10. package/dist/{chunk-2SUCC4DV.js → chunk-4PE4ZAB7.js} +2 -2
  11. package/dist/{chunk-CQBJNFDK.js → chunk-64QK6JEK.js} +22 -7
  12. package/dist/{chunk-CU5VOSTW.js → chunk-7AXQKABT.js} +4 -4
  13. package/dist/{chunk-EFH4NFPY.js → chunk-7JDT4PBU.js} +70 -6
  14. package/dist/{chunk-LLWK6H77.js → chunk-BKDJN76G.js} +31 -1
  15. package/dist/{chunk-4HDOP7LH.js → chunk-C3M5K4ZH.js} +3 -3
  16. package/dist/{chunk-Y7BARS25.js → chunk-CDAQUY5W.js} +2 -2
  17. package/dist/{chunk-TYBB7ON3.js → chunk-EM5QPTXP.js} +11 -11
  18. package/dist/{chunk-3FQD3QME.js → chunk-FEQTQ6PM.js} +65 -11
  19. package/dist/{chunk-AAFBSOSD.js → chunk-JQJPFUZI.js} +3 -3
  20. package/dist/{chunk-WJYB7DSI.js → chunk-MDXR5E5Q.js} +2 -2
  21. package/dist/{chunk-OLQLJY5T.js → chunk-OYMR5AMJ.js} +2 -2
  22. package/dist/{chunk-QVSUMHNN.js → chunk-PYS7UNNW.js} +2 -2
  23. package/dist/{chunk-P5OAM3G2.js → chunk-QIWBCS7N.js} +2 -2
  24. package/dist/{chunk-SOCYCBYG.js → chunk-SNO3KHCY.js} +23 -23
  25. package/dist/{chunk-CEFYM6N5.js → chunk-XP7S3VWY.js} +4 -4
  26. package/dist/cli.js +5 -5
  27. package/dist/{codegen-command-6XXOIQ25.js → codegen-command-U2W72DLG.js} +13 -13
  28. package/dist/{deploy-command-MTQQXPOO.js → deploy-command-QZ3GNLAD.js} +12 -12
  29. package/dist/{env-target-C5JFLDK3.js → env-target-NAYVEXBH.js} +6 -6
  30. package/dist/{ephemeral-command-K3UJSDS4.js → ephemeral-command-DL7EY4LL.js} +7 -7
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +6 -6
  33. package/dist/{init-command-AY4KSXR5.js → init-command-4MG3UKUO.js} +8 -8
  34. package/dist/internal.d.ts +2 -2
  35. package/dist/internal.js +112 -55
  36. package/dist/{io-65CJNLYI.js → io-M7XZEMK7.js} +3 -3
  37. package/dist/{lock-PDFCNYUW.js → lock-GFXD6G2E.js} +6 -2
  38. package/dist/{lock-commands-MC6I3MZA.js → lock-commands-Y4S4NUCE.js} +6 -6
  39. package/dist/{login-command-LCOOOPO2.js → login-command-DFCURZLC.js} +3 -3
  40. package/dist/{logout-command-J2AG5NKC.js → logout-command-WXVZQCAV.js} +2 -2
  41. package/dist/node.d.ts +2 -2
  42. package/dist/node.js +8 -8
  43. package/dist/{profile-command-ZPC2DPFV.js → profile-command-QJAAUZIV.js} +3 -3
  44. package/dist/{release-command-V4K4IORX.js → release-command-DN75G5GJ.js} +26 -14
  45. package/dist/{sandbox-details-command-DMY2KGA2.js → sandbox-details-command-EDO56IY3.js} +4 -4
  46. package/dist/{sandbox-export-command-R6QMEK3D.js → sandbox-export-command-MO6DEZ7Z.js} +5 -5
  47. package/dist/{store-BJONDJoZ.d.ts → store-CUCBSYLj.d.ts} +8 -4
  48. package/dist/{test-command-OEBIGOPP.js → test-command-RRNNJ45I.js} +6 -6
  49. package/dist/{upgrade-command-52AAZ3NV.js → upgrade-command-XFOAWDI3.js} +9 -9
  50. package/dist/{validate-command-KTLPSSH7.js → validate-command-GLF5ZOOW.js} +7 -7
  51. package/dist/{workspace-command-LX5S5N2H.js → workspace-command-QCFELEGR.js} +16 -16
  52. package/guides/environment.md +6 -3
  53. package/llms/fields.md +9 -0
  54. package/llms/kinds-core.md +2 -1
  55. package/llms/lambda.md +1 -1
  56. package/llms/legacy.md +1 -1
  57. package/llms/lock.md +32 -0
  58. package/llms/object-kinds.md +2 -2
  59. package/llms/statements-calls.md +9 -2
  60. package/llms-full.txt +106 -56
  61. package/llms.txt +49 -49
  62. package/manifest.json +2 -2
  63. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -11,6 +11,38 @@ listed here.
11
11
 
12
12
  ---
13
13
 
14
+ ## 0.0.7 — Verb pairs on one path
15
+
16
+ _2026-08-29_ · [release notes](https://github.com/xanots/sdk/releases/tag/v0.0.7)
17
+
18
+ Queries are now identified the way the engine identifies them — by api group, verb, and name together — so `GET /items` and `POST /items` are two endpoints instead of one export error. The grounding docs an AI agent reads got a full pass for people arriving at Xano for the first time, and two silent-failure classes now surface at `export()` instead of on a live endpoint.
19
+
20
+ - A `GET` and `POST` on the same path no longer collide
21
+ - ⚠️ A query's verb and api group are now part of its identity
22
+ - ⚠️ `s.api.call` takes the query handle, not a bare name
23
+ - A tagged value in a template literal now fails the build instead of shipping garbage
24
+ - The grounding docs assume no prior Xano knowledge
25
+ - `xanots deploy` no longer loops on "re-run the deploy" when your session has expired
26
+
27
+ ---
28
+
29
+ ## 0.0.6 — The action identity fix
30
+
31
+ _2026-08-28_ · [release notes](https://github.com/xanots/sdk/releases/tag/v0.0.6)
32
+
33
+ `action.call` and `action.package.call` now take the identity the instance assigned at install
34
+ instead of deriving one from a name. A derived id is well-formed and addresses nothing, so those
35
+ calls exported clean and never resolved — if you have either in a workspace, this is a call-site
36
+ change you need to make. Alongside it: a lock-file false positive that refused a legal workspace,
37
+ and a grounding correction about what an omitted column on `db.add` actually stores.
38
+
39
+ - ⚠️ `action.call` takes the id the instance assigned, not one derived from a name
40
+ - One canonical on two different kinds is no longer a lock error
41
+ - An omitted column on `db.add` lands on its own default, not `null`
42
+ - `xanots init` asks two questions instead of three
43
+
44
+ ---
45
+
14
46
  ## 0.0.5 — Sign in without a loopback
15
47
 
16
48
  _2026-08-26_ · [release notes](https://github.com/xanots/sdk/releases/tag/v0.0.5)
@@ -1 +1 @@
1
- 2ea4560ab5068ad3f41aaaccf9f6084502c807310086df6cd6a011bb8ab31aec
1
+ 049c8539dd912ef18bb98e2cff4c903b31ac405b1efe787dc50be5d15411935c
@@ -3,8 +3,8 @@ import {
3
3
  codingAgentDetected,
4
4
  isCI,
5
5
  refreshAgentFiles
6
- } from "./chunk-P5OAM3G2.js";
7
- import "./chunk-2SUCC4DV.js";
6
+ } from "./chunk-QIWBCS7N.js";
7
+ import "./chunk-4PE4ZAB7.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-6XT23SLU.js.map
17
+ //# sourceMappingURL=agent-file-refresh-4W37DGXS.js.map
package/dist/bin.js CHANGED
@@ -1,27 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  maybeNotifyUpdate
4
- } from "./chunk-Y7BARS25.js";
4
+ } from "./chunk-CDAQUY5W.js";
5
5
  import {
6
6
  readVersion,
7
7
  run
8
- } from "./chunk-SOCYCBYG.js";
8
+ } from "./chunk-SNO3KHCY.js";
9
9
  import {
10
10
  exitCodeOf,
11
11
  reportFailure
12
12
  } from "./chunk-JQLR64UC.js";
13
- import "./chunk-OLQLJY5T.js";
13
+ import "./chunk-OYMR5AMJ.js";
14
14
  import "./chunk-GNPVYOPB.js";
15
15
  import {
16
16
  clearProgress,
17
17
  error
18
18
  } from "./chunk-EZG76F7R.js";
19
- import "./chunk-3FQD3QME.js";
19
+ import "./chunk-FEQTQ6PM.js";
20
20
  import "./chunk-OKNSR7MT.js";
21
- import "./chunk-CQBJNFDK.js";
21
+ import "./chunk-64QK6JEK.js";
22
22
  import "./chunk-WHOJWOSV.js";
23
23
  import "./chunk-5XZ744TS.js";
24
- import "./chunk-EFH4NFPY.js";
24
+ import "./chunk-7JDT4PBU.js";
25
25
 
26
26
  // src/emit/interrupt.ts
27
27
  var EXIT_SIGINT = 130;
@@ -9,8 +9,8 @@ import {
9
9
  } from "./chunk-4PTSTDIG.js";
10
10
  import {
11
11
  getAccessToken
12
- } from "./chunk-SG4UBJ47.js";
13
- import "./chunk-LLWK6H77.js";
12
+ } from "./chunk-3QW5NFZJ.js";
13
+ import "./chunk-BKDJN76G.js";
14
14
  import {
15
15
  isMachineOutput,
16
16
  writeJson
@@ -131,4 +131,4 @@ Promote another branch first (\`xanots workspace branch set-live <other>\`), the
131
131
  export {
132
132
  runBranchCommand
133
133
  };
134
- //# sourceMappingURL=branch-commands-R4FR75UW.js.map
134
+ //# sourceMappingURL=branch-commands-PBQ36L4A.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  c,
3
3
  resp
4
- } from "./chunk-CQBJNFDK.js";
4
+ } from "./chunk-64QK6JEK.js";
5
5
 
6
6
  // src/values/expect.ts
7
7
  var TEST_EXPECT_TYPES = [
@@ -90,4 +90,4 @@ export {
90
90
  TEST_EXPECT_TYPES,
91
91
  expect
92
92
  };
93
- //# sourceMappingURL=chunk-JRGDLAEA.js.map
93
+ //# sourceMappingURL=chunk-2ROR3AZC.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-NDZFBZHC.js";
5
5
  import {
6
6
  getAccessToken
7
- } from "./chunk-SG4UBJ47.js";
7
+ } from "./chunk-3QW5NFZJ.js";
8
8
  import {
9
9
  isMachineOutput,
10
10
  writeJson
@@ -97,4 +97,4 @@ export {
97
97
  fetchSandboxDetails,
98
98
  runSandboxDetailsCommand
99
99
  };
100
- //# sourceMappingURL=chunk-OR43PDCW.js.map
100
+ //# sourceMappingURL=chunk-3EYUR3TX.js.map
@@ -35,7 +35,7 @@ import {
35
35
  registerKind,
36
36
  tableColumns,
37
37
  withFilters
38
- } from "./chunk-CQBJNFDK.js";
38
+ } from "./chunk-64QK6JEK.js";
39
39
  import {
40
40
  assertPathParamInputs,
41
41
  fillPathParams,
@@ -50,8 +50,9 @@ import {
50
50
  import {
51
51
  deriveGuid,
52
52
  realtimeChannelSeedName,
53
+ resolveQueryRef,
53
54
  resolveRef
54
- } from "./chunk-EFH4NFPY.js";
55
+ } from "./chunk-7JDT4PBU.js";
55
56
 
56
57
  // src/statements/set-var.ts
57
58
  var SET_VAR = "mvp:set_var";
@@ -482,7 +483,7 @@ function functionCall(args) {
482
483
  function apiCall(args) {
483
484
  args = argsOrEmpty(args);
484
485
  assertArg("mvp:workspace_run_endpoint", "api", args.api);
485
- const context = { id: resolveRef("query", args.api) };
486
+ const context = { id: resolveQueryRef(args.api) };
486
487
  const headers = coerceHeaders(args.headers);
487
488
  if (headers) context.headers = vf(headers);
488
489
  if (args.auth) {
@@ -3733,4 +3734,4 @@ export {
3733
3734
  workspaceKind,
3734
3735
  workspaceConfig
3735
3736
  };
3736
- //# sourceMappingURL=chunk-GC7ZQHW7.js.map
3737
+ //# sourceMappingURL=chunk-3MDKV2VA.js.map
@@ -7,12 +7,14 @@ import {
7
7
  globalAuthFilePath,
8
8
  localAuthFilePath,
9
9
  oauthErrorCode,
10
+ oauthErrorResponse,
10
11
  readCredential,
11
12
  resolveAuthFilePath,
12
13
  resolveAuthHost,
14
+ resolveOAuthErrorCode,
13
15
  resolveScope,
14
16
  writeCredential
15
- } from "./chunk-LLWK6H77.js";
17
+ } from "./chunk-BKDJN76G.js";
16
18
  import {
17
19
  detail,
18
20
  hostLabel,
@@ -40,7 +42,26 @@ function refreshAccessToken(authHost, clientId, refreshToken, scope) {
40
42
  return provider.refresh(refreshToken, { scope });
41
43
  }
42
44
  function isTransientRefreshError(err) {
43
- return oauthErrorCode(err) === void 0;
45
+ if (oauthErrorCode(err) !== void 0) return false;
46
+ const res = oauthErrorResponse(err);
47
+ if (res === void 0) return true;
48
+ return res.status >= 500;
49
+ }
50
+ async function describeRefreshFailure(err) {
51
+ const base = err instanceof Error ? err.message : String(err);
52
+ const res = oauthErrorResponse(err);
53
+ if (res === void 0) return base;
54
+ const parts = [`HTTP ${res.status}`];
55
+ const code = await resolveOAuthErrorCode(err);
56
+ if (code !== void 0) parts.push(code);
57
+ else if (!res.bodyUsed) {
58
+ try {
59
+ const text = (await res.clone().text()).trim();
60
+ if (text !== "") parts.push(text.length > 200 ? `${text.slice(0, 197)}\u2026` : text);
61
+ } catch {
62
+ }
63
+ }
64
+ return `${base} (${parts.join(" \u2014 ")})`;
44
65
  }
45
66
  async function refreshWithRetry(authHost, clientId, refreshToken, scope) {
46
67
  try {
@@ -215,8 +236,8 @@ async function refreshUnderLock(authFilePath, saved) {
215
236
  try {
216
237
  set = await refreshWithRetry(current.auth_host, current.client_id, current.refresh_token, current.scope);
217
238
  } catch (err) {
218
- const message = err instanceof Error ? err.message : String(err);
219
- if (oauthErrorCode(err) === "invalid_grant") {
239
+ const message = await describeRefreshFailure(err);
240
+ if (await resolveOAuthErrorCode(err) === "invalid_grant") {
220
241
  clearCredential(authFilePath);
221
242
  throw new Error(
222
243
  `Session for ${instance} has expired or was revoked (the refresh token was rejected). Run \`xanots login\` to sign in again.`
@@ -251,4 +272,4 @@ export {
251
272
  envMetaCredentialVarsSet,
252
273
  getAccessToken
253
274
  };
254
- //# sourceMappingURL=chunk-SG4UBJ47.js.map
275
+ //# sourceMappingURL=chunk-3QW5NFZJ.js.map
@@ -31,7 +31,7 @@ that reads well, type-checks, and is wrong. Read before writing:
31
31
  conditions are for.
32
32
  3. \`node_modules/@xanots/sdk/manifest.json\` \u2014 only for per-entry detail neither
33
33
  carries: a statement's full field schema with engine defaults, a filter's
34
- complete argument list. Grep or \`jq\` the one entry you need; it is ~55k
34
+ complete argument list. Grep or \`jq\` the one entry you need; it is ~65k
35
35
  tokens, so never read it whole.
36
36
 
37
37
  The published types and JSDoc (\`node_modules/@xanots/sdk/**/*.d.ts\`) are that
@@ -442,4 +442,4 @@ export {
442
442
  resolveAiPresets,
443
443
  scaffoldProject
444
444
  };
445
- //# sourceMappingURL=chunk-2SUCC4DV.js.map
445
+ //# sourceMappingURL=chunk-4PE4ZAB7.js.map
@@ -14,12 +14,16 @@ import {
14
14
  registerStatement
15
15
  } from "./chunk-5XZ744TS.js";
16
16
  import {
17
+ appNamesByGuid,
17
18
  deriveGuid,
19
+ deriveQueryGuid,
18
20
  getLockedCanonical,
19
21
  lockKey,
22
+ lockNameForObject,
23
+ queryGroupComponent,
20
24
  resolveRef,
21
25
  sha1Bytes
22
- } from "./chunk-EFH4NFPY.js";
26
+ } from "./chunk-7JDT4PBU.js";
23
27
 
24
28
  // src/types/xdo.ts
25
29
  var TAGS = [
@@ -1452,9 +1456,13 @@ var input = {
1452
1456
  *
1453
1457
  * It is NOT a stored file resource and cannot be written to a file column
1454
1458
  * directly. Store it first and write what you get back:
1455
- * `s.storage.create_image({ as: "img", value: ref("input.avatar") })`, then
1456
- * write `ref("img")` to an `f.image()` column. Use {@link input.image} and
1457
- * friends only when the caller already sends a stored file resource.
1459
+ * `s.storage.create_image({ as: "img", value: inp("avatar") })`, then write
1460
+ * `ref("img")` to an `f.image()` column. Use {@link input.image} and friends
1461
+ * only when the caller already sends a stored file resource.
1462
+ *
1463
+ * Read the upload with `inp`, NOT `ref("input.avatar")`: `ref` is the `var`
1464
+ * tag, so that spelling makes the engine look for a stack variable named
1465
+ * `input` and fail the request with `Missing var entry: input`.
1458
1466
  */
1459
1467
  file: makeInput("file"),
1460
1468
  /**
@@ -3535,10 +3543,15 @@ function encodeQuery(def) {
3535
3543
  resolveMockKeys(xdo.run, xdo.test, "query", def.name);
3536
3544
  return xdo;
3537
3545
  }
3546
+ function queryGuid(def) {
3547
+ if (def.guid) return def.guid;
3548
+ return deriveQueryGuid(queryGroupComponent(def), def.verb, def.name);
3549
+ }
3538
3550
  var queryKind = {
3539
3551
  name: "query",
3540
3552
  payloadKey: "query",
3541
- encode: encodeQuery
3553
+ encode: encodeQuery,
3554
+ guidOf: (def) => queryGuid(def)
3542
3555
  };
3543
3556
  registerKind(queryKind);
3544
3557
  function resolveCanonical(def, override) {
@@ -3749,6 +3762,7 @@ function calcSignatureJson(exportObj) {
3749
3762
  }
3750
3763
  function assertUniqueGuids(payload, lock) {
3751
3764
  const seen = /* @__PURE__ */ new Map();
3765
+ const appNames = appNamesByGuid(payload.app);
3752
3766
  for (const key of PAYLOAD_ARRAY_KEYS) {
3753
3767
  const arr = payload[key];
3754
3768
  if (!Array.isArray(arr)) continue;
@@ -3761,7 +3775,8 @@ function assertUniqueGuids(payload, lock) {
3761
3775
  const prev = seen.get(guid);
3762
3776
  if (prev !== void 0) {
3763
3777
  const pinnedBy = lock ? Object.entries(lock.objects).find(([, e]) => e.guid === guid)?.[0] : void 0;
3764
- const lockNote = pinnedBy ? ` This guid is pinned by lock entry "${pinnedBy}" \u2014 if that entry was moved by \`xanots lock rename\`, a new object now re-derives the old name's guid. Pin a distinct explicit \`guid\` on the new object, or update the lock entry.` : ` Object identity is derived from (type, name) \u2014 two objects of the same kind share a name. Rename one, or pin a distinct explicit \`guid\`.`;
3778
+ const legacyQueryKey = key === "query" && pinnedBy !== void 0 && !pinnedBy.includes("|") ? pinnedBy : void 0;
3779
+ const lockNote = legacyQueryKey ? ` Lock entry "${legacyQueryKey}" pins it by NAME ALONE \u2014 a lock written before a query's identity included its api group and verb. Both of these queries claim it. Move it onto the one that already existed, e.g. \`xanots lock rename query ${legacyQueryKey.slice("query:".length)} "${lockNameForObject("query", obj2, appNames)}"\` (--lock=<path> if it is not in the current directory), then re-export: that endpoint keeps its identity and the newcomer derives its own.` : pinnedBy ? ` This guid is pinned by lock entry "${pinnedBy}" \u2014 if that entry was moved by \`xanots lock rename\`, a new object now re-derives the old name's guid. Pin a distinct explicit \`guid\` on the new object, or update the lock entry.` : ` Object identity is derived from (type, name) \u2014 for a query, (api group, verb, name) \u2014 so two objects of the same kind compose the same identity. Rename one, or pin a distinct explicit \`guid\`.`;
3765
3780
  throw new Error(`Duplicate object guid (${guid}) shared by "${prev}" and "${label}".` + lockNote);
3766
3781
  }
3767
3782
  seen.set(guid, label);
@@ -4068,4 +4083,4 @@ export {
4068
4083
  serializeBundle,
4069
4084
  emitBundle
4070
4085
  };
4071
- //# sourceMappingURL=chunk-CQBJNFDK.js.map
4086
+ //# sourceMappingURL=chunk-64QK6JEK.js.map
@@ -6,7 +6,7 @@ import {
6
6
  realtimeChannelGuid,
7
7
  realtimeServerRefName,
8
8
  resolveRealtimeServerRef
9
- } from "./chunk-GC7ZQHW7.js";
9
+ } from "./chunk-3MDKV2VA.js";
10
10
  import {
11
11
  assertCanonical,
12
12
  assertOneOf,
@@ -25,7 +25,7 @@ import {
25
25
  resolveAuthRef,
26
26
  resolveMockKeys,
27
27
  warnLiveDatasource
28
- } from "./chunk-CQBJNFDK.js";
28
+ } from "./chunk-64QK6JEK.js";
29
29
  import {
30
30
  encodeStatement
31
31
  } from "./chunk-5XZ744TS.js";
@@ -35,7 +35,7 @@ import {
35
35
  lockKey,
36
36
  realtimeMessageSeedName,
37
37
  resolveRef
38
- } from "./chunk-EFH4NFPY.js";
38
+ } from "./chunk-7JDT4PBU.js";
39
39
 
40
40
  // src/kinds/canonical.ts
41
41
  function resolveCanonicalToken(label, payloadKey, accessor, def, override) {
@@ -667,4 +667,4 @@ export {
667
667
  addonKind,
668
668
  addon
669
669
  };
670
- //# sourceMappingURL=chunk-CU5VOSTW.js.map
670
+ //# sourceMappingURL=chunk-7AXQKABT.js.map
@@ -269,6 +269,39 @@ function realtimeMessageSeedName(server, channelPath, name) {
269
269
  seedPart("message", "name", name)
270
270
  ].join(SEED_SEP);
271
271
  }
272
+ function querySeedName(group, verb, name) {
273
+ return [
274
+ group === "" ? "" : seedPart("query", "apiGroup", group),
275
+ seedPart("query", "verb", verb),
276
+ seedPart("query", "name", name)
277
+ ].join(SEED_SEP);
278
+ }
279
+ function deriveQueryGuid(group, verb, name) {
280
+ const seed = `query:${querySeedName(group, verb, name)}`;
281
+ const guid = getLockedGuid(seed) ?? getLockedGuid(`query:${name}`) ?? rawDeriveGuid(seed);
282
+ SEEN_SEEDS.set(guid, seed);
283
+ return guid;
284
+ }
285
+ function queryGroupComponent(ref) {
286
+ if (ref.apiGroupId !== void 0) return `#${ref.apiGroupId}`;
287
+ const group = ref.apiGroup;
288
+ if (group === void 0) return "";
289
+ return typeof group === "string" ? group : group.name;
290
+ }
291
+ function resolveQueryRef(target) {
292
+ if (typeof target !== "string" && target.guid) {
293
+ if (target.name) SEEN_SEEDS.set(target.guid, `query:${target.name}`);
294
+ return target.guid;
295
+ }
296
+ const handle = typeof target === "string" ? void 0 : target;
297
+ if (handle?.verb !== void 0 && handle.name) {
298
+ return deriveQueryGuid(queryGroupComponent(handle), handle.verb, handle.name);
299
+ }
300
+ const label = typeof target === "string" ? `"${target}"` : `"${handle?.name ?? "?"}"`;
301
+ throw new Error(
302
+ `Cannot resolve query reference ${label}: a query's identity is composed from its api group, verb, and name, so a bare name cannot identify one. Pass the query() def handle (it carries all three), or a { name, guid } pair to address an object by explicit identity.`
303
+ );
304
+ }
272
305
  function rawDeriveGuid(seed) {
273
306
  return md5Hex(seed);
274
307
  }
@@ -321,6 +354,30 @@ function resolvePayloadKey(kindOrPayloadKey) {
321
354
  function lockKey(payloadKey, name) {
322
355
  return `${payloadKey}:${name}`;
323
356
  }
357
+ function lockNameForObject(payloadKey, obj, appNameByGuid) {
358
+ if (payloadKey !== "query") return obj.name;
359
+ const verb = typeof obj.verb === "string" ? obj.verb : "";
360
+ const appId = obj.app?.id;
361
+ let group = "";
362
+ if (typeof appId === "string" && appId !== "") {
363
+ group = appNameByGuid.get(appId) ?? appId;
364
+ } else if (typeof appId === "number" && appId !== 0) {
365
+ group = `#${appId}`;
366
+ }
367
+ return [group, verb, obj.name].join("|");
368
+ }
369
+ function appNamesByGuid(appSection) {
370
+ const map = /* @__PURE__ */ new Map();
371
+ if (!Array.isArray(appSection)) return map;
372
+ for (const row of appSection) {
373
+ if (!row || typeof row !== "object") continue;
374
+ const { name, guid } = row;
375
+ if (typeof name === "string" && typeof guid === "string" && guid !== "") {
376
+ map.set(guid, name);
377
+ }
378
+ }
379
+ return map;
380
+ }
324
381
  function emptyLock() {
325
382
  return { version: LOCK_VERSION, objects: {} };
326
383
  }
@@ -508,7 +565,7 @@ function recordObserved(ctx, key, identity) {
508
565
  const prior = ctx.observed[key];
509
566
  if (prior?.guid !== void 0 && identity.guid !== void 0 && prior.guid !== identity.guid) {
510
567
  throw new Error(
511
- `Two exported objects collapse onto lock key "${key}" with different guids (${prior.guid} vs ${identity.guid}) \u2014 two same-kind objects sharing a name: a query verb pair pinning explicit guids, or a kind whose identity is composed from more than the name (a realtime channel is unique per server, a message per channel). The lock keys identity by (type, name) and cannot track both; rename one of the objects.`
568
+ `Two exported objects collapse onto lock key "${key}" with different guids (${prior.guid} vs ${identity.guid}) \u2014 two same-kind objects sharing a name behind explicit guids, or a realtime kind whose identity is composed from more than the name (a channel is unique per server, a message per channel). The lock cannot track both under one key; rename one of the objects.`
512
569
  );
513
570
  }
514
571
  const entry = ctx.lock.objects[key];
@@ -573,6 +630,7 @@ function adoptFromBundle(lock, bundle, bundlePath) {
573
630
  objects[key] = after;
574
631
  }
575
632
  };
633
+ const appNames = appNamesByGuid(sections["app"]);
576
634
  for (const payloadKey of LOCK_PAYLOAD_KEYS) {
577
635
  const arr = sections[payloadKey];
578
636
  if (!Array.isArray(arr)) continue;
@@ -581,18 +639,19 @@ function adoptFromBundle(lock, bundle, bundlePath) {
581
639
  if (!obj || typeof obj !== "object") continue;
582
640
  const o = obj;
583
641
  if (typeof o.name !== "string" || typeof o.guid !== "string" || o.guid === "") continue;
584
- if (namesSeen.has(o.name)) {
642
+ const lockName = lockNameForObject(payloadKey, o, appNames);
643
+ if (namesSeen.has(lockName)) {
585
644
  throw new Error(
586
- `${bundlePath} contains two "${payloadKey}" objects named "${o.name}" (a query verb pair, most likely). The lock keys by (type, name) and cannot represent both \u2014 adoption aborted. Rename one of them engine-side so names are unique, then re-export and re-adopt.`
645
+ `${bundlePath} contains two "${payloadKey}" objects with the identity "${lockName}" \u2014 the lock keys identity per kind and cannot represent both. Adoption aborted; rename one of them engine-side, then re-export and re-adopt.`
587
646
  );
588
647
  }
589
- namesSeen.add(o.name);
648
+ namesSeen.add(lockName);
590
649
  const incoming = { guid: o.guid };
591
650
  if (typeof o.canonical === "string" && o.canonical !== "") {
592
651
  incoming.canonical = o.canonical;
593
652
  canonicalsSeen = true;
594
653
  }
595
- applyEntry(lockKey(payloadKey, o.name), incoming);
654
+ applyEntry(lockKey(payloadKey, lockName), incoming);
596
655
  }
597
656
  }
598
657
  const ws = sections["workspace"];
@@ -663,6 +722,9 @@ export {
663
722
  REFERENCEABLE_KINDS,
664
723
  realtimeChannelSeedName,
665
724
  realtimeMessageSeedName,
725
+ deriveQueryGuid,
726
+ queryGroupComponent,
727
+ resolveQueryRef,
666
728
  deriveGuid,
667
729
  guidSeedHint,
668
730
  resolveRef,
@@ -672,6 +734,8 @@ export {
672
734
  CANONICAL_PAYLOAD_KEYS,
673
735
  resolvePayloadKey,
674
736
  lockKey,
737
+ lockNameForObject,
738
+ appNamesByGuid,
675
739
  emptyLock,
676
740
  parseLock,
677
741
  validateLockModel,
@@ -683,4 +747,4 @@ export {
683
747
  adoptFromBundle,
684
748
  mergeObserved
685
749
  };
686
- //# sourceMappingURL=chunk-EFH4NFPY.js.map
750
+ //# sourceMappingURL=chunk-7JDT4PBU.js.map
@@ -122,6 +122,34 @@ function oauthErrorCode(err) {
122
122
  }
123
123
  return void 0;
124
124
  }
125
+ function oauthErrorResponse(err) {
126
+ const cause = err?.cause;
127
+ return typeof Response !== "undefined" && cause instanceof Response ? cause : void 0;
128
+ }
129
+ var OAUTH_ERROR_CODES = /* @__PURE__ */ new Set([
130
+ "invalid_request",
131
+ "invalid_client",
132
+ "invalid_grant",
133
+ "unauthorized_client",
134
+ "unsupported_grant_type",
135
+ "invalid_scope"
136
+ ]);
137
+ async function resolveOAuthErrorCode(err) {
138
+ const rfc = oauthErrorCode(err);
139
+ if (rfc !== void 0) return rfc;
140
+ const res = oauthErrorResponse(err);
141
+ if (res === void 0 || res.bodyUsed) return void 0;
142
+ try {
143
+ const body = await res.clone().json();
144
+ if (!body || typeof body !== "object") return void 0;
145
+ const fields = body;
146
+ for (const candidate of [fields.error, fields.message, fields.code]) {
147
+ if (typeof candidate === "string" && OAUTH_ERROR_CODES.has(candidate)) return candidate;
148
+ }
149
+ } catch {
150
+ }
151
+ return void 0;
152
+ }
125
153
  var OpenIdProvider = class {
126
154
  constructor(opts) {
127
155
  this.opts = opts;
@@ -470,6 +498,8 @@ export {
470
498
  DEFAULT_PORT,
471
499
  decodeAudience,
472
500
  oauthErrorCode,
501
+ oauthErrorResponse,
502
+ resolveOAuthErrorCode,
473
503
  OpenIdProvider,
474
504
  globalAuthFilePath,
475
505
  localAuthFilePath,
@@ -483,4 +513,4 @@ export {
483
513
  resolveScope,
484
514
  assertHttpsOrigin
485
515
  };
486
- //# sourceMappingURL=chunk-LLWK6H77.js.map
516
+ //# sourceMappingURL=chunk-BKDJN76G.js.map
@@ -2,7 +2,7 @@ import {
2
2
  presetFilePath,
3
3
  resolveAiPresets,
4
4
  scaffoldProject
5
- } from "./chunk-2SUCC4DV.js";
5
+ } from "./chunk-4PE4ZAB7.js";
6
6
  import {
7
7
  runNpmCapturingStderr
8
8
  } from "./chunk-ZSYZTGJH.js";
@@ -41,7 +41,7 @@ import {
41
41
  } from "./chunk-Q77KNEUL.js";
42
42
  import {
43
43
  readVersion
44
- } from "./chunk-SOCYCBYG.js";
44
+ } from "./chunk-SNO3KHCY.js";
45
45
  import {
46
46
  UsageError
47
47
  } from "./chunk-JQLR64UC.js";
@@ -470,4 +470,4 @@ export {
470
470
  projectShellFiles,
471
471
  runInitCommand
472
472
  };
473
- //# sourceMappingURL=chunk-4HDOP7LH.js.map
473
+ //# sourceMappingURL=chunk-C3M5K4ZH.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readVersion
3
- } from "./chunk-SOCYCBYG.js";
3
+ } from "./chunk-SNO3KHCY.js";
4
4
  import {
5
5
  atomicWrite
6
6
  } from "./chunk-GNPVYOPB.js";
@@ -170,4 +170,4 @@ export {
170
170
  upgradeCommand,
171
171
  maybeNotifyUpdate
172
172
  };
173
- //# sourceMappingURL=chunk-Y7BARS25.js.map
173
+ //# sourceMappingURL=chunk-CDAQUY5W.js.map
@@ -18,7 +18,7 @@ import {
18
18
  } from "./chunk-ZOYMZZ3S.js";
19
19
  import {
20
20
  getAccessToken
21
- } from "./chunk-SG4UBJ47.js";
21
+ } from "./chunk-3QW5NFZJ.js";
22
22
  import {
23
23
  exportWorkspaceBundle
24
24
  } from "./chunk-QTNO2WD6.js";
@@ -27,15 +27,15 @@ import {
27
27
  resolveFrontendPreset,
28
28
  resolveThemeChoice,
29
29
  sanitizeAppName
30
- } from "./chunk-4HDOP7LH.js";
30
+ } from "./chunk-C3M5K4ZH.js";
31
31
  import {
32
32
  XANO_DIR,
33
33
  resolveAiPresets,
34
34
  scaffoldProject
35
- } from "./chunk-2SUCC4DV.js";
35
+ } from "./chunk-4PE4ZAB7.js";
36
36
  import {
37
37
  TEST_EXPECT_TYPES
38
- } from "./chunk-JRGDLAEA.js";
38
+ } from "./chunk-2ROR3AZC.js";
39
39
  import {
40
40
  raw
41
41
  } from "./chunk-LU7TRWMC.js";
@@ -67,11 +67,11 @@ import {
67
67
  searchConstrainsRows,
68
68
  tableTrigger,
69
69
  workspaceTrigger
70
- } from "./chunk-GC7ZQHW7.js";
70
+ } from "./chunk-3MDKV2VA.js";
71
71
  import {
72
72
  loadDefault,
73
73
  readVersion
74
- } from "./chunk-SOCYCBYG.js";
74
+ } from "./chunk-SNO3KHCY.js";
75
75
  import {
76
76
  UsageError
77
77
  } from "./chunk-JQLR64UC.js";
@@ -115,7 +115,7 @@ import {
115
115
  sys,
116
116
  toolset,
117
117
  withFilters
118
- } from "./chunk-CQBJNFDK.js";
118
+ } from "./chunk-64QK6JEK.js";
119
119
  import {
120
120
  parsePathParams,
121
121
  unboundPathParams
@@ -130,7 +130,7 @@ import {
130
130
  } from "./chunk-5XZ744TS.js";
131
131
  import {
132
132
  REFERENCEABLE_KIND_PAYLOAD_KEYS
133
- } from "./chunk-EFH4NFPY.js";
133
+ } from "./chunk-7JDT4PBU.js";
134
134
 
135
135
  // src/emit/codegen-command.ts
136
136
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -6751,7 +6751,7 @@ async function fetchBundle(args, source) {
6751
6751
  if (source.kind === "sandbox") {
6752
6752
  const auth3 = await getAccessToken(args);
6753
6753
  step("Reading the sandbox workspace");
6754
- const { fetchSandboxBundle } = await import("./sandbox-export-command-R6QMEK3D.js");
6754
+ const { fetchSandboxBundle } = await import("./sandbox-export-command-MO6DEZ7Z.js");
6755
6755
  return {
6756
6756
  bundle: await fetchSandboxBundle(auth3),
6757
6757
  origin: { source: "sandbox", origin: auth3.instance }
@@ -6765,7 +6765,7 @@ async function fetchBundle(args, source) {
6765
6765
  );
6766
6766
  }
6767
6767
  const auth3 = await getAccessToken(args);
6768
- const { resolveLive, fetchEphemeralBundle } = await import("./ephemeral-command-K3UJSDS4.js");
6768
+ const { resolveLive, fetchEphemeralBundle } = await import("./ephemeral-command-DL7EY4LL.js");
6769
6769
  const summary = await resolveLive(auth3, auth3.workspaceId, name);
6770
6770
  step(`Reading ephemeral "${name}"`);
6771
6771
  return {
@@ -7034,4 +7034,4 @@ export {
7034
7034
  verifyCrashEntry,
7035
7035
  blameGeneratedFile
7036
7036
  };
7037
- //# sourceMappingURL=chunk-TYBB7ON3.js.map
7037
+ //# sourceMappingURL=chunk-EM5QPTXP.js.map