@vxil/sdk 0.13.0 → 0.14.0

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/dist/index.d.ts CHANGED
@@ -382,6 +382,55 @@ export interface JobRun {
382
382
  * the fire); `started_at − scheduled_for` is how late it started. null for a
383
383
  * run you enqueued (and for runs fired before 2026-10-01). */
384
384
  scheduled_for?: string | null;
385
+ /** the single-run read only: what the run completed with — the `result` of
386
+ * its signed callback's `completed` body, or the value a generation run
387
+ * settled with (the fields its status mirror received; an over-64 KiB value
388
+ * reads `{ truncated: true, bytes, max_bytes }`). null when nothing reported
389
+ * one — a handler's own 2xx response body is never stored. */
390
+ result?: unknown;
391
+ /** the single-run read only: the latest progress report of the run — a
392
+ * `processing` ping on its signed callback (plain run) or its provider's
393
+ * webhook (generation run). null until one arrives. */
394
+ progress?: JobRunProgress | null;
395
+ }
396
+ /** A run's latest progress report (`JobRun.progress`): only these keys pass. */
397
+ export interface JobRunProgress {
398
+ /** 0..100 */
399
+ progress?: number;
400
+ /** ≤ 64 chars */
401
+ stage?: string;
402
+ /** ≤ 200 chars */
403
+ message?: string;
404
+ /** when the report was stored (ISO) */
405
+ at: string;
406
+ }
407
+ /** The body an external worker POSTs to a run's signed `callback_url`
408
+ * (`postRunCallback`). `completed` ends the run `succeeded` with `result`
409
+ * stored (≤ 64 KiB of JSON); `failed` dead-letters it with `error`;
410
+ * `processing` only records progress (repeatable). On a run suspended in
411
+ * `jobs.wait(…)`, completed / failed WAKE the handler instead, with
412
+ * `payload.wakeup = { via: 'callback', status, result?, error? }`. */
413
+ export type RunCallbackBody = {
414
+ status: 'completed';
415
+ result?: unknown;
416
+ } | {
417
+ status: 'failed';
418
+ error?: string;
419
+ } | {
420
+ status: 'processing';
421
+ progress?: number;
422
+ stage?: string;
423
+ message?: string;
424
+ };
425
+ /** What a run callback answers: the run's state after it (`deduplicated: true`
426
+ * when the URL was already used or the run was already terminal — nothing
427
+ * changed). */
428
+ export interface RunCallbackAnswer {
429
+ run_id: string;
430
+ state: JobRun['state'];
431
+ deduplicated?: boolean;
432
+ woken?: boolean;
433
+ event?: string;
385
434
  }
386
435
  /** The run states no later write can move — what `waitForRun` and an
387
436
  * async+wait invoke resolve `done: true` on. */
@@ -475,7 +524,7 @@ export interface RateLimitOverride {
475
524
  created_at: string;
476
525
  updated_at?: string;
477
526
  }
478
- /** A payments provider webhook delivery in the event log (payments.md §7).
527
+ /** A payments provider webhook delivery in the event log (guide ch. 6, payments).
479
528
  * `payload` and `raw_body` are only populated on the detail read. */
