@ai-matrx/alchemy 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.
Files changed (81) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/actions.cjs.map +1 -1
  3. package/dist/actions.d.cts +18 -23
  4. package/dist/actions.d.ts +18 -23
  5. package/dist/actions.js.map +1 -1
  6. package/dist/checks.d.cts +2 -0
  7. package/dist/checks.d.ts +2 -0
  8. package/dist/core.cjs +4 -4
  9. package/dist/core.cjs.map +1 -1
  10. package/dist/core.d.cts +8 -58
  11. package/dist/core.d.ts +8 -58
  12. package/dist/core.js +4 -4
  13. package/dist/core.js.map +1 -1
  14. package/dist/declare/schema.json +3 -0
  15. package/dist/declare.cjs +1 -1
  16. package/dist/declare.cjs.map +1 -1
  17. package/dist/declare.d.cts +26 -1
  18. package/dist/declare.d.ts +26 -1
  19. package/dist/declare.js +1 -1
  20. package/dist/declare.js.map +1 -1
  21. package/dist/index.cjs +4 -4
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +8 -58
  24. package/dist/index.d.ts +8 -58
  25. package/dist/index.js +4 -4
  26. package/dist/index.js.map +1 -1
  27. package/dist/menu.d.cts +16 -21
  28. package/dist/menu.d.ts +16 -21
  29. package/dist/operate-document.cjs +2 -2
  30. package/dist/operate-document.cjs.map +1 -1
  31. package/dist/operate-document.d.cts +4 -42
  32. package/dist/operate-document.d.ts +4 -42
  33. package/dist/operate-document.js +2 -2
  34. package/dist/operate-document.js.map +1 -1
  35. package/dist/operate-rich-html.cjs +1 -1
  36. package/dist/operate-rich-html.cjs.map +1 -1
  37. package/dist/operate-rich-html.d.cts +3 -42
  38. package/dist/operate-rich-html.d.ts +3 -42
  39. package/dist/operate-rich-html.js +1 -1
  40. package/dist/operate-rich-html.js.map +1 -1
  41. package/dist/operate-server.cjs +1 -1
  42. package/dist/operate-server.cjs.map +1 -1
  43. package/dist/operate-server.d.cts +8 -46
  44. package/dist/operate-server.d.ts +8 -46
  45. package/dist/operate-server.js +1 -1
  46. package/dist/operate-server.js.map +1 -1
  47. package/dist/operate-xlsx.cjs +2 -2
  48. package/dist/operate-xlsx.cjs.map +1 -1
  49. package/dist/operate-xlsx.d.cts +4 -42
  50. package/dist/operate-xlsx.d.ts +4 -42
  51. package/dist/operate-xlsx.js +2 -2
  52. package/dist/operate-xlsx.js.map +1 -1
  53. package/dist/operate.cjs +4 -4
  54. package/dist/operate.cjs.map +1 -1
  55. package/dist/operate.d.cts +8 -58
  56. package/dist/operate.d.ts +8 -58
  57. package/dist/operate.js +4 -4
  58. package/dist/operate.js.map +1 -1
  59. package/dist/ports.d.cts +11 -15
  60. package/dist/ports.d.ts +11 -15
  61. package/dist/react-bar.d.cts +2 -0
  62. package/dist/react-bar.d.ts +2 -0
  63. package/dist/react-host.d.cts +16 -21
  64. package/dist/react-host.d.ts +16 -21
  65. package/dist/react-menu.d.cts +2 -0
  66. package/dist/react-menu.d.ts +2 -0
  67. package/dist/react-overflow.d.cts +16 -21
  68. package/dist/react-overflow.d.ts +16 -21
  69. package/dist/react-palette.d.cts +2 -0
  70. package/dist/react-palette.d.ts +2 -0
  71. package/dist/react-selection.d.cts +2 -0
  72. package/dist/react-selection.d.ts +2 -0
  73. package/dist/react-sheet.d.cts +2 -0
  74. package/dist/react-sheet.d.ts +2 -0
  75. package/dist/surface.cjs +1 -1
  76. package/dist/surface.cjs.map +1 -1
  77. package/dist/surface.d.cts +222 -16
  78. package/dist/surface.d.ts +222 -16
  79. package/dist/surface.js +1 -1
  80. package/dist/surface.js.map +1 -1
  81. package/package.json +2 -2
@@ -1,3 +1,5 @@
1
+ import { Json as Json$2 } from '@ai-matrx/kit/transfer-json';
2
+
1
3
  /**
2
4
  * Matrx Alchemy — Declare types (CONTRACT §2.1).
3
5
  *
@@ -5,8 +7,8 @@
5
7
  * no React. Runtime behaviour lives in `MountedSurface` (`/declare/host`) and in
6
8
  * handler registrations, never here. Zero React, zero `@ai-matrx/agents`.
7
9
  */
