@ai-matrx/alchemy 0.5.1 → 0.6.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.
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Matrx Alchemy — Declare types (CONTRACT §2.1).
3
+ *
4
+ * A declaration is plain JSON data (chair ruling N2): no functions, no classes,
5
+ * no React. Runtime behaviour lives in `MountedSurface` (`/declare/host`) and in
6
+ * handler registrations, never here. Zero React, zero `@ai-matrx/agents`.
7
+ */
8
+ type Json = null | boolean | number | string | Json[] | {
9
+ [key: string]: Json;
10
+ };
11
+ /** Unchanged from `ui_surface_value_type_chk`. */
12
+ type ValueType = "string" | "number" | "boolean" | "object" | "array" | "document";
13
+ type Classification = "ordinary" | "secret" | "credential";
14
+ /** Persisted (CONTRACT §2.7). Projection enforces it before any value leaves. */
15
+ interface Sensitivity {
16
+ /** false = never leaves through Operate. Default true. */
17
+ exportable: boolean;
18
+ /** secret/credential are always excluded; no caller can relax this. Default "ordinary". */
19
+ classification: Classification;
20
+ /** Pre-checked in the preparation workspace. Default true. */
21
+ includedByDefault: boolean;
22
+ }
23
+ interface ValueGroup {
24
+ key: string;
25
+ label: string;
26
+ sortOrder: number;
27
+ description?: string;
28
+ }
29
+ /** The four runtime slots a capture fills (absorbs page-capture). */
30
+ type LiveSlot = "selection" | "on-demand" | "errors" | "requests";
31
+ interface DeclaredValue {
32
+ name: string;
33
+ label: string;
34
+ description: string;
35
+ valueType: ValueType;
36
+ /** Registered content-ir kind key (DB: kind_key). */
37
+ valueKind?: string;
38
+ alwaysAvailable: boolean;
39
+ typicalCharCount: number;
40
+ autoContext?: boolean;
41
+ group?: string;
42
+ sortOrder?: number;
43
+ sensitivity?: Partial<Sensitivity>;
44
+ /** Filled at capture time from a live slot instead of the scope. */
45
+ liveSlot?: LiveSlot;
46
+ /** "request" values drop out of "Only the data". Default "data". */
47
+ role?: "data" | "request";
48
+ }
49
+ /** Where a write lands. "stream" = applied live, op by op, into an editable text. */
50
+ type WriteMode = "draft" | "entity" | "ui" | "stream";
51
+ /** Who may apply WITHOUT a click. "queued" = filed for an organization's review. */
52
+ type ApplyPolicy = "manual" | "ask" | "auto" | "queued";
53
+ /** The WidgetHandle text op set, unchanged in meaning. */
54
+ type StreamOp = "replace" | "insert_before" | "insert_after" | "prepend" | "append" | "patch";
55
+ interface WriteTarget {
56
+ name: string;
57
+ label: string;
58
+ description: string;
59
+ valueType: ValueType;
60
+ valueKind?: string;
61
+ /** Read twin (evidence loop). Required when patchable or mode === "stream". */
62
+ updatesValue?: string;
63
+ patchable?: boolean;
64
+ approvalComparison?: "text-replacement";
65
+ mode: WriteMode;
66
+ /** Required iff mode === "stream". */
67
+ streamOps?: readonly StreamOp[];
68
+ /** Default "manual". Binding overrides may only tighten. */
69
+ applyPolicy?: ApplyPolicy;
70
+ destination?: boolean;
71
+ /** Present when the target writes into an item rather than the screen. */
72
+ itemType?: string;
73
+ group?: string;
74
+ sortOrder?: number;
75
+ }
76
+ /** One kind of thing inside a screen (a row, a message, a code block, a card). */
77
+ interface ItemType {
78
+ name: string;
79
+ label: string;
80
+ description: string;
81
+ /** Value names that together identify one item. */
82
+ identity: readonly string[];
83
+ levels?: readonly string[];
84
+ entityType?: string;
85
+ values: readonly DeclaredValue[];
86
+ writeTargets?: readonly WriteTarget[];
87
+ }
88
+ type Readiness = "verified" | "partial" | "stub";
89
+ /** `ui_surface_execution_mode_check`, unchanged. */
90
+ type ExecutionMode = "python-stream" | "nextjs-stream" | "browser-realtime" | "local-runtime";
91
+ interface ConfigNamespaceDeclaration {
92
+ namespace: string;
93
+ label: string;
94
+ description: string;
95
+ }
96
+ interface EvidenceSourceDeclaration {
97
+ kind: "processed_document";
98
+ idValue: string;
99
+ fileIdValue?: string;
100
+ labelValue?: string;
101
+ representation?: "clean" | "raw";
102
+ }
103
+ /**
104
+ * One screen's declaration. Owning packages add fields (agent roles, client
105
+ * tools) as EXTENSION SLOTS — by interface extension or declaration merging —
106
+ * and register a `DeclarationExtension` so validation and the sync cover them.
107
+ */
108
+ interface SurfaceDeclaration {
109
+ surfaceName: string;
110
+ /** REQUIRED. `ui_surface.client_name`; must equal the surfaceName prefix. */
111
+ client: string;
112
+ /** REQUIRED. `ui_surface.execution_mode`. */
113
+ executionMode: ExecutionMode;
114
+ /** REQUIRED. `ui_surface.description` ("" only where the live row is empty). */
115
+ description: string;
116
+ label: string;
117
+ readiness: Readiness;
118
+ readinessNote?: string;
119
+ urlPattern?: string;
120
+ inheritsFrom?: string;
121
+ intro?: string;
122
+ overlayId?: string;
123
+ values: readonly DeclaredValue[];
124
+ groups?: readonly ValueGroup[];
125
+ writeTargets?: readonly WriteTarget[];
126
+ itemTypes?: readonly ItemType[];
127
+ liveSlots?: readonly LiveSlot[];
128
+ configNamespaces?: readonly ConfigNamespaceDeclaration[];
129
+ evidenceSources?: readonly EvidenceSourceDeclaration[];
130
+ skipBaselineValues?: boolean;
131
+ }
132
+ interface DeclarationIssue {
133
+ surfaceName: string;
134
+ /** "writeTargets/body/updatesValue" */
135
+ path: string;
136
+ sentence: string;
137
+ remedy: string;
138
+ /** Advisory issues are reported, never fatal (the ratchets). Default "error". */
139
+ severity?: "error" | "advisory";
140
+ }
141
+ /** A row the sync writes for an extension slot (e.g. agent roles, client tools). */
142
+ interface ExtensionRow {
143
+ table: string;
144
+ /** The row's key columns within its table (e.g. ["surface_name", "name"]). */
145
+ conflict: readonly string[];
146
+ row: Record<string, Json>;
147
+ }
148
+ interface DeclarationExtension<D extends SurfaceDeclaration = SurfaceDeclaration> {
149
+ key: string;
150
+ /** Package or app that owns the slot, shown in check failures. */
151
+ owner: string;
152
+ /**
153
+ * Lists this slot contributes to inheritance: a child inherits its parent's
154
+ * entries and overrides per identity (child wins).
155
+ */
156
+ inheritedLists?: readonly {
157
+ field: string;
158
+ identity(entry: unknown): string;
159
+ }[];
160
+ validate?(declaration: D, context: ValidationContext): readonly DeclarationIssue[];
161
+ toRows?(declaration: D): readonly ExtensionRow[];
162
+ }
163
+ interface ValidationContext {
164
+ /** Every registered declaration, resolved. */
165
+ all: readonly ResolvedSurfaceDeclaration[];
166
+ }
167
+ type ValueProvenance = {
168
+ kind: "own";
169
+ } | {
170
+ kind: "inherited";
171
+ from: string;
172
+ } | {
173
+ kind: "baseline";
174
+ };
175
+ type ResolvedValue = DeclaredValue & {
176
+ provenance: ValueProvenance;
177
+ groupKey: string;
178
+ /** Defaults filled. */
179
+ resolvedSensitivity: Sensitivity;
180
+ };
181
+ interface ResolvedSurfaceDeclaration extends SurfaceDeclaration {
182
+ contentHash: string;
183
+ values: readonly ResolvedValue[];
184
+ groups: readonly ValueGroup[];
185
+ }
186
+ /**
187
+ * ITEM KEYS. A value or write target is identified by (surfaceName, itemType ?? "", name).
188
+ * The qualified key "<itemType>.<name>" names an item value; a bare name is a screen value.
189
+ */
190
+ type QualifiedValueKey = string;
191
+ /** Live slot payloads (page-capture's shapes, kept). */
192
+ interface LiveValues {
193
+ selection?: {
194
+ choices: Record<string, Json>;
195
+ text: string | null;
196
+ };
197
+ "on-demand"?: readonly OnDemandSection[];
198
+ errors?: readonly string[];
199
+ requests?: readonly RecentRequest[];
200
+ }
201
+ interface OnDemandSection {
202
+ id: string;
203
+ title: string;
204
+ description?: string;
205
+ role: "data" | "request";
206
+ brief?: Json;
207
+ load(signal: AbortSignal): Promise<Json>;
208
+ }
209
+ interface RecentRequest {
210
+ method: string;
211
+ path: string;
212
+ status: string;
213
+ httpStatus?: number;
214
+ durationMs?: number;
215
+ requestId?: string;
216
+ client?: string;
217
+ requestBody?: Json;
218
+ requestBodyNote?: string;
219
+ errorSentence?: string;
220
+ timestamp: number;
221
+ }
222
+ /** RAW-FREE. What leaves the package about a clicked item. */
223
+ interface ResolvedItem {
224
+ itemType: string;
225
+ identity: Record<string, string>;
226
+ level?: string;
227
+ readOnly: boolean;
228
+ }
229
+
230
+ /** Every value, write-target, item-type and group name (the DB CHECK rule). */
231
+ declare const DECLARATION_NAME_RE: RegExp;
232
+ /** "<client>/<local>" — the surface naming convention. */
233
+ declare const SURFACE_NAME_RE: RegExp;
234
+ /** A bare screen value (`status`) or an item value (`table_row.status`). */
235
+ declare const QUALIFIED_VALUE_KEY_RE: RegExp;
236
+ interface ParsedValueKey {
237
+ /** "" for a screen-level value. */
238
+ itemType: string;
239
+ name: string;
240
+ }
241
+ /** Split a qualified key; null when it is not a valid bare or qualified key. */
242
+ declare function parseQualifiedValueKey(key: string): ParsedValueKey | null;
243
+ declare function qualifyValueKey(itemType: string, name: string): QualifiedValueKey;
244
+ /** The client that owns a surface: its name prefix. */
245
+ declare function surfaceClientOf(surfaceName: string): string;
246
+
247
+ /** Canonical JSON: keys sorted, undefined dropped, arrays in order. */
248
+ declare function canonicalJson(value: unknown): string;
249
+ /** SHA-256 hex of a UTF-8 string. Pure, synchronous, runs anywhere (no crypto API needed). */
250
+ declare function sha256Hex(input: string): string;
251
+ /**
252
+ * Drift between clients. Computed, never authored: SHA-256 of the canonical JSON
253
+ * of the declaration as authored (keys sorted, extension fields included).
254
+ * Persisted as `ui_surface.content_hash` once that column exists.
255
+ */
256
+ declare function declarationHash(declaration: SurfaceDeclaration): string;
257
+
258
+ declare const VALUE_TYPES: readonly ["string", "number", "boolean", "object", "array", "document"];
259
+ declare const WRITE_MODES: readonly ["draft", "entity", "ui", "stream"];
260
+ declare const APPLY_POLICIES: readonly ["manual", "ask", "auto", "queued"];
261
+ declare const STREAM_OPS: readonly ["replace", "insert_before", "insert_after", "prepend", "append", "patch"];
262
+ declare const EXECUTION_MODES: readonly ["python-stream", "nextjs-stream", "browser-realtime", "local-runtime"];
263
+ declare const READINESS: readonly ["verified", "partial", "stub"];
264
+ declare const LIVE_SLOTS: readonly ["selection", "on-demand", "errors", "requests"];
265
+ declare const CLASSIFICATIONS: readonly ["ordinary", "secret", "credential"];
266
+ interface ValidateOptions {
267
+ /** Registered config namespaces; omitted = not checked. */
268
+ knownNamespaces?: ReadonlySet<string>;
269
+ /** Registered content-ir kind slugs; omitted = not checked. */
270
+ isKnownKind?: (slug: string) => boolean;
271
+ /** Names every declaration must expose unless `skipBaselineValues`. */
272
+ baselineNames?: readonly string[];
273
+ extensions?: readonly DeclarationExtension[];
274
+ }
275
+ declare function validateDeclarations(declarations: readonly ResolvedSurfaceDeclaration[], options?: ValidateOptions): DeclarationIssue[];
276
+ /**
277
+ * The runtime half: a loaded scope may carry only declared values. Returns one
278
+ * issue per undeclared key (and per `__item` value its item type does not declare).
279
+ */
280
+ declare function validateLoadedValues(declaration: Pick<ResolvedSurfaceDeclaration, "surfaceName" | "values" | "itemTypes">, loaded: Record<string, unknown>, options?: {
281
+ ignore?: readonly string[];
282
+ }): DeclarationIssue[];
283
+ /**
284
+ * Ownership: no `ui.ui_surface` row may exist without a declaring owner
285
+ * (CONTRACT §2.1a). `retired` rows (archived, not deleted) are exempt.
286
+ */
287
+ declare function findOrphanRows(rowNames: readonly string[], declaredNames: Iterable<string>, retired?: Iterable<string>): string[];
288
+
289
+ declare const RESERVED_GROUP_KEYS: {
290
+ readonly general: "general";
291
+ readonly baseline: "baseline";
292
+ readonly inheritedPrefix: "inherited:";
293
+ };
294
+ /** Group sortOrder bands. Curated groups author 0–899; the rest is reserved. */
295
+ declare const GENERAL_GROUP_ORDER = 850;
296
+ declare const INHERITED_GROUP_ORDER_BASE = 9000;
297
+ declare const BASELINE_GROUP_ORDER = 9900;
298
+ declare const DEFAULT_MAX_INHERITANCE_DEPTH = 3;
299
+ declare const DEFAULT_SENSITIVITY: Sensitivity;
300
+ declare function resolveSensitivity(value: Pick<DeclaredValue, "sensitivity">): Sensitivity;
301
+ type Resolved<D extends SurfaceDeclaration> = Omit<D, "values" | "groups"> & {
302
+ values: readonly (D["values"][number] & ResolvedValue)[];
303
+ groups: readonly ValueGroup[];
304
+ contentHash: string;
305
+ };
306
+ interface DeclarationRegistryOptions {
307
+ /** Generic values injected into every declaration unless `skipBaselineValues`. */
308
+ baselineValues?: readonly DeclaredValue[];
309
+ /** Value names only the platform writes; a declaration claiming one is refused. */
310
+ reservedValueNames?: readonly string[];
311
+ /** Write-target names only the platform writes. */
312
+ reservedWriteTargetNames?: readonly string[];
313
+ maxInheritanceDepth?: number;
314
+ }
315
+ interface DeclarationRegistry<D extends SurfaceDeclaration> {
316
+ /** Refuses a second declaration of the same surfaceName. */
317
+ register(declaration: D): void;
318
+ registerExtension(extension: DeclarationExtension<D>): void;
319
+ extensions(): readonly DeclarationExtension<D>[];
320
+ /** Declarations exactly as authored (inheritance unresolved, no baselines). */
321
+ raw(): readonly D[];
322
+ getRaw(surfaceName: string): D | undefined;
323
+ /** Parent chain, ROOT FIRST. Unknown surfaces return []. */
324
+ ancestry(surfaceName: string): string[];
325
+ /** Direct children (declarations naming it in `inheritsFrom`), in declaration order. */
326
+ children(surfaceName: string): string[];
327
+ /** Inheritance + baseline + groups resolved; provenance kept. */
328
+ all(): readonly Resolved<D>[];
329
+ get(surfaceName: string): Resolved<D> | undefined;
330
+ validate(options?: ValidateOptions): readonly DeclarationIssue[];
331
+ }
332
+ declare function createDeclarationRegistry<D extends SurfaceDeclaration>(options?: DeclarationRegistryOptions): DeclarationRegistry<D>;
333
+
334
+ export { APPLY_POLICIES, type ApplyPolicy, BASELINE_GROUP_ORDER, CLASSIFICATIONS, type Classification, type ConfigNamespaceDeclaration, DECLARATION_NAME_RE, DEFAULT_MAX_INHERITANCE_DEPTH, DEFAULT_SENSITIVITY, type DeclarationExtension, type DeclarationIssue, type DeclarationRegistry, type DeclarationRegistryOptions, type DeclaredValue, EXECUTION_MODES, type EvidenceSourceDeclaration, type ExecutionMode, type ExtensionRow, GENERAL_GROUP_ORDER, INHERITED_GROUP_ORDER_BASE, type ItemType, type Json, LIVE_SLOTS, type LiveSlot, type LiveValues, type OnDemandSection, type ParsedValueKey, QUALIFIED_VALUE_KEY_RE, type QualifiedValueKey, READINESS, RESERVED_GROUP_KEYS, type Readiness, type RecentRequest, type Resolved, type ResolvedItem, type ResolvedSurfaceDeclaration, type ResolvedValue, STREAM_OPS, SURFACE_NAME_RE, type Sensitivity, type StreamOp, type SurfaceDeclaration, VALUE_TYPES, type ValidateOptions, type ValidationContext, type ValueGroup, type ValueProvenance, type ValueType, WRITE_MODES, type WriteMode, type WriteTarget, canonicalJson, createDeclarationRegistry, declarationHash, findOrphanRows, parseQualifiedValueKey, qualifyValueKey, resolveSensitivity, sha256Hex, surfaceClientOf, validateDeclarations, validateLoadedValues };