480
529
  export interface PaymentsWebhookEvent {
481
530
  event_id: string;
@@ -508,7 +557,7 @@ export interface PaymentsWebhookEvent {
508
557
  raw_body?: string | null;
509
558
  provider_event_ts?: string | null;
510
559
  }
511
- /** The outcome of a provider re-sync / Restore Purchases (payments.md §7d). */
560
+ /** The outcome of a provider re-sync / Restore Purchases (guide ch. 6, payments). */
512
561
  export interface PaymentsSyncOutcome {
513
562
  provider: string;
514
563
  synced: number;
@@ -523,7 +572,7 @@ export interface PaymentsSyncOutcome {
523
572
  }>;
524
573
  dry_run?: boolean;
525
574
  }
526
- /** A lifecycle simulation run (payments.md §7d; mock/dev tenants only). */
575
+ /** A lifecycle simulation run (guide ch. 6, payments; mock/dev tenants only). */
527
576
  export interface PaymentsSimulationResult {
528
577
  scenario: string;
529
578
  run_id: string;
@@ -545,8 +594,8 @@ export interface PaymentsSimulationResult {
545
594
  pass: boolean;
546
595
  };
547
596
  }
548
- /** The ONE complete entitlement read (GET /v1/payments/entitlements; payments.md
549
- * §3a). `until` is the winning subscription's current_period_end (+ the
597
+ /** The ONE complete entitlement read (GET /v1/payments/entitlements; guide ch. 6,
598
+ * payments). `until` is the winning subscription's current_period_end (+ the
550
599
  * configured grace window when it is past_due); null on the free baseline. */
551
600
  export interface PaymentsEntitlementView {
552
601
  user_id: string;
@@ -581,7 +630,7 @@ export interface PaymentsEntitlementView {
581
630
  * `completed` (Paddle paid → completed). Handle `succeeded` gated on
582
631
  * `provider_status === 'completed'` plus `completed` to act once per charge. */
583
632
  export type PaymentsProviderChargeStatus = 'paid' | 'completed';
584
- /** A charge row as listed by GET /v1/payments/charges (payments.md §3). */
633
+ /** A charge row as listed by GET /v1/payments/charges (guide ch. 6, payments). */
585
634
  export interface PaymentsCharge {
586
635
  /** the vxil charge id (`chg_…`) — what refunds and a charge-linked grant key on */
587
636
  charge_id: string;
@@ -630,8 +679,8 @@ export interface PaymentsRefund {
630
679
  source: 'api' | 'webhook';
631
680
  created_at: string | null;
632
681
  }
633
- /** A subscription row as listed by GET /v1/payments/subscriptions (payments.md
634
- * §3) — provider subscriptions, manual grants and purchase passes alike.
682
+ /** A subscription row as listed by GET /v1/payments/subscriptions (guide ch. 6,
683
+ * payments) — provider subscriptions, manual grants and purchase passes alike.
635
684
  * `current_period_start` (2026-09-25) is the row's own window start: for a
636
685
  * purchase pass (`provider_sub_id: 'purchase:<charge_id>'`) the day its access
637
686
  * begins, which is in the FUTURE for a pass queued behind a live one; for a
@@ -661,9 +710,27 @@ export interface FileObject {
661
710
  size_bytes: number;
662
711
  status: 'pending' | 'available' | 'deleted';
663
712
  created_at: string;
713
+ /** The object's public URL when it is published to the public asset host
714
+ * (`files.publish`), else null. */
715
+ public_url?: string | null;
716
+ }
717
+ /** A published object (guide ch. 6, files, "Public asset delivery"): a stable,
718
+ * content-addressed URL on vxil's public asset host, served with
719
+ * `Cache-Control: public, max-age=31536000, immutable`. `variants` maps each
720
+ * declared image preset (`publicAssets.variants`) to its URL — images only. */
721
+ export interface PublishedFile {
722
+ object_id: string;
723
+ url: string;
724
+ sha256: string;
725
+ content_type: string;
726
+ size_bytes: number;
727
+ published_at: string | null;
728
+ variants: Record<string, string>;
664
729
  }
665
- /** A live shared link as listed by GET /v1/files/{id}/shared-links (files.md
666
- * §6). `downloads` is the burn-on-read counter; `max_downloads` null =
730
+ /** Why one id of a bulk publish was not published. */
731
+ export type PublishErrorCode = 'not_found' | 'upload_incomplete' | 'content_type_not_publishable' | 'object_too_large' | 'quota_exceeded' | 'batch_budget_exceeded' | 'asset_taken_down' | 'publish_failed';
732
+ /** A live shared link as listed by GET /v1/files/{id}/shared-links (guide ch. 6,
733
+ * files). `downloads` is the burn-on-read counter; `max_downloads` null =
667
734
  * unlimited (1 = a one-time link). A link that hit its cap, expired, or was
668
735
  * revoked no longer lists. */
669
736
  export interface FileSharedLink {
@@ -682,7 +749,7 @@ export interface CreateSharedLinkOptions {
682
749
  expires_at?: string;
683
750
  max_downloads?: number | null;
684
751
  }
685
- /** One recognized OCR text block (files.md §1.1). bbox is [x, y, w, h] in the
752
+ /** One recognized OCR text block (guide ch. 6, files). bbox is [x, y, w, h] in the
686
753
  * provider's unit space; page is 1-based. confidence is 0..1 normalized per
687
754
  * provider (Textract native 0..100 divided by 100; mock pins 0.95); absent
688
755
  * when the provider supplied none. */
@@ -923,7 +990,7 @@ export interface AiGenerationRecord {
923
990
  * generation) */
924
991
  result_state: 'stored' | 'purged' | 'not_recorded';
925
992
  }
926
- /** The `data` of `job.generation.queued` (jobs.md §11): the run was accepted. */
993
+ /** The `data` of `job.generation.queued` (guide ch. 6, jobs): the run was accepted. */
927
994
  export interface JobGenerationQueuedEventPayload {
928
995
  run_id: string;
929
996
  job_name: string;
@@ -971,10 +1038,13 @@ export interface JobRunEventPayload {
971
1038
  level?: 'error';
972
1039
  state?: 'broken';
973
1040
  /** `job.dead_lettered` only, and only when something other than the
974
- * executor killed the run: `reaped` (the stuck-run reaper) or
975
- * `queue_backstop` (the queue's own retries ran out). Absent when the run
1041
+ * executor killed the run: `reaped` (the stuck-run reaper),
1042
+ * `queue_backstop` (the queue's own retries ran out), `callback_failed`
1043
+ * (the run's signed callback reported `status: 'failed'`) or
1044
+ * `callback_timeout` (the handler handed the run off with a 202 and no
1045
+ * callback completed it within its lifetime). Absent when the run
976
1046
  * exhausted its attempts normally. */
977
- reason?: 'reaped' | 'queue_backstop';
1047
+ reason?: 'reaped' | 'queue_backstop' | 'callback_failed' | 'callback_timeout';
978
1048
  }
979
1049
  /** The provider-reported environment of the money (`production` | `sandbox`). */
980
1050
  export type PaymentsEventEnvironment = 'production' | 'sandbox';
@@ -1366,6 +1436,13 @@ export interface JobDelivery<P = unknown> {
1366
1436
  payload: P;
1367
1437
  /** a schedule-fired run only: the slot it was due for (ISO, UTC) */
1368
1438
  scheduled_for?: string;
1439
+ /** a run enqueued with `callback` only: its CURRENT single-use signed
1440
+ * callback URL. Hand it to the worker that finishes the job (no API key
1441
+ * needed) and answer 202 — the run waits until that worker POSTs
1442
+ * `{ status: 'completed', result }` / `{ status: 'failed', error }` /
1443
+ * `{ status: 'processing', progress, stage, message }` to it (see
1444
+ * `postRunCallback`). */
1445
+ callback_url?: string;
1369
1446
  }
1370
1447
  /** The `?since=` replay read (GET /v1/ai/generations/{id}/stream). */
1371
1448
  export interface AiResumePage {
@@ -1510,7 +1587,7 @@ export interface RagSearchHit {
1510
1587
  * vector-search (−1…1; null when retrieval used no query vector). */
1511
1588
  similarity?: number | null;
1512
1589
  /** the effective post-boost score results are RANKED by — present only when
1513
- * metadata boosts applied (rag.md §2f). */
1590
+ * metadata boosts applied (guide ch. 6, rag). */
1514
1591
  boosted_score?: number;
1515
1592
  metadata?: Record<string, unknown>;
1516
1593
  }
@@ -1527,7 +1604,7 @@ export interface RagSearchResult {
1527
1604
  };
1528
1605
  }
1529
1606
  /** A replayed frame page from the rag-native resume endpoint (proxies the ai
1530
- * §2a replay buffer: every recorded frame with seq > since, plus done). */
1607
+ * feature's replay buffer: every recorded frame with seq > since, plus done). */
1531
1608
  export interface RagResumePage {
1532
1609
  generation_id: string;
1533
1610
  since: number;
@@ -1751,7 +1828,7 @@ export interface DmConfigState {
1751
1828
  version: number;
1752
1829
  configured: boolean;
1753
1830
  }
1754
- /** The safe query subset the keyless cms public lane admits (roadmap §4.4): the
1831
+ /** The safe query subset the keyless cms public lane admits (guide ch. 4): the
1755
1832
  * same bounded filter/sort/limit/cursor as the authored list, minus anything
1756
1833
  * owner- or lifecycle-scoped (the lane FORCES status='published'). `filter` is a
1757
1834
  * JSON object, serialized to the wire `filter=` param. */
@@ -1773,7 +1850,7 @@ export interface CmsPublicRow {
1773
1850
  published_at: string | null;
1774
1851
  }
1775
1852
  /** Build the anonymous, KEYLESS public-delivery URL for a collection's PUBLISHED
1776
- * items (roadmap §4.4) — `{base}/v1/cms/public/:tenantId/:collection[?…]`. This is
1853
+ * items (guide ch. 4, "Draft and publish") — `{base}/v1/cms/public/:tenantId/:collection[?…]`. This is
1777
1854
  * the reader path a public blog/storefront/docs site hits with NO api key: the
1778
1855
  * edge mints a restricted read-only inner token bound to the URL tenant, forces
1779
1856
  * `status='published'`, and strips the collection's owner_field. PURE (no
@@ -1784,7 +1861,7 @@ export declare function cmsPublicUrl(tenantId: string, collection: string, query
1784
1861
  baseUrl?: string;
1785
1862
  }): string;
1786
1863
  /** Fetch a page of a collection's PUBLISHED items over the KEYLESS public lane
1787
- * (roadmap §4.4) — NO api key, no `Vxil` client, no auth of any kind. This is the
1864
+ * (guide ch. 4) — NO api key, no `Vxil` client, no auth of any kind. This is the
1788
1865
  * anonymous reader path (a blog/storefront/docs front-end). Returns the same
1789
1866
  * `{ items, next_cursor }` envelope the authed list does, but rows are stripped
1790
1867
  * to the public surface (`CmsPublicRow`) — drafts and the owner_field are never
@@ -1798,6 +1875,16 @@ export declare function listCmsPublic(tenantId: string, collection: string, quer
1798
1875
  items: CmsPublicRow[];
1799
1876
  next_cursor: string | null;
1800
1877
  }>;
1878
+ /** POST a run's single-use signed `callback_url` (guide ch. 6, "Hand a run to
1879
+ * an external worker") — KEYLESS: no API key, no `Vxil` client; the URL is the
1880
+ * credential, so call this from the worker that finishes the job (a render
1881
+ * farm, a GPU box, another queue's task). Idempotent: a repeat of a used URL
1882
+ * answers `deduplicated: true`. A non-2xx throws `VxilError` (401 a forged or
1883
+ * altered URL, 410 `callback_expired`, 413 `result_too_large`, 404 a run that
1884
+ * did not opt in). */
1885
+ export declare function postRunCallback(callbackUrl: string, body: RunCallbackBody, opts?: {
1886
+ fetch?: typeof fetch;
1887
+ }): Promise<RunCallbackAnswer>;
1801
1888
  /** The structural shape a `vxil gen`-generated `VxilSchema` satisfies. The base
1802
1889
  * `Vxil` class is generic over it (`new Vxil<VxilSchema>(...)`), exactly the
1803
1890
  * `createClient<Database>()` move — types are layered on; the runtime is
@@ -1952,12 +2039,12 @@ type DisabledFeatures<S extends VxilSchemaShape> = {
1952
2039
  [P in keyof FeatureMap]: FeatureMap[P] extends S['features'] ? never : P;
1953
2040
  }[keyof FeatureMap];
1954
2041
  /** The feature-narrowed client: feature namespaces the tenant hasn't enabled become
1955
- * a compile error (the design's §4.4 headline). `Vxil.connect<VxilSchema>()`
2042
+ * a compile error. `Vxil.connect<VxilSchema>()`
1956
2043
  * returns it; plain `new Vxil<VxilSchema>()` stays un-narrowed for back-compat. */
1957
2044
  export type EnabledVxil<S extends VxilSchemaShape> = Omit<Vxil<S>, DisabledFeatures<S>> & {
1958
2045
  [P in DisabledFeatures<S>]: DisabledFeature<FeatureMap[P] & string>;
1959
2046
  };
1960
- /** One config-declared per-record ACTION (cms.md §17): a button on a record row
2047
+ /** One config-declared per-record ACTION (guide ch. 4): a button on a record row
1961
2048
  * that invokes the deployed tenant function `fn` ONCE with `{ collection,
1962
2049
  * item_id, action, actor, item }`. Exactly one human-initiated step — no
1963
2050
  * conditions, no chaining, no scheduling. ≤8 per collection. */
@@ -1969,7 +2056,7 @@ export interface CmsActionDef {
1969
2056
  /** the deployed function name (/^[a-z][a-z0-9-]{0,47}$/) */
1970
2057
  fn: string;
1971
2058
  }
1972
- /** One live item referencing another through a relation field (cms.md §11.1). */
2059
+ /** One live item referencing another through a relation field (guide ch. 4). */
1973
2060
  export interface CmsBacklink {
1974
2061
  collection: string;
1975
2062
  field: string;
@@ -1986,7 +2073,7 @@ export interface CmsBacklinksPage {
1986
2073
  has_more: boolean;
1987
2074
  limit: number;
1988
2075
  }
1989
- /** ONE page of the slot re-index (cms.md §19). Loop while `complete` is false,
2076
+ /** ONE page of the slot re-index (guide ch. 4). Loop while `complete` is false,
1990
2077
  * feeding `next_cursor` back in. `skipped` counts rows a concurrent write moved
1991
2078
  * under the page — the re-index never overwrites them (their own writer
1992
2079
  * re-projected them), but a `$inc` or a cascade `set_null` only re-projects its
@@ -2006,7 +2093,7 @@ export interface CmsReindexPage {
2006
2093
  * but unaccelerated). */
2007
2094
  index_certify?: 'armed' | 'pending' | 'timeout';
2008
2095
  }
2009
- /** The result of a bounded filtered delete (cms.md §20). `matched` counts the
2096
+ /** The result of a bounded filtered delete (guide ch. 4). `matched` counts the
2010
2097
  * rows this page selected (≤ `limit`); `deleted` counts the ones actually
2011
2098
  * removed (a row that vanished between the match and the delete is skipped).
2012
2099
  * Loop while `deleted > 0` — the filter re-evaluates against live rows.
@@ -2026,33 +2113,33 @@ export interface CmsBulkDeleteResult {
2026
2113
  complete: boolean;
2027
2114
  next_cursor: string | null;
2028
2115
  }
2029
- /** A write guard (cms.md §10): "after this write, at most `max` live items
2116
+ /** A write guard (guide ch. 4): "after this write, at most `max` live items
2030
2117
  * match `filter`". Requires `lock` — an unlocked guard is racy by construction. */
2031
2118
  export interface CmsGuard {
2032
2119
  filter: Record<string, unknown>;
2033
2120
  max: number;
2034
2121
  }
2035
- /** One guard of a `guards[]` multi-invariant write (cms.md §10). Same
2122
+ /** One guard of a `guards[]` multi-invariant write (guide ch. 4). Same
2036
2123
  * { filter, max } as CmsGuard plus an optional custom 409 `message` surfaced on
2037
2124
  * the FIRST violation. */
2038
2125
  export interface CmsGuardTerm extends CmsGuard {
2039
2126
  /** Custom guard_failed message (≤200 chars) for THIS invariant. */
2040
2127
  message?: string;
2041
2128
  }
2042
- /** Concurrency options shared by the cms write methods (cms.md §9–10). */
2129
+ /** Concurrency options shared by the cms write methods (guide ch. 4). */
2043
2130
  export interface CmsWriteOpts {
2044
2131
  /** Optimistic CAS: sent as `If-Match: <version>`; mismatch → 409 version_conflict. */
2045
2132
  ifVersion?: number;
2046
2133
  /** Bounded field precondition checked against the locked row (≤4 terms;
2047
2134
  * `{field: null}` = "absent or null" — the slot-claim shape). 409 precondition_failed. */
2048
2135
  if?: Record<string, unknown>;
2049
- /** Per-(tenant,collection,key) advisory lock — serializes same-key writers. */
2136
+ /** A per-(project, collection, key) lock — serializes same-key writers. */
2050
2137
  lock?: string;
2051
2138
  /** Declarative capacity/overlap invariant; requires `lock`. 409 guard_failed.
2052
2139
  * Mutually exclusive with `guards`. */
2053
2140
  guard?: CmsGuard;
2054
2141
  /** Multiple capacity/overlap invariants evaluated co-atomically under the ONE
2055
- * `lock` (≤4; requires `lock`; cms.md §10). Mutually exclusive with `guard`.
2142
+ * `lock` (≤4; requires `lock`; guide ch. 4). Mutually exclusive with `guard`.
2056
2143
  * The FIRST failing guard's optional `message` rides the 409 guard_failed. */
2057
2144
  guards?: CmsGuardTerm[];
2058
2145
  }
@@ -2068,7 +2155,7 @@ export interface CmsWindow {
2068
2155
  since?: string;
2069
2156
  until?: string;
2070
2157
  }
2071
- /** cms-rel B2: the aggregate request body (cms.md §12.1). */
2158
+ /** the aggregate request body (guide ch. 4). */
2072
2159
  export interface CmsAggregateBody {
2073
2160
  /** 1–4 exprs; fn ∈ count|sum|min|max|avg (sum/avg need an n*-slot field). */
2074
2161
  aggregates: Array<{
@@ -2086,7 +2173,7 @@ export interface CmsAggregateBody {
2086
2173
  /** group rows returned; clamped to 500. */
2087
2174
  limit?: number;
2088
2175
  }
2089
- /** cms-rel B3: the rank request body (cms.md §12.2). */
2176
+ /** the rank request body (guide ch. 4). */
2090
2177
  export interface CmsRankBody {
2091
2178
  /** REQUIRED: the ranked entity — a slot-bound own field (often a relation). */
2092
2179
  groupBy: string;
@@ -2103,7 +2190,7 @@ export interface CmsRankBody {
2103
2190
  window?: CmsWindow;
2104
2191
  limit?: number;
2105
2192
  }
2106
- /** cms-rel B4: one transaction step (cms.md §13). `$where` = the bounded CAS
2193
+ /** one transaction step (guide ch. 4). `$where` = the bounded CAS
2107
2194
  * precondition (the PATCH `if` grammar: ≤4 terms, scalar / null /
2108
2195
  * {$eq $ne $gt $gte $lt $lte $in}). */
2109
2196
  export type CmsTxStep = {
@@ -2123,7 +2210,7 @@ export type CmsTxStep = {
2123
2210
  item_id: string;
2124
2211
  $where?: Record<string, unknown>;
2125
2212
  };
2126
- /** One op of `vx.cms.batch` (cms.md §21) — the single route's own body keys,
2213
+ /** One op of `vx.cms.batch` (guide ch. 4) — the single route's own body keys,
2127
2214
  * typed by op. `ref` is an opaque tag echoed on the matching result. */
2128
2215
  export type CmsBatchOp = {
2129
2216
  op: 'get';
@@ -2222,7 +2309,7 @@ export interface CmsBatchResponse<T extends readonly CmsBatchOp[]> {
2222
2309
  };
2223
2310
  }
2224
2311
  /** One CMS item as the API returns it — the envelope `$expand` inlines in place
2225
- * of a stored relation id (cms.md §6.2). `R` is the target collection's Row. */
2312
+ * of a stored relation id (guide ch. 4). `R` is the target collection's Row. */
2226
2313
  export interface CmsItemEnvelope<R> {
2227
2314
  item_id: string;
2228
2315
  collection: string;
@@ -2238,7 +2325,7 @@ export interface CmsFileRef {
2238
2325
  object_id: string;
2239
2326
  $ref: 'files';
2240
2327
  }
2241
- /** Every shape an expanded member can take (cms.md §6.2, all four verified in
2328
+ /** Every shape an expanded member can take (guide ch. 4, all four verified in
2242
2329
  * cms-v1 core.ts): the full envelope; a `{ object_id, $ref: 'files' }` stub for
2243
2330
  * a file field; the BARE id when the expansion hit a cycle or the depth budget;
2244
2331
  * `null` when the target is soft-deleted, not visible to this caller, or owned
@@ -2282,7 +2369,7 @@ export interface CollectionClient<C extends VxilSchemaShape['cms'][string], S ex
2282
2369
  version: number;
2283
2370
  data: C['Row'];
2284
2371
  }>;
2285
- /** `expand` inlines the named relation/file fields (cms.md §6.2) — the names
2372
+ /** `expand` inlines the named relation/file fields (guide ch. 4) — the names
2286
2373
  * come from the generated `Relations`, so a typo is a compile error. Bounds
2287
2374
  * (worker-clamped regardless of config): depth 1 (ceiling 2), ≤5 fields
2288
2375
  * (ceiling 25). Omit it and the result type is exactly today's `Row`. */
@@ -2317,12 +2404,12 @@ export interface CollectionClient<C extends VxilSchemaShape['cms'][string], S ex
2317
2404
  items: C['Row'][];
2318
2405
  next_cursor: string | null;
2319
2406
  }>;
2320
- /** `SELECT count(*)` under the same bounded filter grammar (cms.md §9.4).
2407
+ /** `SELECT count(*)` under the same bounded filter grammar (guide ch. 4).
2321
2408
  * Refused (422) on collections with beforeRead visibility hooks. */
2322
2409
  count(filter?: Partial<C['Filterable']>): Promise<number>;
2323
2410
  patch(itemId: string, data: C['Patch'], opts?: CmsWriteOpts): Promise<C['Row']>;
2324
2411
  /** Atomic in-database increment — ONE conditional UPDATE; never
2325
- * read-modify-write (cms.md §9.3). Delta keys are the numeric Row fields. */
2412
+ * read-modify-write (guide ch. 4). Delta keys are the numeric Row fields. */
2326
2413
  inc(itemId: string, incs: Partial<Record<NumericKeys<C['Row']> & string, number>>, opts?: Pick<CmsWriteOpts, 'ifVersion' | 'if'>): Promise<C['Row']>;
2327
2414
  delete(itemId: string, opts?: Pick<CmsWriteOpts, 'ifVersion'>): Promise<{
2328
2415
  item_id: string;
@@ -2330,7 +2417,7 @@ export interface CollectionClient<C extends VxilSchemaShape['cms'][string], S ex
2330
2417
  cascaded: number;
2331
2418
  set_null: number;
2332
2419
  }>;
2333
- /** cms.md §20: bounded filtered delete over the generated `Filterable` — a
2420
+ /** Bounded filtered delete over the generated `Filterable` — a
2334
2421
  * filter is required, ≤100 rows per call, `dryRun` previews. Loop while
2335
2422
  * `deleted > 0`. */
2336
2423
  deleteMany(q: {
@@ -2340,7 +2427,7 @@ export interface CollectionClient<C extends VxilSchemaShape['cms'][string], S ex
2340
2427
  dryRun?: boolean;
2341
2428
  }): Promise<CmsBulkDeleteResult>;
2342
2429
  publish(itemId: string): Promise<C['Row']>;
2343
- /** cms-rel B2: bounded group-by aggregate (spec §7 `groupBy()` surface).
2430
+ /** Bounded group-by aggregate (guide ch. 4).
2344
2431
  * groupBy/field names are typed over the Row's keys; slot-existence stays a
2345
2432
  * runtime check — exactly like `query`. Joins stay expressed as dotted
2346
2433
  * filter keys (no `.join()` builder — one grammar, not two). */
@@ -2357,7 +2444,7 @@ export interface CollectionClient<C extends VxilSchemaShape['cms'][string], S ex
2357
2444
  }>;
2358
2445
  scanned: number;
2359
2446
  }>;
2360
- /** cms-rel B3: window ranking over the aggregate. */
2447
+ /** Window ranking over the aggregate (guide ch. 4). */
2361
2448
  rank(q: Omit<CmsRankBody, 'groupBy' | 'partitionBy' | 'metric'> & {
2362
2449
  groupBy: keyof C['Row'] & string;
2363
2450
  partitionBy?: keyof C['Row'] & string;
@@ -2413,12 +2500,12 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2413
2500
  * `Vxil.connect<VxilSchema>({ apiKey }).rag` won't type-check if `rag` is off.
2414
2501
  * Runtime is identical to `new Vxil`; this only adds the compile-time gate. */
2415
2502
  static connect<S extends VxilSchemaShape = VxilSchemaShape>(opts: VxilOptions): EnabledVxil<S>;
2416
- /** Typed per-collection CMS handle (design §4.8). A thin wrapper over the
2503
+ /** Typed per-collection CMS handle (guide ch. 5). A thin wrapper over the
2417
2504
  * generic `cms.items.*` methods — the wire calls are identical; the generated
2418
2505
  * `VxilSchema` supplies the field types. `vx.cms.items.*` stays as the
2419
2506
  * always-available un-generic fallback. */
2420
2507
  from<C extends keyof S['cms'] & string>(collection: C): CollectionClient<S['cms'][C], S>;
2421
- /** Typed function invoke (design §4.5). `vx.fn.<name>(payload)` POSTs to
2508
+ /** Typed function invoke (guide ch. 8). `vx.fn.<name>(payload)` POSTs to
2422
2509
  * /v1/fn/<name>; the generated `VxilSchema` types Input/Output (Level-0
2423
2510
  * opaque until a function declares a signature). A Proxy gives the
2424
2511
  * `vx.fn.<name>` accessor shape without enumerating names at runtime.
@@ -2457,7 +2544,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2457
2544
  * (email/display_name/avatar_url/attributes) is scrubbed, while the id is
2458
2545
  * kept so cross-feature references stay intact. NOTE: a full account-delete
2459
2546
  * flow also calls the auth half — POST /v1/auth/users/:id/erase — to erase
2460
- * the credential/session identity (see features/tenant-users.md §3).
2547
+ * the credential/session identity (see guide ch. 6, auth).
2461
2548
  */
2462
2549
  delete: (id: string, opts?: {
2463
2550
  erase?: boolean;
@@ -2494,7 +2581,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2494
2581
  readonly notifications: {
2495
2582
  send: (input: {
2496
2583
  user_id: string;
2497
- /** The four shipped template ids (notifications.md §7). */
2584
+ /** The four shipped template ids (guide ch. 6, notifications). */
2498
2585
  template: "magic-link" | "otp-code" | "welcome" | "transactional";
2499
2586
  data: Record<string, unknown>;
2500
2587
  /** Explicit wins; otherwise the recipient's stored `locale` attribute
@@ -2590,7 +2677,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2590
2677
  user_id?: string;
2591
2678
  status?: string;
2592
2679
  limit?: number;
2593
- /** A7: only deliveries that reached this engagement state */
2680
+ /** only deliveries that reached this engagement state */
2594
2681
  engagement?: "delivered" | "opened" | "clicked";
2595
2682
  }) => Promise<Delivery[]>;
2596
2683
  suppressions: {
@@ -2643,7 +2730,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2643
2730
  * does not cover them, so an "unsubscribe from everything" click can never
2644
2731
  * lock a user out of its own account. Muteable ids: `welcome`,
2645
2732
  * `transactional`. (Password-reset mail rides `transactional`, which stays
2646
- * muteable — see the notifications feature doc §6c.)
2733
+ * muteable — see guide ch. 6, notifications.)
2647
2734
  *
2648
2735
  * SCOPES: with an end-user token both calls are confined to the verified
2649
2736
  * principal and take `notifications:read` (a browser key that can mute its
@@ -2687,7 +2774,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2687
2774
  };
2688
2775
  /** A single delivery by id (the list is `deliveries()`). */
2689
2776
  delivery: (deliveryId: string) => Promise<Delivery>;
2690
- /** Email broadcast campaigns (notifications.md §11b): audience-ref fan-out
2777
+ /** Email broadcast campaigns (guide ch. 6, notifications): audience-ref fan-out
2691
2778
  * with quiet-hours + frequency-cap policy. `schedule_cron` sets a recurring
2692
2779
  * send (status `scheduled`); omit it for a `draft`. */
2693
2780
  campaigns: {
@@ -2754,12 +2841,12 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2754
2841
  /** The tenant's enabled-feature summary (GET /v1/features). Privilege-
2755
2842
  * independent: any valid key may read it — it leaks no secrets, only which
2756
2843
  * features the tenant has turned on. Mirrors what the MCP tool-list
2757
- * aggregation sees. (audit #113) */
2844
+ * aggregation sees. */
2758
2845
  list: () => Promise<string[]>;
2759
2846
  /** The FULL enabled-feature summary: `features` + `api_versions` (released
2760
2847
  * API majors per feature) + the additive `key` block — the CALLING key's
2761
2848
  * identity and per-tool MCP permissions (allowed_tools/denied_tools
2762
- * patterns, api_keys 0057; mcp.md §6.7). `key` is absent for non-key
2849
+ * patterns; guide ch. 10). `key` is absent for non-key
2763
2850
  * callers and for keys without explicit tool perms. `list()` stays the
2764
2851
  * stable flat-array shorthand. */
2765
2852
  summary: () => Promise<{
@@ -2831,7 +2918,14 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2831
2918
  readonly jobs: {
2832
2919
  /** Enqueue a one-off job; Vxil POSTs a signed callback to target_url with
2833
2920
  * retries. deliver_after (ISO) / delay_seconds (≤ 30 d, at most one of the
2834
- * two) defer the first delivery; > 12 h returns state 'delayed'. */
2921
+ * two) defer the first delivery; > 12 h returns state 'delayed'.
2922
+ *
2923
+ * `callback: true` (or `{ ttl_seconds }`, 60 s..31 d; default 24 h) opts
2924
+ * the run in to a KEYLESS signed `callback_url` (in the answer and on every
2925
+ * delivery): an external worker POSTs it to complete / fail the run, report
2926
+ * progress, or wake a `wait`. A handler that answers 202 HANDS the run off
2927
+ * — it waits for that callback (dead-lettered as `CallbackTimeout` when the
2928
+ * lifetime passes). See `postRunCallback`. */
2835
2929
  enqueue: (input: {
2836
2930
  job_name: string;
2837
2931
  target_url: string;
@@ -2840,11 +2934,15 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2840
2934
  max_attempts?: number;
2841
2935
  deliver_after?: string;
2842
2936
  delay_seconds?: number;
2937
+ callback?: boolean | {
2938
+ ttl_seconds?: number;
2939
+ };
2843
2940
  }) => Promise<{
2844
2941
  run_id: string;
2845
2942
  state: string;
2846
2943
  deduplicated?: boolean;
2847
2944
  deliver_after?: string;
2945
+ callback_url?: string;
2848
2946
  }>;
2849
2947
  /** Atomic multi-enqueue (≤100 items; any invalid item rejects the whole
2850
2948
  * batch). Each item = the enqueue input, incl. per-item idempotency_key
@@ -2865,7 +2963,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2865
2963
  }>;
2866
2964
  count: number;
2867
2965
  }>;
2868
- /** Enqueue a long-running EXTERNAL generation run (jobs.md §11): Vxil calls
2966
+ /** Enqueue a long-running EXTERNAL generation run (guide ch. 6, jobs): Vxil calls
2869
2967
  * the provider (BYO key), tracks completion via poll/webhook, mirrors a typed
2870
2968
  * generation_status onto a tenant record, enforces a built-in timeout, and
2871
2969
  * (on failure) fires the payments credit-reversal.
@@ -2874,7 +2972,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2874
2972
  * of the same `idempotency_key` (`deduplicated: true`) carries the run's
2875
2973
  * status NOW (`processing`, `completed` or `failed` too).
2876
2974
  *
2877
- * `reserve_credits` (§11.8) takes a PROVISIONAL held credit debit at enqueue
2975
+ * `reserve_credits` takes a PROVISIONAL held credit debit at enqueue
2878
2976
  * (linked to the run), committed on `completed` and reversed on
2879
2977
  * failed/timeout/DLQ. `amount` is positive-only and CLAMPED to the platform
2880
2978
  * `config.generation.maxReserveCredits` cap; in end-user mode `user_id` is
@@ -2916,11 +3014,15 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2916
3014
  /** dotted path of the value a completed run settles with (mirrored as `result`) */
2917
3015
  result_path?: string;
2918
3016
  };
3017
+ /** `progress_fields`: the progress keys (`progress` / `stage` /
3018
+ * `message`) a webhook-mode `processing` callback also writes onto the
3019
+ * mirrored record — realtime clients of that record see them live */
2919
3020
  status_mirror?: {
2920
3021
  feature: string;
2921
3022
  collection: string;
2922
3023
  record_id: string;
2923
3024
  column?: string;
3025
+ progress_fields?: Array<"progress" | "stage" | "message">;
2924
3026
  };
2925
3027
  timeout?: {
2926
3028
  after_ms: number;
@@ -2988,12 +3090,21 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
2988
3090
  }>;
2989
3091
  /**
2990
3092
  * Suspend the RUNNING run until an event (call from the executing
2991
- * handler, then return 200 — the suspension wins).
3093
+ * handler, then return 200 — the suspension wins). `state: 'resumed'` =
3094
+ * the event already fired (continue; `wakeup` is its payload). A run
3095
+ * enqueued with `callback` also gets its `callback_url`: an external worker
3096
+ * POSTing it wakes this wait with no API key.
2992
3097
  */
2993
3098
  wait: (runId: string, input: {
2994
3099
  event: string;
2995
3100
  timeout_seconds?: number;
2996
- }) => Promise<void>;
3101
+ }) => Promise<{
3102
+ run_id: string;
3103
+ state: "waiting" | "resumed";
3104
+ event: string;
3105
+ wakeup?: unknown;
3106
+ callback_url?: string;
3107
+ }>;
2997
3108
  /** Wake every run waiting on the event. */
2998
3109
  emitEvent: (event: string, payload?: Record<string, unknown>) => Promise<number>;
2999
3110
  /** Secret for verifying X-Vxil-Jobs-Signature on your callback endpoints. */
@@ -3431,9 +3542,9 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3431
3542
  createPolicy: (input: {
3432
3543
  name: string;
3433
3544
  key_template: string;
3434
- /** omitted ⇒ seeded from the tenant's rate-limits config `defaults` (F8-54) */
3545
+ /** omitted ⇒ seeded from the tenant's rate-limits config `defaults` */
3435
3546
  limit?: number;
3436
- /** omitted ⇒ seeded from the tenant's rate-limits config `defaults` (F8-54) */
3547
+ /** omitted ⇒ seeded from the tenant's rate-limits config `defaults` */
3437
3548
  window_seconds?: number;
3438
3549
  behavior?: "block" | "shape";
3439
3550
  }) => Promise<RateLimitPolicy>;
@@ -3507,7 +3618,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3507
3618
  }>;
3508
3619
  /** Per-identifier overrides layered over a policy: `pattern` matches the
3509
3620
  * RENDERED key (exact, or a `*`-glob where the longest literal prefix
3510
- * wins). Propagates to the check path within ≤30s (KV cacheTtl). */
3621
+ * wins). Propagates to the check path within ≤30s (cache TTL). */
3511
3622
  overrides: {
3512
3623
  list: (policyId: string) => Promise<RateLimitOverride[]>;
3513
3624
  create: (policyId: string, input: {
@@ -3539,7 +3650,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3539
3650
  * end-user principal (default-deny) in end-user mode; a no-op in
3540
3651
  * server-caller mode. Omit for shared/reference collections. */
3541
3652
  owner_field?: string;
3542
- /** Public delivery (roadmap §4.4): when true, this collection's PUBLISHED
3653
+ /** Public delivery (guide ch. 4): when true, this collection's PUBLISHED
3543
3654
  * items become KEYLESS-readable through the anonymous public lane —
3544
3655
  * `GET {base}/v1/cms/public/:tenantId/:collection` with NO api key. Drafts
3545
3656
  * and the owner_field are never exposed. Optional; defaults false. Use the
@@ -3557,15 +3668,15 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3557
3668
  };
3558
3669
  index_slot?: "s1" | "s2" | "s3" | "s4" | "n1" | "n2" | "t1" | "t2";
3559
3670
  relation_to?: string;
3560
- /** Value uniqueness across the collection's LIVE items (cms.md §9.3);
3671
+ /** Value uniqueness across the collection's LIVE items (guide ch. 4);
3561
3672
  * scalar-valued types only. Concurrent duplicates → 409 unique_violation. */
3562
3673
  unique?: boolean;
3563
3674
  /** relation fields only: what a delete of the referenced item does to
3564
- * this one — cascade / set_null (bounded fan-out, cms.md §11) or
3565
- * `restrict` (§11.1: the delete is refused with 409 `referenced`
3675
+ * this one — cascade / set_null (bounded fan-out, guide ch. 4) or
3676
+ * `restrict` (the delete is refused with 409 `referenced`
3566
3677
  * while a live reference exists). */
3567
3678
  on_delete?: "cascade" | "set_null" | "restrict";
3568
- /** FIELD-LEVEL read security (cms.md §18): the end-user ORG ROLE slugs
3679
+ /** FIELD-LEVEL read security (guide ch. 4): the end-user ORG ROLE slugs
3569
3680
  * allowed to READ this field. Omitted/`[]` = ungated. A non-empty list
3570
3681
  * is FAIL-SAFE — in verified end-user mode the field is OMITTED from
3571
3682
  * every read (get / list / query / `$expand` / the write-response echo)
@@ -3575,14 +3686,14 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3575
3686
  * session) still sees every field. Writes are unaffected. ≤16 entries,
3576
3687
  * each `^[a-z0-9][a-z0-9_-]{0,31}$` (the `orgs` role alphabet). */
3577
3688
  read_roles?: string[];
3578
- /** Equality index for an UNSLOTTED field (cms.md §3 "Indexed
3689
+ /** Equality index for an UNSLOTTED field (guide ch. 4 "Indexed
3579
3690
  * equality"): `=` / `$eq` / `$in` filters on it are index-served
3580
3691
  * instead of a bounded scan — results are identical either way. ≤4
3581
3692
  * per collection; not with `index_slot` (a slot already indexes
3582
3693
  * equality) and not on a computed field. */
3583
3694
  indexed?: boolean;
3584
3695
  }>;
3585
- /** Per-record action buttons (cms.md §17): `[{ key, label, fn }]` —
3696
+ /** Per-record action buttons (guide ch. 4): `[{ key, label, fn }]` —
3586
3697
  * exactly ONE human-initiated step each; `fn` names a deployed tenant
3587
3698
  * function invoked by `items.runAction`. ≤8 per collection. */
3588
3699
  actions?: CmsActionDef[];
@@ -3600,7 +3711,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3600
3711
  owner_field?: string | null;
3601
3712
  }>>;
3602
3713
  addField: (collection: string, field: Record<string, unknown>) => Promise<void>;
3603
- /** Set (or clear, with `null`/`[]`) a field's READ-ROLE gate (cms.md §18) —
3714
+ /** Set (or clear, with `null`/`[]`) a field's READ-ROLE gate (guide ch. 4) —
3604
3715
  * the same-type in-place alter on the fields route. Re-sends the field's
3605
3716
  * `type` (required by the alter path); every OTHER attribute the field
3606
3717
  * carries is re-sent from `rest`, because the alter overwrites the whole
@@ -3608,7 +3719,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3608
3719
  * read unless the session's verified roles intersect `roles`; server-caller
3609
3720
  * reads and ALL writes are unaffected. */
3610
3721
  setFieldReadRoles: (collection: string, field: string, type: "string" | "text" | "int" | "float" | "bool" | "datetime" | "json" | "relation" | "file", roles: string[] | null, rest?: Record<string, unknown>) => Promise<void>;
3611
- /** Turn a field's EQUALITY INDEX on or off (cms.md §3 "Indexed equality")
3722
+ /** Turn a field's EQUALITY INDEX on or off (guide ch. 4 "Indexed equality")
3612
3723
  * — the same-type in-place alter on the fields route; `indexed` is
3613
3724
  * present-key, so no other attribute moves. Only for UNSLOTTED,
3614
3725
  * non-computed fields, ≤4 per collection (422 `eq_index_budget`).
@@ -3621,16 +3732,16 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3621
3732
  reindex_required: boolean;
3622
3733
  }>;
3623
3734
  /** Set (or clear, with `null`) the collection's end-user owner-scope flag
3624
- * (design §5.1). Names an existing `string` field that holds the owner id. */
3735
+ * (guide ch. 4, "`ownerField`"). Names an existing `string` field that holds the owner id. */
3625
3736
  setOwnerField: (collection: string, ownerField: string | null) => Promise<void>;
3626
- /** Toggle the collection's PUBLIC-delivery flag (roadmap §4.4). When `true`,
3737
+ /** Toggle the collection's PUBLIC-delivery flag (guide ch. 4). When `true`,
3627
3738
  * its PUBLISHED items become KEYLESS-readable via the anonymous public lane
3628
3739
  * (`GET {base}/v1/cms/public/:tenantId/:collection` — no api key); drafts and
3629
3740
  * the owner_field are never exposed. `false` closes the lane (and purges the
3630
3741
  * edge cache). Read the public side with `cmsPublicUrl` / `listCmsPublic`. */
3631
3742
  setPublic: (collection: string, isPublic: boolean) => Promise<void>;
3632
3743
  /** Re-project the collection's index slots after an `index_slot` move
3633
- * (cms.md §19). Slots are projected on WRITE only, so until this runs,
3744
+ * (guide ch. 4). Slots are projected on WRITE only, so until this runs,
3634
3745
  * stored rows keep their OLD projection: the new slot is NULL and the
3635
3746
  * VACATED slot still holds the old field's values — range/sort on the
3636
3747
  * moved field returns the WRONG rows, not merely missing ones. ONE page
@@ -3659,15 +3770,15 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3659
3770
  pages: number;
3660
3771
  index_certify?: CmsReindexPage["index_certify"];
3661
3772
  }>;
3662
- /** Replace the collection's per-record ACTION list (cms.md §17) — the
3773
+ /** Replace the collection's per-record ACTION list (guide ch. 4) — the
3663
3774
  * `{ actions }` fields-route meta-op; `[]` clears. Each action is ONE
3664
3775
  * human-initiated step: the dashboard renders it as a button per record,
3665
3776
  * and `items.runAction` invokes its deployed function. */
3666
3777
  setActions: (collection: string, actions: CmsActionDef[]) => Promise<void>;
3667
3778
  };
3668
3779
  items: {
3669
- /** `lock` serializes same-key writers (per-tenant advisory lock); `guard`
3670
- * is the declarative capacity/overlap invariant (requires lock) — cms.md §10. */
3780
+ /** `lock` serializes same-key writers (a per-key lock); `guard`
3781
+ * is the declarative capacity/overlap invariant (requires lock) — guide ch. 4. */
3671
3782
  create: (collection: string, input: {
3672
3783
  data: Record<string, unknown>;
3673
3784
  status?: "draft" | "published";
@@ -3680,7 +3791,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3680
3791
  version: number;
3681
3792
  data: Record<string, unknown>;
3682
3793
  }>;
3683
- /** `expand` inlines relation/file fields into `data` (cms.md §6.2): the
3794
+ /** `expand` inlines relation/file fields into `data` (guide ch. 4): the
3684
3795
  * full item envelope, a `{ object_id, $ref: 'files' }` stub for a file,
3685
3796
  * the bare id on a cycle/depth cut, `null` for an invisible target. */
3686
3797
  get: (collection: string, itemId: string, opts?: {
@@ -3714,19 +3825,19 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3714
3825
  items: Array<Record<string, unknown>>;
3715
3826
  next_cursor: string | null;
3716
3827
  }>;
3717
- /** Merge-patch data keys; null clears a key. Concurrency opts (cms.md §9):
3828
+ /** Merge-patch data keys; null clears a key. Concurrency opts (guide ch. 4):
3718
3829
  * `ifVersion` → If-Match CAS; `if` → bounded field precondition against
3719
- * the locked row; `lock`/`guard` → the §10 serialization primitives. */
3830
+ * the locked row; `lock`/`guard` → the write-serialization primitives (guide ch. 4). */
3720
3831
  patch: (collection: string, itemId: string, data: Record<string, unknown>, opts?: CmsWriteOpts) => Promise<Record<string, unknown>>;
3721
3832
  /** Atomic in-database increment — PATCH `{ $inc: {field: delta} }`, ONE
3722
3833
  * conditional UPDATE guarded by the field's validation min/max (the quota
3723
3834
  * shape), the optional `if` precondition, and If-Match. 409
3724
- * inc_out_of_bounds when the guard refuses (cms.md §9.3). */
3835
+ * inc_out_of_bounds when the guard refuses (guide ch. 4). */
3725
3836
  inc: (collection: string, itemId: string, incs: Record<string, number>, opts?: Pick<CmsWriteOpts, "ifVersion" | "if">) => Promise<Record<string, unknown>>;
3726
- /** `{ count }` under the same bounded filter grammar (cms.md §9.4). 422
3837
+ /** `{ count }` under the same bounded filter grammar (guide ch. 4). 422
3727
3838
  * count_unavailable_with_read_hooks on beforeRead-hooked collections. */
3728
3839
  count: (collection: string, filter?: Record<string, unknown>) => Promise<number>;
3729
- /** Returns the cascade tally (cms.md §11); `ifVersion` rides If-Match and
3840
+ /** Returns the cascade tally (guide ch. 4); `ifVersion` rides If-Match and
3730
3841
  * a conflict aborts BEFORE any cascade side-effect. */
3731
3842
  delete: (collection: string, itemId: string, opts?: Pick<CmsWriteOpts, "ifVersion">) => Promise<{
3732
3843
  item_id: string;
@@ -3734,7 +3845,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3734
3845
  cascaded: number;
3735
3846
  set_null: number;
3736
3847
  }>;
3737
- /** N-22 (cms.md §20): BOUNDED FILTERED delete — soft-delete up to `limit`
3848
+ /** BOUNDED FILTERED delete — soft-delete up to `limit`
3738
3849
  * items (1–100, default 25) matching `filter`, newest id first. A filter
3739
3850
  * is REQUIRED (an unselected sweep is refused 422). Each matched row runs
3740
3851
  * the SAME single-item delete path (restrict refusal, cascade budget,
@@ -3754,7 +3865,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3754
3865
  dryRun?: boolean;
3755
3866
  }) => Promise<CmsBulkDeleteResult>;
3756
3867
  publish: (collection: string, itemId: string) => Promise<Record<string, unknown>>;
3757
- /** P1-12 (cms.md §11.1): the BOUNDED reverse read — which live items
3868
+ /** The BOUNDED reverse read — which live items
3758
3869
  * reference this one, through which relation field. Owner-scoped in
3759
3870
  * end-user mode like `get`. `count` is the page returned (≤ limit, max
3760
3871
  * 100), never a total; `has_more` says the cap was hit. A DELETE refused
@@ -3763,7 +3874,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3763
3874
  backlinks: (collection: string, itemId: string, opts?: {
3764
3875
  limit?: number;
3765
3876
  }) => Promise<CmsBacklinksPage>;
3766
- /** P1-7 (cms.md §17): run ONE declared per-record action — invokes the
3877
+ /** Run ONE declared per-record action — invokes the
3767
3878
  * action's deployed function with `{ collection, item_id, action, actor,
3768
3879
  * item }` and returns its result. 404 when the key is not declared;
3769
3880
  * 502 `action_failed` (with `upstream.code` = the function's error
@@ -3775,7 +3886,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3775
3886
  fn: string;
3776
3887
  result: unknown;
3777
3888
  }>;
3778
- /** cms-rel B2 (cms.md §12): bounded group-by aggregate. fns count|sum|
3889
+ /** Bounded group-by aggregate. fns count|sum|
3779
3890
  * min|max|avg over index-slot-bound fields; groupBy ≤2 slot-bound
3780
3891
  * fields; filter = the full query DSL incl. ONE-hop dotted join terms
3781
3892
  * ({"channel.visibility":"public"}); scan capped at 50k rows → 422
@@ -3786,7 +3897,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3786
3897
  }>;
3787
3898
  scanned: number;
3788
3899
  }>;
3789
- /** cms-rel B3 (cms.md §12): window ranking over the aggregate — rank ∈
3900
+ /** Window ranking over the aggregate — rank ∈
3790
3901
  * row_number|rank|percent_rank, computed over ≤500 aggregated groups
3791
3902
  * (never raw rows), optional partitionBy. Same scan cap as aggregate. */
3792
3903
  rank: (collection: string, body: CmsRankBody) => Promise<{
@@ -3814,7 +3925,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3814
3925
  done: boolean;
3815
3926
  }>;
3816
3927
  };
3817
- /** cms-rel B4 (cms.md §13): atomic multi-collection transaction — 1–5
3928
+ /** Atomic multi-collection transaction — 1–5
3818
3929
  * steps over ≤3 collections, per-step `$where` CAS preconditions (the
3819
3930
  * PATCH `if` grammar). All-or-nothing: any failed precondition/validation
3820
3931
  * rolls the WHOLE transaction back (409 precondition_failed names the
@@ -3830,7 +3941,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3830
3941
  committed: boolean;
3831
3942
  tx_id: string;
3832
3943
  }>;
3833
- /** P1-1 (cms.md §21): several get / query / create / patch / delete ops in
3944
+ /** Several get / query / create / patch / delete ops in
3834
3945
  * ONE round trip — the function-chain shape ("read 3 rows → patch 2 →
3835
3946
  * create 1" is one call, not six). ≤25 ops, each run through the SAME path
3836
3947
  * its single route uses (scopes, owner-scoping, hooks, guards, `if`,
@@ -3844,7 +3955,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3844
3955
  batch: <T extends readonly CmsBatchOp[]>(ops: readonly [...T], opts?: {
3845
3956
  atomic?: boolean;
3846
3957
  }) => Promise<CmsBatchResponse<T>>;
3847
- /** cms-rel B5 (cms.md §12.4): declared read-models (config `readModels`
3958
+ /** Declared read-models (config `readModels`
3848
3959
  * bag) — list with last-run status, and "run now" materialization into
3849
3960
  * the rollup collection. */
3850
3961
  readModels: {
@@ -3949,7 +4060,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3949
4060
  /** Read the resolved DM config (defaults merged with the stored partial). */
3950
4061
  getConfig: () => Promise<DmConfigState>;
3951
4062
  /** Write the DM master config — a partial merge (omitted leaves keep their
3952
- * current value), version-bumped and republished to the gate's KV key. */
4063
+ * current value), version-bumped and republished to the gate's cache. */
3953
4064
  setConfig: (patch: {
3954
4065
  enabled?: boolean;
3955
4066
  maxParticipants?: number;
@@ -4082,7 +4193,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4082
4193
  /** The MCP aggregation surface (the `mcp` feature). */
4083
4194
  readonly mcp: {
4084
4195
  /** Per-tenant secret for verifying the X-Vxil-Mcp-Signature header on custom
4085
- * MCP tool calls (mcp.md §6.5) — the mirror of jobs.signingSecret(). */
4196
+ * MCP tool calls (guide ch. 10) — the mirror of jobs.signingSecret(). */
4086
4197
  signingSecret: () => Promise<string>;
4087
4198
  };
4088
4199
  /**
@@ -4179,7 +4290,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4179
4290
  ids?: string[];
4180
4291
  before?: string;
4181
4292
  }) => Promise<FeedBadge>;
4182
- /** The badge: { unseen, unread, total } (KV-cached over the authority). */
4293
+ /** The badge: { unseen, unread, total } (cached, recomputed on a miss). */
4183
4294
  unreadCount: (userId: string) => Promise<FeedBadge>;
4184
4295
  };
4185
4296
  /**
@@ -4294,7 +4405,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4294
4405
  ids?: string[];
4295
4406
  before?: string;
4296
4407
  }) => Promise<FeedBadge>;
4297
- /** The badge: { unseen, unread, total } (KV-cached over the authority). */
4408
+ /** The badge: { unseen, unread, total } (cached, recomputed on a miss). */
4298
4409
  unreadCount: (userId: string) => Promise<FeedBadge>;
4299
4410
  };
4300
4411
  /**
@@ -4545,7 +4656,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4545
4656
  pending?: boolean;
4546
4657
  }>>;
4547
4658
  };
4548
- /** Custom tenant roles (permission-sets; migration orgs/0019). A custom role
4659
+ /** Custom tenant roles (permission-sets). A custom role
4549
4660
  * is a named set of permissions assignable like any built-in; the four
4550
4661
  * built-ins reproduce the fixed owner>admin>member>viewer lattice. */
4551
4662
  roles: {
@@ -4579,7 +4690,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4579
4690
  /** Delete a custom role (built-in roles cannot be deleted). */
4580
4691
  delete: (roleKey: string) => Promise<void>;
4581
4692
  };
4582
- /** Per-org/user resource ACL grants (migration orgs/0019): grant a permission
4693
+ /** Per-org/user resource ACL grants: grant a permission
4583
4694
  * on a specific resource string; `check(...,{ resource })` consults them. */
4584
4695
  acl: {
4585
4696
  grant: (orgId: string, input: {
@@ -4708,7 +4819,9 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4708
4819
  }>;
4709
4820
  /** Soft delete; bytes are hard-deleted 30 days later. */
4710
4821
  delete: (objectId: string) => Promise<void>;
4711
- /** Aggregate storage usage vs quotas (the FilesManager Storage panel). */
4822
+ /** Aggregate storage usage vs quotas (the FilesManager Storage panel).
4823
+ * `public_assets` = published copies vs the plan's published-bytes ceiling
4824
+ * (identical bytes count once). */
4712
4825
  usage: () => Promise<{
4713
4826
  usage: {
4714
4827
  object_count: number;
@@ -4720,8 +4833,47 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4720
4833
  maxTotalBytes?: number;
4721
4834
  };
4722
4835
  available: Record<string, number | null>;
4836
+ public_assets?: {
4837
+ enabled: boolean;
4838
+ published_objects: number;
4839
+ published_bytes: number;
4840
+ max_published_bytes: number;
4841
+ bytes_remaining: number;
4842
+ };
4843
+ }>;
4844
+ /** SERVER-ONLY (403 server_only in end-user mode). Publish an available
4845
+ * object to vxil's public asset host: a stable, content-addressed URL
4846
+ * (`https://cdn.vxil.app/<tenant>/<sha256>.<ext>`) served from a global
4847
+ * edge cache with `Cache-Control: public, max-age=31536000, immutable`,
4848
+ * playable video/audio and CORS from `publicAssets.corsOrigins`. Needs
4849
+ * `files.publicAssets.enabled`. Publishable: png/jpeg/webp/avif/gif,
4850
+ * mp4/webm, mp3/m4a/ogg, woff2/woff, json — never HTML or SVG (422
4851
+ * `content_type_not_publishable`). Counts against the plan's
4852
+ * published-bytes ceiling (422 `quota_exceeded`). Idempotent: an already
4853
+ * published object answers its existing URL. Emits
4854
+ * `files.object.published`. */
4855
+ publish: (objectId: string) => Promise<PublishedFile>;
4856
+ /** SERVER-ONLY. Publish up to 100 objects (about 2 GiB of bytes) in one
4857
+ * call; a bad id lands in `errors[]` without failing the rest (ids past
4858
+ * the byte budget as `batch_budget_exceeded` — send them again),
4859
+ * `published[]` keeps your order. */
4860
+ publishMany: (objectIds: string[]) => Promise<{
4861
+ published: PublishedFile[];
4862
+ errors: Array<{
4863
+ object_id: string;
4864
+ code: PublishErrorCode;
4865
+ message: string;
4866
+ }>;
4723
4867
  }>;
4724
- /** OCR / text extraction (files.md §1.1, BYO-key add-on). Small/mock inputs
4868
+ /** SERVER-ONLY. Take an object off the public asset host. Its public copy
4869
+ * is deleted once no other object of yours has the same bytes, and the
4870
+ * edge cache stops serving it within about a minute and a half (a
4871
+ * browser that already downloaded it keeps its copy). Deleting the object
4872
+ * unpublishes it too. 404 when it is not published; 503
4873
+ * `unpublish_failed` when the public copy could not be removed right
4874
+ * then (it stays published — retry). Emits `files.object.unpublished`. */
4875
+ unpublish: (objectId: string) => Promise<void>;
4876
+ /** OCR / text extraction (guide ch. 6, files, BYO-key add-on). Small/mock inputs
4725
4877
  * extract inline (status `available`); large inputs (or `async:true`) return
4726
4878
  * 202 with a `job_id` — poll `getText()`. */
4727
4879
  extractText: (objectId: string, opts?: {
@@ -4875,7 +5027,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4875
5027
  * The AI substrate (the `ai` feature): store prompt TEMPLATES (config-as-code),
4876
5028
  * then generate (sync or streamed) and embed across providers. 'mock' is the
4877
5029
  * deterministic default; the real providers (openai/anthropic/gemini/azure/
4878
- * openrouter) route via BYO keys in tenant_secrets. `images` on the generate
5030
+ * openrouter) route via BYO keys in your project secrets. `images` on the generate
4879
5031
  * inputs takes up to 8 vision refs: a public https:// URL, a
4880
5032
  * data:image/...;base64 URL, or file:<object_id> (a files-feature object) —
4881
5033
  * fetched images are capped at 4 MiB each; `documents` (pdf/text, ≤10 MiB
@@ -5087,7 +5239,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5087
5239
  * outlives the ≤300s realtime token TTL); reconnect with `?since=<seq>`. */
5088
5240
  remintToken: (generationId: string) => Promise<AiStreamToken>;
5089
5241
  /** Resume a streamed generation after a dropped socket: every recorded frame
5090
- * with seq > `since` plus `done` (the §2a replay buffer — plain JSON, not
5242
+ * with seq > `since` plus `done` (the replay buffer — plain JSON, not
5091
5243
  * an SSE stream; the buffer lives 1 h). A settled JOB-lane generation is
5092
5244
  * served from its stored answer instead (30 days). `status` says where the
5093
5245
  * generation is; `expired: true` means it settled but its frames are gone
@@ -5184,7 +5336,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5184
5336
  user_id?: string;
5185
5337
  input?: Record<string, unknown>;
5186
5338
  }) => Promise<RagStreamHandle>;
5187
- /** Retrieval-only grounding preview (rag.md §1c): the exact chunks `answer`
5339
+ /** Retrieval-only grounding preview (guide ch. 6, rag): the exact chunks `answer`
5188
5340
  * would ground on, with rerank + metadata boosts applied — no generation,
5189
5341
  * no token spend. `boosts`/`rerank`/`min_score` override the rag config.
5190
5342
  * `min_score` floors the EFFECTIVE `score`, which is a RANK value (about
@@ -5312,7 +5464,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5312
5464
  * `quota` inlines one quota, `creditType` inlines the same owner-bound
5313
5465
  * balance `getBalance` returns — ONE call for a thin client's paywall.
5314
5466
  * A non-2xx answer means UNKNOWN: render the last cached answer, never
5315
- * free (payments.md §3a).
5467
+ * free (guide ch. 6, payments).
5316
5468
  *
5317
5469
  * OVERLAPPING SUBSCRIPTIONS — what `until` means. The WINNER is the
5318
5470
  * entitled subscription with the highest `tierMap[tier].rank` (default 0);
@@ -5456,7 +5608,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5456
5608
  status?: string;
5457
5609
  }) => Promise<PaymentsSubscription[]>;
5458
5610
  /**
5459
- * Create a hosted-checkout session (payments.md §3). Redirect the buyer to
5611
+ * Create a hosted-checkout session (guide ch. 6, payments). Redirect the buyer to
5460
5612
  * the returned `url`; completion lands server-side via the provider webhook
5461
5613
  * (the matching session flips to completed, the charge/grant is folded).
5462
5614
  * Idempotency-Key REQUIRED — a retry replays the SAME session verbatim.
@@ -5480,7 +5632,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5480
5632
  url: string;
5481
5633
  }>;
5482
5634
  /**
5483
- * Refund a charge at-most-once (payments.md §6a). Omit `amount_cents` to
5635
+ * Refund a charge at-most-once (guide ch. 6, payments). Omit `amount_cents` to
5484
5636
  * refund the full un-refunded remainder. Idempotency-Key REQUIRED — a retry
5485
5637
  * replays the recorded refund (never a second provider refund); a refund can
5486
5638
  * NEVER exceed the charge (422 refund_exceeds_charge).
@@ -5677,7 +5829,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5677
5829
  }) => Promise<{
5678
5830
  refunds: PaymentsRefund[];
5679
5831
  }>;
5680
- /** Provider webhook event log (payments.md §7 "Event log & replay"):
5832
+ /** Provider webhook event log (guide ch. 6, payments "Event log & replay"):
5681
5833
  * operator visibility over every delivery — incl. persisted signature
5682
5834
  * failures — plus an idempotent reprocess verb. Needs payments:read
5683
5835
  * (reprocess: payments:write).