8
- type Json$2 = null | boolean | number | string | Json$2[] | {
9
- [key: string]: Json$2;
10
+ type Json$1 = null | boolean | number | string | Json$1[] | {
11
+ [key: string]: Json$1;
10
12
  };
11
13
  /** Unchanged from `ui_surface_value_type_chk`. */
12
14
  type ValueType = "string" | "number" | "boolean" | "object" | "array" | "document";
@@ -136,6 +138,8 @@ interface SurfaceDeclaration {
136
138
  configNamespaces?: readonly ConfigNamespaceDeclaration[];
137
139
  evidenceSources?: readonly EvidenceSourceDeclaration[];
138
140
  skipBaselineValues?: boolean;
141
+ /** Opt out of the host's baseline item types (`baselineItemTypes`, e.g. `TABLE_ROW_ITEM_TYPE`). */
142
+ skipBaselineItemTypes?: boolean;
139
143
  }
140
144
  type ValueProvenance = {
141
145
  kind: "own";
@@ -161,6 +165,37 @@ interface ResolvedSurfaceDeclaration extends SurfaceDeclaration {
161
165
  * The qualified key "<itemType>.<name>" names an item value; a bare name is a screen value.
162
166
  */
163
167
  type QualifiedValueKey = string;
168
+ /** Live slot payloads (page-capture's shapes, kept). */
169
+ interface LiveValues {
170
+ selection?: {
171
+ choices: Record<string, Json$1>;
172
+ text: string | null;
173
+ };
174
+ "on-demand"?: readonly OnDemandSection[];
175
+ errors?: readonly string[];
176
+ requests?: readonly RecentRequest[];
177
+ }
178
+ interface OnDemandSection {
179
+ id: string;
180
+ title: string;
181
+ description?: string;
182
+ role: "data" | "request";
183
+ brief?: Json$1;
184
+ load(signal: AbortSignal): Promise<Json$1>;
185
+ }
186
+ interface RecentRequest {
187
+ method: string;
188
+ path: string;
189
+ status: string;
190
+ httpStatus?: number;
191
+ durationMs?: number;
192
+ requestId?: string;
193
+ client?: string;
194
+ requestBody?: Json$1;
195
+ requestBodyNote?: string;
196
+ errorSentence?: string;
197
+ timestamp: number;
198
+ }
164
199
  /** RAW-FREE. What leaves the package about a clicked item. */
165
200
  interface ResolvedItem {
166
201
  itemType: string;
@@ -254,7 +289,7 @@ type ActionResult<T = unknown> = {
254
289
  /** `POST /actions/run` (aidream) — the request. */
255
290
  interface ServerActionRunRequest {
256
291
  name: string;
257
- input: Json$2;
292
+ input: Json$1;
258
293
  by: ActionCaller;
259
294
  surface_name?: string;
260
295
  policy?: ActionPolicy;
@@ -263,8 +298,8 @@ interface ServerActionRunRequest {
263
298
  interface ServerActionRunResponse {
264
299
  status: "applied" | "proposed" | "refused";
265
300
  message: string;
266
- receipts: Json$2[];
267
- proposal?: Json$2;
301
+ receipts: Json$1[];
302
+ proposal?: Json$1;
268
303
  }
269
304
  /** A mandate run request: by alias (an Action's `target`) or by key. */
270
305
  type MandateRunRequest = ({
@@ -274,7 +309,7 @@ type MandateRunRequest = ({
274
309
  key: string;
275
310
  alias?: never;
276
311
  }) & {
277
- variables: Record<string, Json$2>;
312
+ variables: Record<string, Json$1>;
278
313
  userInput?: string;
279
314
  by: ActionCaller;
280
315
  policy: ActionPolicy;
@@ -402,14 +437,6 @@ interface ClickTarget {
402
437
  host?: unknown;
403
438
  }
404
439
 
405
- /**
406
- * Framework-neutral transfer contracts (Alchemy Operate, CONTRACT §2.3). All data crossing this boundary is JSON.
407
- * Moved from `@ai-matrx/kit/content-transfer` in ALC-16; the format-adapter contract lives in `./contract`.
408
- */
409
- type Json$1 = null | boolean | number | string | Json$1[] | {
410
- [key: string]: Json$1;
411
- };
412
-
413
440
  /**
414
441
  * Operate — the format and delivery contract (Matrx Alchemy CONTRACT §2.3, ALC-16).
415
442
  *
@@ -439,7 +466,7 @@ type Receipt = {
439
466
  sentence: string;
440
467
  warning?: string;
441
468
  fix?: string; /** What the handler produced (e.g. the created record). */
442
- result?: Json$1;
469
+ result?: Json$2;
443
470
  } | {
444
471
  status: "queued";
445
472
  to: WriteTargetRef;
@@ -944,6 +971,127 @@ interface ServerPort {
944
971
 
945
972
  type SurfaceActionPorts = Pick<AlchemyHostPorts, "diagnostics" | "serverActions" | "mandates" | "pageActions" | "overlay" | "approvals" | "door">;
946
973
 
974
+ /**
975
+ * LIVE VALUES — what a mounted page holds right now (ALC-18, LIST.md D3).
976
+ *
977
+ * A page publishes ONE live capture while it is mounted: its title and route, what it is OF
978
+ * (`identity`), the exact choices the person made (`selection`), its data sections, the errors on
979
+ * screen and its recent requests. Descendants that hold state the page does not (a grid's rows, a
980
+ * compare view) contribute sections. Every reader — the page's Alchemy menu, the admin debug
981
+ * context, an agent through `SurfacePort.getValue` — reads the SAME capture through this store, at
982
+ * read time, from the live getters. There is no second capture path.
983
+ *
984
+ * The four declared live slots (`LiveSlot`: selection, on-demand, errors, requests) are views of
985
+ * the capture (`liveSlotsOf`), and a surface's named value reads through `liveValueOf`.
986
+ *
987
+ * Framework-neutral: no React, no DOM. A host hook subscribes with `subscribe` + `version`
988
+ * (`useSyncExternalStore`). The most recent publication wins (a dialog over a page, a page over
989
+ * the shell's default).
990
+ */
991
+
992
+ type LiveCaptureKind = "table-page" | "record" | "dialog" | "admin-page";
993
+ /** A chosen thing, by name and id. Either may be null (not chosen / not loaded). */
994
+ interface LiveNamed {
995
+ id: string | null;
996
+ name: string | null;
997
+ }
998
+ type LiveCaptureValue = LiveNamed | string | number | boolean | null;
999
+ interface LiveSection {
1000
+ /** Stable id, unique within one capture. */
1001
+ id: string;
1002
+ /** What the person calls this part of the page. */
1003
+ title: string;
1004
+ description?: string;
1005
+ /** `data` survives "Only the data"; `request` does not. */
1006
+ role: "data" | "request";
1007
+ value: unknown;
1008
+ /** The one-line brief (counts, a sentence). */
1009
+ brief?: unknown;
1010
+ /** A section too big to hold on the page: `value` is the honest stub and `load` reads it on use. */
1011
+ load?: () => Promise<unknown>;
1012
+ }
1013
+ interface LiveRequest {
1014
+ method: string;
1015
+ path: string;
1016
+ status: string;
1017
+ httpStatus?: number;
1018
+ durationMs?: number;
1019
+ requestId?: string;
1020
+ /** Which client door (supabase-rest, supabase-rpc, aidream, next-api …). */
1021
+ client?: string;
1022
+ /** The JSON request body, credentials redacted. */
1023
+ requestBody?: unknown;
1024
+ requestBodyNote?: string;
1025
+ /** A failed request's own sentence from the server, verbatim. */
1026
+ errorSentence?: string;
1027
+ timestamp: number;
1028
+ }
1029
+ interface LiveCapture {
1030
+ /** The declared surface these are live values of. Absent/null = the page declares no surface yet. */
1031
+ surfaceName?: string | null;
1032
+ kind: LiveCaptureKind;
1033
+ title: string;
1034
+ route: string;
1035
+ url?: string;
1036
+ /** What this page is OF (table, record, dialog subject …), names and ids. */
1037
+ identity: Record<string, LiveCaptureValue>;
1038
+ /** The exact choices the person made on the page, in order. */
1039
+ selection: Record<string, LiveCaptureValue>;
1040
+ sections: LiveSection[];
1041
+ /** The error sentences on screen, verbatim. */
1042
+ errors: string[];
1043
+ requests: LiveRequest[];
1044
+ }
1045
+ interface LiveContribution {
1046
+ owner: string;
1047
+ sections: LiveSection[];
1048
+ /** Names a descendant knows and the page does not. */
1049
+ identity?: Record<string, LiveCaptureValue>;
1050
+ }
1051
+ /** What a reader shows before anyone uses the capture: no section value is walked. */
1052
+ interface LiveOutline {
1053
+ surfaceName: string | null;
1054
+ kind: LiveCaptureKind;
1055
+ title: string;
1056
+ loadable: Array<Pick<LiveSection, "id" | "title">>;
1057
+ }
1058
+ /**
1059
+ * The page's capture plus its descendants' contributions. A descendant fills a name the page left
1060
+ * empty and never overrides one; a section id claimed twice throws, naming both owners.
1061
+ */
1062
+ declare function mergeLiveCapture(base: LiveCapture, contributions: readonly LiveContribution[]): LiveCapture;
1063
+ /** The four declared live slots (`LiveSlot`) as views of one capture. */
1064
+ declare function liveSlotsOf(capture: LiveCapture): LiveValues;
1065
+ /**
1066
+ * One named live value of a capture, or `undefined` when the capture holds none by that name.
1067
+ * Slot names (`selection`, `errors`, `requests`, `on-demand`) read the slot; `title`, `route`,
1068
+ * `url`, `kind` and `identity` read the page; any other name reads an identity or selection entry,
1069
+ * then a held section's value (a section that must be loaded answers its stub).
1070
+ */
1071
+ declare function liveValueOf(capture: LiveCapture, name: string): unknown;
1072
+ interface LiveValuesStore {
1073
+ /** A page's live capture, read at read time. Returns its unpublish. The most recent wins. */
1074
+ publish(read: () => LiveCapture): () => void;
1075
+ /** A descendant's sections (and names). Returns its removal. */
1076
+ contribute(owner: string, read: () => LiveSection[] | Omit<LiveContribution, "owner">): () => void;
1077
+ /** Say a getter's answer changed (readers re-render). */
1078
+ touch(): void;
1079
+ /** Whether any page is publishing right now. */
1080
+ has(): boolean;
1081
+ /** The live capture: the latest publication merged with every contribution. */
1082
+ read(): LiveCapture | null;
1083
+ /** The outline without building section values (safe in render). */
1084
+ outline(): LiveOutline | null;
1085
+ /** The live capture of ONE surface, when the publishing page is that surface. */
1086
+ readFor(surfaceName: string): LiveCapture | null;
1087
+ subscribe(listener: () => void): () => void;
1088
+ /** Bumps on every publish / contribute / touch. */
1089
+ version(): number;
1090
+ }
1091
+ declare function createLiveValues(): LiveValuesStore;
1092
+ /** THE live-values store of this JS realm: every host page publishes here, every reader reads here. */
1093
+ declare const liveValues: LiveValuesStore;
1094
+
947
1095
  /**
948
1096
  * `createSurfacePort` — the one SurfacePort runtime (Applets CONTRACTS §6 + Amendment 2.1).
949
1097
  *
@@ -1000,6 +1148,12 @@ interface CreateSurfacePortOptions {
1000
1148
  * `action_unhandled`, so a page Action can never wait for an answer that cannot come.
1001
1149
  */
1002
1150
  emit(stream: string, payload: unknown): boolean;
1151
+ /**
1152
+ * The page's live values (ALC-18): `getValue(name)` on a value nobody set reads the mounted
1153
+ * surface's live capture (`liveValueOf`) — only while a page publishing THAT surface is mounted.
1154
+ * Usually `liveValues` from `@ai-matrx/alchemy/surface`.
1155
+ */
1156
+ live?: LiveValuesStore;
1003
1157
  /** Values seeded at mount; a value already set is never overwritten. */
1004
1158
  seedValues?: () => Promise<Record<string, unknown>>;
1005
1159
  /** The surface to read when nothing is mounted yet (e.g. the Applet's own `applets/<id>`). */
@@ -1063,4 +1217,56 @@ interface SurfaceClient {
1063
1217
  };
1064
1218
  }
1065
1219
 
1066
- export { APPLET_SURFACE_PREFIX, type ActionCaller, type ActionContext, type ActionInfo, type ActionResult, type CreateSurfacePortOptions, type MandateRunRef, PAGE_ACTION_STREAM, type PageActionEvent, type PendingPageActions, type ReadSurfaceChainOptions, type SurfaceClient, type SurfacePort, type SurfacePortHandle, type SurfacePortRunPorts, type SurfaceReadAnswer, type SurfaceReadChain, createSurfacePort, readSurfaceChain, surfaceActionVisible, valueStream };
1220
+ /**
1221
+ * `@ai-matrx/alchemy/declare/host` — HOST-BINDING types only (CONTRACT §2.1, §2.6).
1222
+ * Never imported by providers (`/declare`, `/actions`, `/menu`, `/operate` see only
1223
+ * the raw-free `ResolvedItem`). Types only: no runtime code.
1224
+ */
1225
+
1226
+ /** Raw item reads: consumed only by projection and the write handler that owns the target. */
1227
+ interface InternalResolvedItem extends ResolvedItem {
1228
+ readValues(signal: AbortSignal): Promise<Record<string, unknown>>;
1229
+ }
1230
+
1231
+ /**
1232
+ * ITEM SOURCES — the one path from "the person pointed at this" to a declared item (ALC-18, D4).
1233
+ *
1234
+ * A mounted container (a canonical table, a message list) registers ONE source under its own id.
1235
+ * When a menu opens on an anchor inside it, the host asks `itemSources.resolve(containerId, target)`
1236
+ * and gets back the declared item — `itemType`, `identity`, `level`, `readOnly`, `readValues` — plus
1237
+ * the opaque `host` data the container's owner attached (the menu rows it builds for that item). The
1238
+ * package never reads `host`; it never crosses into a model.
1239
+ *
1240
+ * A container that answers an item type no surface declares is a defect the host's guard names;
1241
+ * the canonical table answers `TABLE_ROW_ITEM_TYPE` (`@ai-matrx/alchemy/declare`), which every
1242
+ * surface carries as a baseline.
1243
+ */
1244
+
1245
+ /** What was pointed at inside a container, in the container's own words. */
1246
+ interface ItemTarget {
1247
+ containerId: string;
1248
+ /** The level aimed at (a table: selection | cell | column | row | table). */
1249
+ level: string;
1250
+ /** The item's id within the container (a table's row id). */
1251
+ itemId?: string;
1252
+ /** A sub-part of the item (a table's column id). */
1253
+ partId?: string;
1254
+ }
1255
+ /** A resolved item, plus the container owner's opaque data for it. */
1256
+ interface ItemHit<H = unknown> {
1257
+ item: InternalResolvedItem;
1258
+ host?: H;
1259
+ }
1260
+ type ItemSource<H = unknown> = (target: ItemTarget) => ItemHit<H> | null;
1261
+ interface ItemSourceRegistry {
1262
+ /** One source per mounted container. A re-register replaces; the returned removal removes only its own. */
1263
+ register<H>(containerId: string, source: ItemSource<H>): () => void;
1264
+ /** The item at the target, or null when no container answers it. A throwing source answers null. */
1265
+ resolve<H = unknown>(target: ItemTarget): ItemHit<H> | null;
1266
+ has(containerId: string): boolean;
1267
+ }
1268
+ declare function createItemSources(onError?: (error: unknown, target: ItemTarget) => void): ItemSourceRegistry;
1269
+ /** THE item-source registry of this JS realm. */
1270
+ declare const itemSources: ItemSourceRegistry;
1271
+
1272
+ export { APPLET_SURFACE_PREFIX, type ActionCaller, type ActionContext, type ActionInfo, type ActionResult, type CreateSurfacePortOptions, type ItemHit, type ItemSource, type ItemSourceRegistry, type ItemTarget, type LiveCapture, type LiveCaptureKind, type LiveCaptureValue, type LiveContribution, type LiveNamed, type LiveOutline, type LiveRequest, type LiveSection, type LiveValuesStore, type MandateRunRef, PAGE_ACTION_STREAM, type PageActionEvent, type PendingPageActions, type ReadSurfaceChainOptions, type SurfaceClient, type SurfacePort, type SurfacePortHandle, type SurfacePortRunPorts, type SurfaceReadAnswer, type SurfaceReadChain, createItemSources, createLiveValues, createSurfacePort, itemSources, liveSlotsOf, liveValueOf, liveValues, mergeLiveCapture, readSurfaceChain, surfaceActionVisible, valueStream };
package/dist/surface.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Json as Json$2 } from '@ai-matrx/kit/transfer-json';
2
+
1
3
  /**
2
4
  * Matrx Alchemy — Declare types (CONTRACT §2.1).
3
5
  *
@@ -5,8 +7,8 @@
5
7
  * no React. Runtime behaviour lives in `MountedSurface` (`/declare/host`) and in
6
8
  * handler registrations, never here. Zero React, zero `@ai-matrx/agents`.
7
9
  */
8
- type Json$2 = null | boolean | number | string | Json$2[] | {
9
- [key: string]: Json$2;
10
+ type Json$1 = null | boolean | number | string | Json$1[] | {
11
+ [key: string]: Json$1;
10
12
  };
11
13
  /** Unchanged from `ui_surface_value_type_chk`. */
12
14
  type ValueType = "string" | "number" | "boolean" | "object" | "array" | "document";
@@ -136,6 +138,8 @@ interface SurfaceDeclaration {
136
138
  configNamespaces?: readonly ConfigNamespaceDeclaration[];
137
139
  evidenceSources?: readonly EvidenceSourceDeclaration[];
138
140
  skipBaselineValues?: boolean;
141
+ /** Opt out of the host's baseline item types (`baselineItemTypes`, e.g. `TABLE_ROW_ITEM_TYPE`). */
142
+ skipBaselineItemTypes?: boolean;
139
143
  }
140
144
  type ValueProvenance = {
141
145
  kind: "own";
@@ -161,6 +165,37 @@ interface ResolvedSurfaceDeclaration extends SurfaceDeclaration {
161
165
  * The qualified key "<itemType>.<name>" names an item value; a bare name is a screen value.
162
166
  */
163
167
  type QualifiedValueKey = string;
168
+ /** Live slot payloads (page-capture's shapes, kept). */
169
+ interface LiveValues {
170
+ selection?: {
171
+ choices: Record<string, Json$1>;
172
+ text: string | null;
173
+ };
174
+ "on-demand"?: readonly OnDemandSection[];
175
+ errors?: readonly string[];
176
+ requests?: readonly RecentRequest[];
177
+ }
178
+ interface OnDemandSection {
179
+ id: string;
180
+ title: string;
181
+ description?: string;
182
+ role: "data" | "request";
183
+ brief?: Json$1;
184
+ load(signal: AbortSignal): Promise<Json$1>;
185
+ }
186
+ interface RecentRequest {
187
+ method: string;
188
+ path: string;
189
+ status: string;
190
+ httpStatus?: number;
191
+ durationMs?: number;
192
+ requestId?: string;
193
+ client?: string;
194
+ requestBody?: Json$1;
195
+ requestBodyNote?: string;
196
+ errorSentence?: string;
197
+ timestamp: number;
198
+ }
164
199
  /** RAW-FREE. What leaves the package about a clicked item. */
165
200
  interface ResolvedItem {
166
201
  itemType: string;
@@ -254,7 +289,7 @@ type ActionResult<T = unknown> = {
254
289
  /** `POST /actions/run` (aidream) — the request. */
255
290
  interface ServerActionRunRequest {
256
291
  name: string;
257
- input: Json$2;
292
+ input: Json$1;
258
293
  by: ActionCaller;
259
294
  surface_name?: string;
260
295
  policy?: ActionPolicy;
@@ -263,8 +298,8 @@ interface ServerActionRunRequest {
263
298
  interface ServerActionRunResponse {
264
299
  status: "applied" | "proposed" | "refused";
265
300
  message: string;
266
- receipts: Json$2[];
267
- proposal?: Json$2;
301
+ receipts: Json$1[];
302
+ proposal?: Json$1;
268
303
  }
269
304
  /** A mandate run request: by alias (an Action's `target`) or by key. */
270
305
  type MandateRunRequest = ({
@@ -274,7 +309,7 @@ type MandateRunRequest = ({
274
309
  key: string;
275
310
  alias?: never;
276
311
  }) & {
277
- variables: Record<string, Json$2>;
312
+ variables: Record<string, Json$1>;
278
313
  userInput?: string;
279
314
  by: ActionCaller;
280
315
  policy: ActionPolicy;
@@ -402,14 +437,6 @@ interface ClickTarget {
402
437
  host?: unknown;
403
438
  }
404
439
 
405
- /**
406
- * Framework-neutral transfer contracts (Alchemy Operate, CONTRACT §2.3). All data crossing this boundary is JSON.
407
- * Moved from `@ai-matrx/kit/content-transfer` in ALC-16; the format-adapter contract lives in `./contract`.
408
- */
409
- type Json$1 = null | boolean | number | string | Json$1[] | {
410
- [key: string]: Json$1;
411
- };
412
-
413
440
  /**
414
441
  * Operate — the format and delivery contract (Matrx Alchemy CONTRACT §2.3, ALC-16).
415
442
  *
@@ -439,7 +466,7 @@ type Receipt = {
439
466
  sentence: string;
440
467
  warning?: string;
441
468
  fix?: string; /** What the handler produced (e.g. the created record). */
442
- result?: Json$1;
469
+ result?: Json$2;
443
470
  } | {
444
471
  status: "queued";
445
472
  to: WriteTargetRef;
@@ -944,6 +971,127 @@ interface ServerPort {
944
971
 
945
972
  type SurfaceActionPorts = Pick<AlchemyHostPorts, "diagnostics" | "serverActions" | "mandates" | "pageActions" | "overlay" | "approvals" | "door">;
946
973
 
974
+ /**
975
+ * LIVE VALUES — what a mounted page holds right now (ALC-18, LIST.md D3).
976
+ *
977
+ * A page publishes ONE live capture while it is mounted: its title and route, what it is OF
978
+ * (`identity`), the exact choices the person made (`selection`), its data sections, the errors on
979
+ * screen and its recent requests. Descendants that hold state the page does not (a grid's rows, a
980
+ * compare view) contribute sections. Every reader — the page's Alchemy menu, the admin debug
981
+ * context, an agent through `SurfacePort.getValue` — reads the SAME capture through this store, at
982
+ * read time, from the live getters. There is no second capture path.
983
+ *
984
+ * The four declared live slots (`LiveSlot`: selection, on-demand, errors, requests) are views of
985
+ * the capture (`liveSlotsOf`), and a surface's named value reads through `liveValueOf`.
986
+ *
987
+ * Framework-neutral: no React, no DOM. A host hook subscribes with `subscribe` + `version`
988
+ * (`useSyncExternalStore`). The most recent publication wins (a dialog over a page, a page over
989
+ * the shell's default).
990
+ */
991
+
992
+ type LiveCaptureKind = "table-page" | "record" | "dialog" | "admin-page";
993
+ /** A chosen thing, by name and id. Either may be null (not chosen / not loaded). */
994
+ interface LiveNamed {
995
+ id: string | null;
996
+ name: string | null;
997
+ }
998
+ type LiveCaptureValue = LiveNamed | string | number | boolean | null;
999
+ interface LiveSection {
1000
+ /** Stable id, unique within one capture. */
1001
+ id: string;
1002
+ /** What the person calls this part of the page. */
1003
+ title: string;
1004
+ description?: string;
1005
+ /** `data` survives "Only the data"; `request` does not. */
1006
+ role: "data" | "request";
1007
+ value: unknown;
1008
+ /** The one-line brief (counts, a sentence). */
1009
+ brief?: unknown;
1010
+ /** A section too big to hold on the page: `value` is the honest stub and `load` reads it on use. */
1011
+ load?: () => Promise<unknown>;
1012
+ }
1013
+ interface LiveRequest {
1014
+ method: string;
1015
+ path: string;
1016
+ status: string;
1017
+ httpStatus?: number;
1018
+ durationMs?: number;
1019
+ requestId?: string;
1020
+ /** Which client door (supabase-rest, supabase-rpc, aidream, next-api …). */
1021
+ client?: string;
1022
+ /** The JSON request body, credentials redacted. */
1023
+ requestBody?: unknown;
1024
+ requestBodyNote?: string;
1025
+ /** A failed request's own sentence from the server, verbatim. */
1026
+ errorSentence?: string;
1027
+ timestamp: number;
1028
+ }
1029
+ interface LiveCapture {
1030
+ /** The declared surface these are live values of. Absent/null = the page declares no surface yet. */
1031
+ surfaceName?: string | null;
1032
+ kind: LiveCaptureKind;
1033
+ title: string;
1034
+ route: string;
1035
+ url?: string;
1036
+ /** What this page is OF (table, record, dialog subject …), names and ids. */
1037
+ identity: Record<string, LiveCaptureValue>;
1038
+ /** The exact choices the person made on the page, in order. */
1039
+ selection: Record<string, LiveCaptureValue>;
1040
+ sections: LiveSection[];
1041
+ /** The error sentences on screen, verbatim. */
1042
+ errors: string[];
1043
+ requests: LiveRequest[];
1044
+ }
1045
+ interface LiveContribution {
1046
+ owner: string;
1047
+ sections: LiveSection[];
1048
+ /** Names a descendant knows and the page does not. */
1049
+ identity?: Record<string, LiveCaptureValue>;
1050
+ }
1051
+ /** What a reader shows before anyone uses the capture: no section value is walked. */
1052
+ interface LiveOutline {
1053
+ surfaceName: string | null;
1054
+ kind: LiveCaptureKind;
1055
+ title: string;
1056
+ loadable: Array<Pick<LiveSection, "id" | "title">>;
1057
+ }
1058
+ /**
1059
+ * The page's capture plus its descendants' contributions. A descendant fills a name the page left
1060
+ * empty and never overrides one; a section id claimed twice throws, naming both owners.
1061
+ */
1062
+ declare function mergeLiveCapture(base: LiveCapture, contributions: readonly LiveContribution[]): LiveCapture;
1063
+ /** The four declared live slots (`LiveSlot`) as views of one capture. */
1064
+ declare function liveSlotsOf(capture: LiveCapture): LiveValues;
1065
+ /**
1066
+ * One named live value of a capture, or `undefined` when the capture holds none by that name.
1067
+ * Slot names (`selection`, `errors`, `requests`, `on-demand`) read the slot; `title`, `route`,
1068
+ * `url`, `kind` and `identity` read the page; any other name reads an identity or selection entry,
1069
+ * then a held section's value (a section that must be loaded answers its stub).
1070
+ */
1071
+ declare function liveValueOf(capture: LiveCapture, name: string): unknown;
1072
+ interface LiveValuesStore {
1073
+ /** A page's live capture, read at read time. Returns its unpublish. The most recent wins. */
1074
+ publish(read: () => LiveCapture): () => void;
1075
+ /** A descendant's sections (and names). Returns its removal. */
1076
+ contribute(owner: string, read: () => LiveSection[] | Omit<LiveContribution, "owner">): () => void;
1077
+ /** Say a getter's answer changed (readers re-render). */
1078
+ touch(): void;
1079
+ /** Whether any page is publishing right now. */
1080
+ has(): boolean;
1081
+ /** The live capture: the latest publication merged with every contribution. */
1082
+ read(): LiveCapture | null;
1083
+ /** The outline without building section values (safe in render). */
1084
+ outline(): LiveOutline | null;
1085
+ /** The live capture of ONE surface, when the publishing page is that surface. */
1086
+ readFor(surfaceName: string): LiveCapture | null;
1087
+ subscribe(listener: () => void): () => void;
1088
+ /** Bumps on every publish / contribute / touch. */
1089
+ version(): number;
1090
+ }
1091
+ declare function createLiveValues(): LiveValuesStore;
1092
+ /** THE live-values store of this JS realm: every host page publishes here, every reader reads here. */
1093
+ declare const liveValues: LiveValuesStore;
1094
+
947
1095
  /**
948
1096
  * `createSurfacePort` — the one SurfacePort runtime (Applets CONTRACTS §6 + Amendment 2.1).
949
1097
  *
@@ -1000,6 +1148,12 @@ interface CreateSurfacePortOptions {
1000
1148
  * `action_unhandled`, so a page Action can never wait for an answer that cannot come.
1001
1149
  */
1002
1150
  emit(stream: string, payload: unknown): boolean;
1151
+ /**
1152
+ * The page's live values (ALC-18): `getValue(name)` on a value nobody set reads the mounted
1153
+ * surface's live capture (`liveValueOf`) — only while a page publishing THAT surface is mounted.
1154
+ * Usually `liveValues` from `@ai-matrx/alchemy/surface`.
1155
+ */
1156
+ live?: LiveValuesStore;
1003
1157
  /** Values seeded at mount; a value already set is never overwritten. */
1004
1158
  seedValues?: () => Promise<Record<string, unknown>>;
1005
1159
  /** The surface to read when nothing is mounted yet (e.g. the Applet's own `applets/<id>`). */
@@ -1063,4 +1217,56 @@ interface SurfaceClient {
1063
1217
  };
1064
1218
  }
1065
1219
 
1066
- export { APPLET_SURFACE_PREFIX, type ActionCaller, type ActionContext, type ActionInfo, type ActionResult, type CreateSurfacePortOptions, type MandateRunRef, PAGE_ACTION_STREAM, type PageActionEvent, type PendingPageActions, type ReadSurfaceChainOptions, type SurfaceClient, type SurfacePort, type SurfacePortHandle, type SurfacePortRunPorts, type SurfaceReadAnswer, type SurfaceReadChain, createSurfacePort, readSurfaceChain, surfaceActionVisible, valueStream };
1220
+ /**
1221
+ * `@ai-matrx/alchemy/declare/host` — HOST-BINDING types only (CONTRACT §2.1, §2.6).
1222
+ * Never imported by providers (`/declare`, `/actions`, `/menu`, `/operate` see only
1223
+ * the raw-free `ResolvedItem`). Types only: no runtime code.
1224
+ */
1225
+
1226
+ /** Raw item reads: consumed only by projection and the write handler that owns the target. */
1227
+ interface InternalResolvedItem extends ResolvedItem {
1228
+ readValues(signal: AbortSignal): Promise<Record<string, unknown>>;
1229
+ }
1230
+
1231
+ /**
1232
+ * ITEM SOURCES — the one path from "the person pointed at this" to a declared item (ALC-18, D4).
1233
+ *
1234
+ * A mounted container (a canonical table, a message list) registers ONE source under its own id.
1235
+ * When a menu opens on an anchor inside it, the host asks `itemSources.resolve(containerId, target)`
1236
+ * and gets back the declared item — `itemType`, `identity`, `level`, `readOnly`, `readValues` — plus
1237
+ * the opaque `host` data the container's owner attached (the menu rows it builds for that item). The
1238
+ * package never reads `host`; it never crosses into a model.
1239
+ *
1240
+ * A container that answers an item type no surface declares is a defect the host's guard names;
1241
+ * the canonical table answers `TABLE_ROW_ITEM_TYPE` (`@ai-matrx/alchemy/declare`), which every
1242
+ * surface carries as a baseline.
1243
+ */
1244
+
1245
+ /** What was pointed at inside a container, in the container's own words. */
1246
+ interface ItemTarget {
1247
+ containerId: string;
1248
+ /** The level aimed at (a table: selection | cell | column | row | table). */
1249
+ level: string;
1250
+ /** The item's id within the container (a table's row id). */
1251
+ itemId?: string;
1252
+ /** A sub-part of the item (a table's column id). */
1253
+ partId?: string;
1254
+ }
1255
+ /** A resolved item, plus the container owner's opaque data for it. */
1256
+ interface ItemHit<H = unknown> {
1257
+ item: InternalResolvedItem;
1258
+ host?: H;
1259
+ }
1260
+ type ItemSource<H = unknown> = (target: ItemTarget) => ItemHit<H> | null;
1261
+ interface ItemSourceRegistry {
1262
+ /** One source per mounted container. A re-register replaces; the returned removal removes only its own. */
1263
+ register<H>(containerId: string, source: ItemSource<H>): () => void;
1264
+ /** The item at the target, or null when no container answers it. A throwing source answers null. */
1265
+ resolve<H = unknown>(target: ItemTarget): ItemHit<H> | null;
1266
+ has(containerId: string): boolean;
1267
+ }
1268
+ declare function createItemSources(onError?: (error: unknown, target: ItemTarget) => void): ItemSourceRegistry;
1269
+ /** THE item-source registry of this JS realm. */
1270
+ declare const itemSources: ItemSourceRegistry;
1271
+
1272
+ export { APPLET_SURFACE_PREFIX, type ActionCaller, type ActionContext, type ActionInfo, type ActionResult, type CreateSurfacePortOptions, type ItemHit, type ItemSource, type ItemSourceRegistry, type ItemTarget, type LiveCapture, type LiveCaptureKind, type LiveCaptureValue, type LiveContribution, type LiveNamed, type LiveOutline, type LiveRequest, type LiveSection, type LiveValuesStore, type MandateRunRef, PAGE_ACTION_STREAM, type PageActionEvent, type PendingPageActions, type ReadSurfaceChainOptions, type SurfaceClient, type SurfacePort, type SurfacePortHandle, type SurfacePortRunPorts, type SurfaceReadAnswer, type SurfaceReadChain, createItemSources, createLiveValues, createSurfacePort, itemSources, liveSlotsOf, liveValueOf, liveValues, mergeLiveCapture, readSurfaceChain, surfaceActionVisible, valueStream };