@almadar/core 10.58.0 → 10.59.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,3178 @@
1
+ import { b3 as PageTraitRef, O as OrbitalSchema, bh as ThemeDefinition, aa as Orbital, c as Page, N as DomainContext, a as OrbitalDefinition } from './schema-CVTOy4at.js';
2
+ import { F as FieldValue, E as EntityField, a as EntityPersistence, bp as ServiceParams, e as Entity, f as EntityRow, A as AnyPatternConfig, O as OrbitalId, T as TraitId, b as EventId, c as Effect } from './effect-CK9fn56C.js';
3
+ import { S as SExpr, R as RuntimeValue, d as EventPayloadValue, J as JsonValue, a as EventPayload, L as LogMeta, g as JsonObject, T as ToolArgs, c as EvalContext } from './expression-Fk8bQWef.js';
4
+ import { z } from 'zod';
5
+ import { a as TraitReference, g as Trait, L as ListenSource, D as DeclaredTraitConfig, b as TraitConfig, C as ConfigFieldDeclaration, S as State, ae as Transition, r as Event, e as TraitConfigValue, Y as TraitCategory, as as TraitScope } from './trait-BjPraUgs.js';
6
+ import { T as TraitOverlay, R as RuleOverlay, J as JsonSchema, c as FactoryConfigTier } from './types-Dopw3s2O.js';
7
+ import { MakeTraitRefOpts, EventWiringEntry, LayoutStrategy } from './builders.js';
8
+
9
+ /**
10
+ * S-Expression Bindings
11
+ *
12
+ * Defines binding types and utilities for S-expression context.
13
+ * Bindings are references to values that are resolved at runtime.
14
+ *
15
+ * Core Bindings:
16
+ * - @entity - The linked entity for this trait (e.g., @entity.health)
17
+ * - @payload - Event payload data (e.g., @payload.amount)
18
+ * - @state - Current state machine state
19
+ * - @now - Current timestamp (Date.now())
20
+ *
21
+ * Entity Bindings:
22
+ * - @EntityName.field - Reference to singleton/runtime entity (e.g., @GameConfig.gravity)
23
+ *
24
+ * @packageDocumentation
25
+ */
26
+
27
+ /**
28
+ * Schema for a binding string.
29
+ * Validates that the string starts with @ and has valid format.
30
+ */
31
+ declare const BindingSchema: z.ZodEffects<z.ZodString, string, string>;
32
+ /**
33
+ * Binding documentation for LLM prompts and validation messages.
34
+ *
35
+ * IMPORTANT: Keep synchronized with CORE_BINDINGS in expression.ts
36
+ */
37
+ declare const BINDING_DOCS: {
38
+ readonly entity: {
39
+ readonly description: "Reference to the linked entity for this trait";
40
+ readonly examples: readonly ["@entity.health", "@entity.x", "@entity.status"];
41
+ readonly requiresPath: true;
42
+ };
43
+ readonly payload: {
44
+ readonly description: "Reference to the event payload data";
45
+ readonly examples: readonly ["@payload.amount", "@payload.targetId", "@payload.action"];
46
+ readonly requiresPath: true;
47
+ };
48
+ readonly state: {
49
+ readonly description: "Current state machine state name";
50
+ readonly examples: readonly ["@state"];
51
+ readonly requiresPath: false;
52
+ };
53
+ readonly now: {
54
+ readonly description: "Current timestamp in milliseconds";
55
+ readonly examples: readonly ["@now"];
56
+ readonly requiresPath: false;
57
+ };
58
+ readonly config: {
59
+ readonly description: "Trait configuration values";
60
+ readonly examples: readonly ["@config.apiEndpoint", "@config.theme"];
61
+ readonly requiresPath: true;
62
+ };
63
+ readonly computed: {
64
+ readonly description: "Computed/calculated values";
65
+ readonly examples: readonly ["@computed.total", "@computed.isValid"];
66
+ readonly requiresPath: true;
67
+ };
68
+ readonly trait: {
69
+ readonly description: "Trait context data";
70
+ readonly examples: readonly ["@trait.name", "@trait.category"];
71
+ readonly requiresPath: true;
72
+ };
73
+ readonly user: {
74
+ readonly description: "Authenticated user / agent context for ownership and role-based gating";
75
+ readonly examples: readonly ["@user.id", "@user.role"];
76
+ readonly requiresPath: true;
77
+ };
78
+ readonly callsitePayload: {
79
+ readonly description: "Call-site-captured event payload — emitted by the compiler's inline-trait hoisting when an extracted render block captured @payload; resolved at the composing effect by the runtime BindingResolver";
80
+ readonly examples: readonly ["@callsitePayload.error", "@callsitePayload.row"];
81
+ readonly requiresPath: true;
82
+ };
83
+ readonly pages: {
84
+ readonly description: "Render-resolved schema sigil — the host orbital's pages as a NavItem[] array (href = page.path, label = page.name). Substituted from the OrbitalSchema before codegen; never survives as a live binding.";
85
+ readonly examples: readonly ["@pages"];
86
+ readonly requiresPath: false;
87
+ };
88
+ readonly currentTheme: {
89
+ readonly description: "Render-resolved schema sigil — the host orbital's active data-theme key, derived from Orbital.theme. Substituted from the OrbitalSchema before codegen; never survives as a live binding.";
90
+ readonly examples: readonly ["@currentTheme"];
91
+ readonly requiresPath: false;
92
+ };
93
+ };
94
+ /**
95
+ * Validation rules for bindings in different contexts.
96
+ */
97
+ declare const BINDING_CONTEXT_RULES: {
98
+ readonly guard: {
99
+ readonly allowed: readonly ["entity", "payload", "state", "now", "config", "user"];
100
+ readonly description: "Guards can access entity fields, event payload, current state, time, the call-site trait config (@config.X), and the authenticated user context (@user.id, @user.role) for ownership / role gates. Config access lets atoms write mode-aware guards — e.g. std-modal's OPEN can require @payload.row only when @config.mode equals \"edit\", letting create-mode legitimately fire OPEN with no row. Like effects, @config.X is substituted at molecule/organism inline time with the literal call-site value; at atom-scope validate, @config is allowed-but-unresolved.";
101
+ };
102
+ readonly effect: {
103
+ readonly allowed: readonly ["entity", "payload", "state", "now", "trait", "config", "user", "callsitePayload", "pages", "currentTheme"];
104
+ readonly description: "Effects can access and modify entity fields, use payload data, embed another trait's live frame via @trait.X inside render-ui children, read trait config values (@config.X) for atoms parameterized by their call-site, and read the authenticated user context (@user.id, @user.role). At molecule/organism inline time, @config.X is substituted with the literal value from the call-site config block; at atom-scope validate, @config is allowed-but-unresolved. @callsitePayload.X is the call-site-captured event payload emitted by the compiler's inline-trait hoisting (a hoisted render block that captured @payload); it is resolved at the composing effect by the runtime BindingResolver.";
105
+ };
106
+ readonly tick: {
107
+ readonly allowed: readonly ["entity", "state", "now", "config", "user"];
108
+ readonly description: "Ticks can access entity fields, current state, time, trait config (@config.X) for parameterized atoms, and the authenticated user context (@user.id, @user.role). Same substitution semantics as guards/effects.";
109
+ };
110
+ };
111
+ type BindingContext = keyof typeof BINDING_CONTEXT_RULES;
112
+ /**
113
+ * Tag property of a `RenderBindingMarker`. `$`-prefixed so it can never
114
+ * collide with a pattern prop key (prop keys are camelCase identifiers).
115
+ */
116
+ declare const RENDER_BINDING_MARKER: "$renderBinding";
117
+ /**
118
+ * A render-ui prop leaf that is evaluated at RENDER time, not at flush time.
119
+ *
120
+ * The interpreted path's executor carries `@entity`-dependent leaves into
121
+ * slot content as these markers instead of resolving them eagerly; the
122
+ * renderer (`@almadar/ui`'s SlotContentRenderer) resolves each marker
123
+ * against the live entity store on every render — the same model the
124
+ * compiled shell uses (state-based JSX reading `fields?.X` per React
125
+ * render). Payload-dependent leaves are never deferred: `@payload` is
126
+ * event-scoped and does not exist at render time.
127
+ *
128
+ * A `type` (not `interface`) so it carries an implicit index signature and
129
+ * stays assignable to the `SExpr` record branch at guard call sites.
130
+ */
131
+ type RenderBindingMarker = {
132
+ readonly [RENDER_BINDING_MARKER]: true;
133
+ /** The raw prop expression: a binding string (`'@entity.hp'`, embedded
134
+ * form `'HP: @entity.hp'`) or an S-expression tree. */
135
+ readonly expression: SExpr;
136
+ };
137
+ /** Narrow an arbitrary prop value to a `RenderBindingMarker`. */
138
+ declare function isRenderBindingMarker(value: RuntimeValue): value is RenderBindingMarker;
139
+ /**
140
+ * Does this raw prop expression reference `@entity` anywhere (pure binding,
141
+ * embedded-binding string, nested S-expression, or object tree)? Marker
142
+ * objects count as entity-referencing by construction.
143
+ */
144
+ declare function containsEntityBinding(value: SExpr): boolean;
145
+ /**
146
+ * Does this raw prop expression reference the event payload (`@payload` /
147
+ * `@callsitePayload`) anywhere? Such leaves stay flush-time evaluated —
148
+ * the payload does not exist at render time.
149
+ */
150
+ declare function containsPayloadBinding(value: SExpr): boolean;
151
+ /**
152
+ * Check if a binding is valid in a given context.
153
+ *
154
+ * @param binding - Parsed binding
155
+ * @param context - Context where binding is used
156
+ * @returns Error message if invalid, null if valid
157
+ */
158
+ declare function validateBindingInContext(binding: {
159
+ type: 'core' | 'entity';
160
+ root: string;
161
+ }, context: BindingContext): string | null;
162
+ /**
163
+ * Get all valid binding examples for a context.
164
+ *
165
+ * @param context - Context to get examples for
166
+ * @returns Array of example binding strings
167
+ */
168
+ declare function getBindingExamples(context: BindingContext): string[];
169
+
170
+ /**
171
+ * Binding root classification
172
+ *
173
+ * The prefix of an `@X.path` binding expression identifies which runtime
174
+ * context resolves the rest of the path. This type is the TS-side mirror
175
+ * of `OirBindingRoot` in `orbital-core`'s IR; publishing it from
176
+ * `@almadar/core` lets the codegen, the runtime binding resolver, and
177
+ * the verifier's schema walker all refer to the same narrow union.
178
+ *
179
+ * Distinct from {@link ParsedBinding.root} (which is a plain string): use
180
+ * `BindingRoot` whenever you need exhaustiveness over the known prefixes.
181
+ *
182
+ * - `entity`: `@entity.field` — the trait's linked entity (first row on
183
+ * the client, `getById` result on the server).
184
+ * - `payload`: `@payload.x` — the last event's payload.
185
+ * - `state`: `@state.x` — the state machine's `state` slot (rare;
186
+ * mostly used for guard/effect contexts).
187
+ * - `config`: `@config.x` — the trait ref's merged config from the
188
+ * molecule call site.
189
+ * - `user`: `@user.x` — authenticated user / agent context.
190
+ * - `trait`: `@trait.x` — render-time reference to another trait's
191
+ * mounted view. Resolved by `<TraitFrame>` at runtime, not by the
192
+ * SExpression compiler.
193
+ * - `item`: `@item.x` — iterator variable inside a `map` / repeat
194
+ * pattern.
195
+ * - `now`: `@now` — current timestamp (ISO string).
196
+ * - `computed`: `@computed.x` — evaluator-computed value (Phase 4.5).
197
+ * - `other`: catch-all for unknown prefixes or entity-reference
198
+ * bindings (`@User.name`, `@_item`).
199
+ *
200
+ * @packageDocumentation
201
+ */
202
+
203
+ type BindingRoot = 'entity' | 'payload' | 'state' | 'config' | 'user' | 'trait' | 'item' | 'now' | 'computed' | 'other';
204
+ /** Every known binding root, in a stable order — useful for exhaustiveness checks. */
205
+ declare const BINDING_ROOTS: readonly BindingRoot[];
206
+ /**
207
+ * Narrow a raw binding-root string (e.g. the `root` field of
208
+ * `ParsedBinding` from `./expression.ts`) to a `BindingRoot`. Returns
209
+ * `'other'` for entity-reference roots like `@User.name` or unknown
210
+ * prefixes.
211
+ */
212
+ declare function toBindingRoot(root: string): BindingRoot;
213
+ /**
214
+ * A trait reference string of the form `@trait.<TraitName>`. Used as the
215
+ * value type for `trait`-typed config fields. The runtime + compiled codegen
216
+ * both substitute this with embedded trait UI at render time.
217
+ *
218
+ * Branded as a literal-template type so TS narrows on use; consumers should
219
+ * call {@link isTraitFieldRef} to validate runtime values before assignment.
220
+ */
221
+ type TraitFieldRef = `@trait.${string}`;
222
+ /** Type guard: narrow an unknown value to {@link TraitFieldRef}. */
223
+ declare function isTraitFieldRef(value: RuntimeValue): value is TraitFieldRef;
224
+ /** Zod schema for {@link TraitFieldRef} values. Useful when validating analyzer
225
+ * JSON or recipe overrides at runtime boundaries. */
226
+ declare const TraitFieldRefSchema: z.ZodString;
227
+
228
+ /**
229
+ * Authenticated user context — what `@user.x` resolves against.
230
+ *
231
+ * The canonical shape for the `user` binding root, shared by both execution
232
+ * paths: the JS interpreter resolves `@user.id` through
233
+ * `EvaluationContext.user`, and the compiled shell emits `user?.id` against the
234
+ * `UserContext` its `@app/shared` re-exports from here.
235
+ *
236
+ * `id` is the field the behavior library reads for ownership scoping and `role`
237
+ * the field it reads for capability gating. Auth providers that name the subject
238
+ * `uid` must normalize at their boundary — {@link normalizeUserContext} does that.
239
+ *
240
+ * @packageDocumentation
241
+ */
242
+
243
+ /** Authenticated user / agent identity behind `@user.x` bindings. */
244
+ interface UserContext {
245
+ /** Stable subject identifier. `@user.id` — the ownership key. */
246
+ id: string;
247
+ /** `@user.email` */
248
+ email?: string;
249
+ /** `@user.name` — display name. */
250
+ name?: string;
251
+ /** `@user.role` — single role string, compared against a policy's allowed list. */
252
+ role?: string;
253
+ /** `@user.permissions` — fine-grained capability strings. */
254
+ permissions?: string[];
255
+ /** Additional provider claims, readable as `@user.<claim>`. */
256
+ [key: string]: FieldValue | undefined;
257
+ }
258
+ /**
259
+ * The identity of an unauthenticated viewer. A resolvable object rather than
260
+ * `undefined` so a role predicate evaluates to a definite `false` instead of
261
+ * comparing against nothing.
262
+ */
263
+ declare const ANONYMOUS_USER: UserContext;
264
+ /** Provider-shaped identity claims, before normalization. */
265
+ interface RawUserClaims {
266
+ id?: string;
267
+ uid?: string;
268
+ email?: string | null;
269
+ name?: string;
270
+ displayName?: string | null;
271
+ role?: string;
272
+ permissions?: string[];
273
+ [key: string]: FieldValue | undefined;
274
+ }
275
+ /**
276
+ * Normalize provider claims into a {@link UserContext}.
277
+ *
278
+ * Firebase (and most OIDC providers) name the subject `uid` and the display name
279
+ * `displayName`, while every `.lolo` behavior reads `@user.id` / `@user.name`.
280
+ * Without this normalization `@user.id` is `undefined` against a fully
281
+ * authenticated request and every ownership filter silently matches no rows.
282
+ * `uid` is preserved so `@user.uid` keeps working.
283
+ *
284
+ * Returns `undefined` for absent or subject-less claims so callers can
285
+ * distinguish "no auth ran" from "anonymous"; use {@link ANONYMOUS_USER} where a
286
+ * definite identity is required.
287
+ */
288
+ declare function normalizeUserContext(claims: RawUserClaims | null | undefined): UserContext | undefined;
289
+ /**
290
+ * Turn a row of an app's `[identity]` entity into a viewer.
291
+ *
292
+ * There is no separate persona shape: an identity row IS the persona
293
+ * (`Almadar_LOLO_Identity.md` §4.3), so this only guards the one field the
294
+ * behavior library requires — a non-empty string `id` — and passes every other
295
+ * declared field through as a `@user.<field>` claim. Rows without a usable id
296
+ * yield `undefined` rather than a persona nobody can own rows as.
297
+ */
298
+ declare function personaFromIdentityRow(row: Record<string, FieldValue | undefined>): UserContext | undefined;
299
+ /**
300
+ * The viewer a host presents when nothing named one.
301
+ *
302
+ * Without this, `@user` is `Null` in headless verify and preview, so every
303
+ * `viewerName: @user.name` binding renders blank and the account menu never
304
+ * appears — an app that cannot say who you are. Worse, an ownership filter that
305
+ * works and one that is broken both render an empty table.
306
+ *
307
+ * `role` is deliberately EMPTY, not a guess. A default of `admin` would silently
308
+ * flip which branch renders at the 38 `@user.role` comparisons in the corpus;
309
+ * an empty role matches no literal, exactly as `Null` did, so this fixes
310
+ * "undefined at runtime" without changing a single guard outcome.
311
+ */
312
+ declare const DEFAULT_VIEWER: UserContext;
313
+ /**
314
+ * The viewer to present an app as when nothing named one.
315
+ *
316
+ * `DEFAULT_VIEWER` is synthetic — `viewer-1` is in no app's roster — so under it
317
+ * every ownership predicate (`@entity.<owner> == @user.id`) matches zero rows and
318
+ * a correctly-scoped app renders empty tables everywhere. That is indistinguishable
319
+ * on screen from a broken filter, which is exactly the failure DEFAULT_VIEWER's own
320
+ * comment warns about.
321
+ *
322
+ * So when the app declares an `[identity]` roster, the default viewer is a REAL
323
+ * member of it. `DEFAULT_VIEWER` remains the fallback for apps that declare no
324
+ * identity entity, where there is nobody to be.
325
+ *
326
+ * Both execution paths share this rule; the Rust twin is
327
+ * `orbital-core::runtime::persona::resolve_default_viewer`.
328
+ */
329
+ declare function resolveDefaultViewer(roster: readonly UserContext[]): UserContext;
330
+ /** Look a persona up in a roster by id, or by role when no id matches. */
331
+ declare function findPersonaInRoster(roster: readonly UserContext[], idOrRole: string): UserContext | undefined;
332
+ /**
333
+ * Resolve a persona spec — a bare id/role (`Person Id 3`, `moderator`) or a full
334
+ * JSON `UserContext` — into a viewer. This is the `ALMADAR_PERSONA` contract,
335
+ * shared by every host that presents an app as somebody.
336
+ *
337
+ * The roster is the app's OWN declared personas — the seeded rows of its
338
+ * `[identity]` entity (`Almadar_LOLO_Identity.md` §4.3) — supplied by the host
339
+ * that has them in hand (the runtime's live store on the interpreter path, the
340
+ * schema-derived seed rows on the compiled path). There is no global roster:
341
+ * an app without an `[identity]` entity resolves only JSON-form specs.
342
+ *
343
+ * Throws on anything unresolvable rather than returning `undefined`: "no persona"
344
+ * and "persona silently ignored" look identical on screen, so a bad spec must
345
+ * fail at boot instead of rendering as nobody.
346
+ */
347
+ declare function resolvePersonaSpec(spec: string, roster: readonly UserContext[]): UserContext;
348
+ /**
349
+ * Marks a bearer token as a mocked dev identity rather than a real ID token.
350
+ * The prefix is deliberately unmistakable: a server accepts these ONLY behind an
351
+ * explicit dev opt-in, so a production deployment rejects them like any other
352
+ * malformed token.
353
+ */
354
+ declare const DEV_TOKEN_PREFIX = "almadar-dev.";
355
+ /**
356
+ * Encode a viewer as a dev bearer token.
357
+ *
358
+ * Carries the WHOLE identity, not just the subject: real Firebase claims have no
359
+ * `role`, so a server that only reads `uid` leaves every `@user.role` gate inert
360
+ * even for a signed-in user. URI-encoded JSON keeps the token header-safe (no
361
+ * spaces or delimiters) and works unchanged in Node and the browser.
362
+ */
363
+ declare function encodeDevIdentityToken(user: UserContext): string;
364
+ /**
365
+ * Decode a dev bearer token back into a viewer, or `undefined` if it is not one
366
+ * / is malformed — callers fail closed rather than inventing an identity.
367
+ */
368
+ declare function decodeDevIdentityToken(token: string): UserContext | undefined;
369
+
370
+ /**
371
+ * Validation error types — the shape emitted by every
372
+ * `.orb` / `.lolo` validator pass.
373
+ *
374
+ * `ValidationError` is the wire shape: `{ code, path, message, suggestion? }`.
375
+ * `code` is `ValidationErrorCode`, which is an OPEN `string` to let the
376
+ * Rust validator emit new codes without an `@almadar/core` rev. The
377
+ * `KNOWN_VALIDATION_ERROR_CODES` const documents the codes currently
378
+ * emitted by the validator + lolo lower pipeline (extracted from
379
+ * `orbital-rust/crates/orbital-compiler/src/phases/validation/` +
380
+ * `orbital-rust/crates/orbital-lolo/src/`).
381
+ *
382
+ * Consumers that want to narrow a code to the closed known set use
383
+ * `KnownValidationErrorCode`:
384
+ *
385
+ * ```ts
386
+ * if (err.code in KNOWN_VALIDATION_ERROR_CODES) {
387
+ * // err.code is now narrowable to KnownValidationErrorCode for
388
+ * // exhaustive switch handling.
389
+ * }
390
+ * ```
391
+ *
392
+ * @packageDocumentation
393
+ */
394
+ /**
395
+ * One validation diagnostic emitted by the validator / lolo lower pipeline.
396
+ *
397
+ * - `code`: machine-readable identifier (see `KNOWN_VALIDATION_ERROR_CODES`).
398
+ * - `path`: JSON pointer-like path into the failing schema location,
399
+ * e.g. `'orbitals[0].traits[2].stateMachine.transitions[1].effects[0]'`.
400
+ * - `message`: human-readable description of the failure.
401
+ * - `suggestion`: optional hint the validator may add to help the
402
+ * author / LLM fix the issue.
403
+ */
404
+ interface ValidationError {
405
+ code: ValidationErrorCode;
406
+ path: string;
407
+ message: string;
408
+ suggestion?: string;
409
+ }
410
+ /**
411
+ * Validation error code — open `string` for forward-compat with the
412
+ * Rust validator's evolving code set. Narrow to the closed known set
413
+ * via `KnownValidationErrorCode` when exhaustive handling is needed.
414
+ */
415
+ type ValidationErrorCode = string;
416
+ /**
417
+ * The result of a single validator pass: a boolean verdict plus the errors
418
+ * and warnings (the validator wire shape, `ValidationError`).
419
+ *
420
+ * Distinct from `ValidationResults` (app.ts): that is the Firestore-persisted
421
+ * app-document shape keyed on `ValidationIssue` (with `severity` + array path
422
+ * + `validatedAt`). This `ValidationResult` is the in-process pass result keyed
423
+ * on `ValidationError` (code + JSON-pointer string path + `suggestion`).
424
+ * `ok === true` iff there are zero errors AND zero warnings.
425
+ */
426
+ interface ValidationResult {
427
+ ok: boolean;
428
+ errors: ValidationError[];
429
+ warnings: ValidationError[];
430
+ }
431
+ /**
432
+ * Closed set of validation codes the Rust validator + lolo lower
433
+ * pipeline currently emit. Source-tagged: codes are extracted from
434
+ * `orbital-rust/crates/orbital-compiler/src/phases/validation/**.rs`
435
+ * and `orbital-rust/crates/orbital-lolo/src/**.rs`. Keep this in sync
436
+ * with the Rust side; mismatches are caught by the Rust validator's
437
+ * own unit tests, which assert the emitted code-set matches an
438
+ * exported manifest.
439
+ *
440
+ * Categories (prefix → meaning):
441
+ * - `ORB_BINDING_*` — binding (`@entity.X`, `@payload.Y`, ...) issues
442
+ * - `ORB_E_*` / `ORB_EFF_*` / `ORB_EMIT_*` — entity / effect / emit
443
+ * - `ORB_GEN_*` — generic / cross-cutting structure
444
+ * - `ORB_O_*` / `ORB_P_*` / `ORB_S_*` / `ORB_SM_*` / `ORB_T_*` —
445
+ * orbital / page / schema / state-machine / trait
446
+ * - `ORB_QUERY_*` — query / search behaviors
447
+ * - `ORB_RUI_*` — render-UI binding + prop validation
448
+ * - `ORB_SLOT_*` — UI-slot conflict / contention
449
+ * - `ORB_SVC_*` / `ORB_UI_*` — service / UI primitives
450
+ * - `ORB_X_*` — cross-orbital constraints (listens, emits, IDs)
451
+ * - `ORB_ID_*` — V4 dual-carry id integrity (unknown ref, name/kind
452
+ * mismatch, ledger orphan)
453
+ */
454
+ declare const KNOWN_VALIDATION_ERROR_CODES: {
455
+ readonly ORB_BINDING_ENTITY_FIELD_NEVER_SET: "ORB_BINDING_ENTITY_FIELD_NEVER_SET";
456
+ readonly ORB_BINDING_ENTITY_FIELD_NOT_FOUND: "ORB_BINDING_ENTITY_FIELD_NOT_FOUND";
457
+ readonly ORB_BINDING_INVALID_FIELD_NAME: "ORB_BINDING_INVALID_FIELD_NAME";
458
+ readonly ORB_BINDING_INVALID_FORMAT: "ORB_BINDING_INVALID_FORMAT";
459
+ readonly ORB_BINDING_INVALID_PATH: "ORB_BINDING_INVALID_PATH";
460
+ readonly ORB_BINDING_NOW_NO_PATH: "ORB_BINDING_NOW_NO_PATH";
461
+ readonly ORB_BINDING_PAYLOAD_FIELD_UNDECLARED: "ORB_BINDING_PAYLOAD_FIELD_UNDECLARED";
462
+ readonly ORB_BINDING_PAYLOAD_IN_TICK: "ORB_BINDING_PAYLOAD_IN_TICK";
463
+ readonly ORB_BINDING_PAYLOAD_TYPE_INCOMPATIBLE: "ORB_BINDING_PAYLOAD_TYPE_INCOMPATIBLE";
464
+ readonly ORB_BINDING_SET_TARGET_MISSING_PATH: "ORB_BINDING_SET_TARGET_MISSING_PATH";
465
+ readonly ORB_BINDING_STATE_NO_PATH: "ORB_BINDING_STATE_NO_PATH";
466
+ readonly ORB_BINDING_TRAIT_CYCLE: "ORB_BINDING_TRAIT_CYCLE";
467
+ readonly ORB_BINDING_TRAIT_INVALID_FORMAT: "ORB_BINDING_TRAIT_INVALID_FORMAT";
468
+ readonly ORB_BINDING_TRAIT_INVALID_POSITION: "ORB_BINDING_TRAIT_INVALID_POSITION";
469
+ readonly ORB_BINDING_TRAIT_MISSING_NAME: "ORB_BINDING_TRAIT_MISSING_NAME";
470
+ readonly ORB_BINDING_TRAIT_SELF_REFERENCE: "ORB_BINDING_TRAIT_SELF_REFERENCE";
471
+ readonly ORB_BINDING_TRAIT_UNKNOWN: "ORB_BINDING_TRAIT_UNKNOWN";
472
+ readonly ORB_BINDING_UNKNOWN_ENTITY: "ORB_BINDING_UNKNOWN_ENTITY";
473
+ readonly ORB_BINDING_UNKNOWN_ROOT: "ORB_BINDING_UNKNOWN_ROOT";
474
+ readonly ORB_E_DUPLICATE_FIELD: "ORB_E_DUPLICATE_FIELD";
475
+ readonly ORB_E_EMPTY_ENUM_VALUES: "ORB_E_EMPTY_ENUM_VALUES";
476
+ readonly ORB_E_INVALID_FIELD_NAME: "ORB_E_INVALID_FIELD_NAME";
477
+ readonly ORB_E_INVALID_FIELD_TYPE: "ORB_E_INVALID_FIELD_TYPE";
478
+ readonly ORB_E_INVALID_RELATION: "ORB_E_INVALID_RELATION";
479
+ readonly ORB_E_LITERAL_UNION_DEFAULT_MISMATCH: "ORB_E_LITERAL_UNION_DEFAULT_MISMATCH";
480
+ readonly ORB_E_MISSING_COLLECTION: "ORB_E_MISSING_COLLECTION";
481
+ readonly ORB_E_MISSING_NAME: "ORB_E_MISSING_NAME";
482
+ readonly ORB_E_NO_FIELDS: "ORB_E_NO_FIELDS";
483
+ readonly ORB_EFF_CALL_SERVICE_MISSING_ACTION: "ORB_EFF_CALL_SERVICE_MISSING_ACTION";
484
+ readonly ORB_EFF_CALL_SERVICE_MISSING_HANDLERS: "ORB_EFF_CALL_SERVICE_MISSING_HANDLERS";
485
+ readonly ORB_EFF_CALL_SERVICE_MISSING_SERVICE: "ORB_EFF_CALL_SERVICE_MISSING_SERVICE";
486
+ readonly ORB_EFF_EMIT_INVALID_NAME: "ORB_EFF_EMIT_INVALID_NAME";
487
+ readonly ORB_EFF_EMIT_KEY_INVALID: "ORB_EFF_EMIT_KEY_INVALID";
488
+ readonly ORB_EFF_EMIT_UNDECLARED_EVENT: "ORB_EFF_EMIT_UNDECLARED_EVENT";
489
+ readonly ORB_EFF_FETCH_INVALID_ENTITY: "ORB_EFF_FETCH_INVALID_ENTITY";
490
+ readonly ORB_EFF_FETCH_INVALID_INCLUDE: "ORB_EFF_FETCH_INVALID_INCLUDE";
491
+ readonly ORB_EFF_MISSING_FETCH_FOR_ENTITY: "ORB_EFF_MISSING_FETCH_FOR_ENTITY";
492
+ readonly ORB_EFF_MISSING_REQUIRED_EMIT: "ORB_EFF_MISSING_REQUIRED_EMIT";
493
+ readonly ORB_EFF_NAVIGATE_MISSING_PAYLOAD: "ORB_EFF_NAVIGATE_MISSING_PAYLOAD";
494
+ readonly ORB_EFF_NAVIGATE_TARGET_UNREACHABLE: "ORB_EFF_NAVIGATE_TARGET_UNREACHABLE";
495
+ readonly ORB_EFF_SET_INVALID_BINDING: "ORB_EFF_SET_INVALID_BINDING";
496
+ readonly ORB_EFF_SET_PAYLOAD_NOT_ALLOWED: "ORB_EFF_SET_PAYLOAD_NOT_ALLOWED";
497
+ readonly ORB_EFF_SLOT_CONFLICT: "ORB_EFF_SLOT_CONFLICT";
498
+ readonly ORB_EFF_UNKNOWN_TYPE: "ORB_EFF_UNKNOWN_TYPE";
499
+ readonly ORB_EMIT_DECLARED_BUT_UNFIRED: "ORB_EMIT_DECLARED_BUT_UNFIRED";
500
+ readonly ORB_EMIT_PAYLOAD_EXTRA_FIELD: "ORB_EMIT_PAYLOAD_EXTRA_FIELD";
501
+ readonly ORB_EMIT_PAYLOAD_FIELD_TYPE_MISMATCH: "ORB_EMIT_PAYLOAD_FIELD_TYPE_MISMATCH";
502
+ readonly ORB_EMIT_PAYLOAD_MISSING_REQUIRED: "ORB_EMIT_PAYLOAD_MISSING_REQUIRED";
503
+ readonly ORB_EMIT_SUCCESS_PAYLOAD_RETURN_MISMATCH: "ORB_EMIT_SUCCESS_PAYLOAD_RETURN_MISMATCH";
504
+ readonly ORB_GEN_DUPLICATE: "ORB_GEN_DUPLICATE";
505
+ readonly ORB_GEN_INVALID_REFERENCE: "ORB_GEN_INVALID_REFERENCE";
506
+ readonly ORB_GEN_INVALID_VALUE: "ORB_GEN_INVALID_VALUE";
507
+ readonly ORB_GEN_MISSING_FIELD: "ORB_GEN_MISSING_FIELD";
508
+ readonly ORB_O_MISSING_PAGES: "ORB_O_MISSING_PAGES";
509
+ readonly ORB_P_DUPLICATE_PATH: "ORB_P_DUPLICATE_PATH";
510
+ readonly ORB_P_EMPTY_TRAITS: "ORB_P_EMPTY_TRAITS";
511
+ readonly ORB_P_INVALID_PATH: "ORB_P_INVALID_PATH";
512
+ readonly ORB_P_INVALID_TRAIT_REF: "ORB_P_INVALID_TRAIT_REF";
513
+ readonly ORB_P_INVALID_VIEW_TYPE: "ORB_P_INVALID_VIEW_TYPE";
514
+ readonly ORB_P_MISSING_NAME: "ORB_P_MISSING_NAME";
515
+ readonly ORB_P_MISSING_PATH: "ORB_P_MISSING_PATH";
516
+ readonly ORB_P_MISSING_TRAITS: "ORB_P_MISSING_TRAITS";
517
+ readonly ORB_P_SECTIONS_FORBIDDEN: "ORB_P_SECTIONS_FORBIDDEN";
518
+ readonly ORB_QUERY_MISSING_RECOMMENDED: "ORB_QUERY_MISSING_RECOMMENDED";
519
+ readonly ORB_QUERY_MISSING_SEARCH: "ORB_QUERY_MISSING_SEARCH";
520
+ readonly ORB_QUERY_UNKNOWN_SINGLETON: "ORB_QUERY_UNKNOWN_SINGLETON";
521
+ readonly ORB_QUERY_UNSUPPORTED_PATTERN: "ORB_QUERY_UNSUPPORTED_PATTERN";
522
+ readonly ORB_QUERY_UNUSED_SINGLETON: "ORB_QUERY_UNUSED_SINGLETON";
523
+ readonly ORB_RUI_BINDING_TYPE_MISMATCH: "ORB_RUI_BINDING_TYPE_MISMATCH";
524
+ readonly ORB_RUI_ELEMENT_SHAPE_MISMATCH: "ORB_RUI_ELEMENT_SHAPE_MISMATCH";
525
+ readonly ORB_RUI_EVENT_BINDING_PAYLOAD_MISMATCH: "ORB_RUI_EVENT_BINDING_PAYLOAD_MISMATCH";
526
+ readonly ORB_RUI_INVALID_FIELD_PATH: "ORB_RUI_INVALID_FIELD_PATH";
527
+ readonly ORB_RUI_INVALID_ITEM_ACTION: "ORB_RUI_INVALID_ITEM_ACTION";
528
+ readonly ORB_RUI_INVALID_PATTERN: "ORB_RUI_INVALID_PATTERN";
529
+ readonly ORB_RUI_INVALID_PROP: "ORB_RUI_INVALID_PROP";
530
+ readonly ORB_RUI_INVALID_SLOT: "ORB_RUI_INVALID_SLOT";
531
+ readonly ORB_RUI_MISSING_ACTION: "ORB_RUI_MISSING_ACTION";
532
+ readonly ORB_RUI_MISSING_PATTERN_TYPE: "ORB_RUI_MISSING_PATTERN_TYPE";
533
+ readonly ORB_RUI_MISSING_REQUIRED_PROP: "ORB_RUI_MISSING_REQUIRED_PROP";
534
+ readonly ORB_RUI_PROP_TYPE_MISMATCH: "ORB_RUI_PROP_TYPE_MISMATCH";
535
+ readonly ORB_RUI_UNKNOWN_ITEM_ACTION_PROP: "ORB_RUI_UNKNOWN_ITEM_ACTION_PROP";
536
+ readonly ORB_S_EMPTY_VERSION: "ORB_S_EMPTY_VERSION";
537
+ readonly ORB_S_MISSING_NAME: "ORB_S_MISSING_NAME";
538
+ readonly ORB_S_NO_ORBITALS: "ORB_S_NO_ORBITALS";
539
+ readonly ORB_SLOT_CONTENTION: "ORB_SLOT_CONTENTION";
540
+ readonly ORB_SLOT_CONTENTION_RUNTIME: "ORB_SLOT_CONTENTION_RUNTIME";
541
+ readonly ORB_SLOT_HUD_NON_GAME: "ORB_SLOT_HUD_NON_GAME";
542
+ readonly ORB_SLOT_INVALID_NAME: "ORB_SLOT_INVALID_NAME";
543
+ readonly ORB_SLOT_INVALID_NESTING: "ORB_SLOT_INVALID_NESTING";
544
+ readonly ORB_SLOT_MAIN_NOT_COVERED: "ORB_SLOT_MAIN_NOT_COVERED";
545
+ readonly ORB_SLOT_PRIORITY_CONFLICT: "ORB_SLOT_PRIORITY_CONFLICT";
546
+ readonly ORB_SVC_DUPLICATE_NAME: "ORB_SVC_DUPLICATE_NAME";
547
+ readonly ORB_SVC_INVALID_INTEGRATOR: "ORB_SVC_INVALID_INTEGRATOR";
548
+ readonly ORB_SVC_INVALID_URL: "ORB_SVC_INVALID_URL";
549
+ readonly ORB_SVC_MISSING_BASE_URL: "ORB_SVC_MISSING_BASE_URL";
550
+ readonly ORB_SVC_MISSING_CAPABILITIES: "ORB_SVC_MISSING_CAPABILITIES";
551
+ readonly ORB_SVC_MISSING_EVENTS: "ORB_SVC_MISSING_EVENTS";
552
+ readonly ORB_SVC_MISSING_SERVER_PATH: "ORB_SVC_MISSING_SERVER_PATH";
553
+ readonly ORB_SVC_RESERVED_EVENT: "ORB_SVC_RESERVED_EVENT";
554
+ readonly ORB_SVC_UNKNOWN_TYPE: "ORB_SVC_UNKNOWN_TYPE";
555
+ readonly ORB_T_CONFIG_OBJECT_ARRAY_FORBIDDEN: "ORB_T_CONFIG_OBJECT_ARRAY_FORBIDDEN";
556
+ readonly ORB_T_CONFIG_SHAPE_MISMATCH: "ORB_T_CONFIG_SHAPE_MISMATCH";
557
+ readonly ORB_T_CONFIG_TIER_INVALID: "ORB_T_CONFIG_TIER_INVALID";
558
+ readonly ORB_T_DEPRECATED_UI: "ORB_T_DEPRECATED_UI";
559
+ readonly ORB_T_DUPLICATE_NAME: "ORB_T_DUPLICATE_NAME";
560
+ readonly ORB_T_DUPLICATE_STATE: "ORB_T_DUPLICATE_STATE";
561
+ readonly ORB_T_DUPLICATE_TRANSITION: "ORB_T_DUPLICATE_TRANSITION";
562
+ readonly ORB_T_ENTITY_NAME_SHADOWS_TRAIT_UNION: "ORB_T_ENTITY_NAME_SHADOWS_TRAIT_UNION";
563
+ readonly ORB_T_EVENT_TYPE_WRONG_KIND: "ORB_T_EVENT_TYPE_WRONG_KIND";
564
+ readonly ORB_T_EVT_DUPLICATE: "ORB_T_EVT_DUPLICATE";
565
+ readonly ORB_T_EVT_EXTERNAL_MISSING_PAYLOAD: "ORB_T_EVT_EXTERNAL_MISSING_PAYLOAD";
566
+ readonly ORB_T_EVT_INVALID_NAME: "ORB_T_EVT_INVALID_NAME";
567
+ readonly ORB_T_EVT_SCOPE_MISMATCH: "ORB_T_EVT_SCOPE_MISMATCH";
568
+ readonly ORB_T_EVT_TICK_UNDECLARED: "ORB_T_EVT_TICK_UNDECLARED";
569
+ readonly ORB_T_EVT_UNDECLARED: "ORB_T_EVT_UNDECLARED";
570
+ readonly ORB_T_INIT_MISSING_FETCH: "ORB_T_INIT_MISSING_FETCH";
571
+ readonly ORB_T_INVALID_CATEGORY: "ORB_T_INVALID_CATEGORY";
572
+ readonly ORB_T_INVALID_FORMAT: "ORB_T_INVALID_FORMAT";
573
+ readonly ORB_T_INVALID_PATTERN_DEFAULT: "ORB_T_INVALID_PATTERN_DEFAULT";
574
+ readonly ORB_T_INVALID_SLOT_DEFAULT: "ORB_T_INVALID_SLOT_DEFAULT";
575
+ readonly ORB_T_INVALID_TRANSITION: "ORB_T_INVALID_TRANSITION";
576
+ readonly ORB_T_MISSING_INIT_TRANSITION: "ORB_T_MISSING_INIT_TRANSITION";
577
+ readonly ORB_T_MISSING_RENDER_UI: "ORB_T_MISSING_RENDER_UI";
578
+ readonly ORB_T_MULTIPLE_INITIAL_STATES: "ORB_T_MULTIPLE_INITIAL_STATES";
579
+ readonly ORB_T_NO_INITIAL_STATE: "ORB_T_NO_INITIAL_STATE";
580
+ readonly ORB_T_TYPE_ANNOTATION_MISMATCH: "ORB_T_TYPE_ANNOTATION_MISMATCH";
581
+ readonly ORB_T_TYPE_COMPOSITION_CONFLICT: "ORB_T_TYPE_COMPOSITION_CONFLICT";
582
+ readonly ORB_T_TYPE_CYCLE: "ORB_T_TYPE_CYCLE";
583
+ readonly ORB_T_TYPE_KIND_MISMATCH: "ORB_T_TYPE_KIND_MISMATCH";
584
+ readonly ORB_T_TYPE_UNKNOWN: "ORB_T_TYPE_UNKNOWN";
585
+ readonly ORB_T_TYPE_UNKNOWN_PARAM: "ORB_T_TYPE_UNKNOWN_PARAM";
586
+ readonly ORB_T_TYPE_WRONG_ARG_COUNT: "ORB_T_TYPE_WRONG_ARG_COUNT";
587
+ readonly ORB_T_UNDEFINED_EVENT: "ORB_T_UNDEFINED_EVENT";
588
+ readonly ORB_T_UNDEFINED_TRAIT: "ORB_T_UNDEFINED_TRAIT";
589
+ readonly ORB_UI_ICON_EMPTY: "ORB_UI_ICON_EMPTY";
590
+ readonly ORB_UI_ICON_INVALID_FORMAT: "ORB_UI_ICON_INVALID_FORMAT";
591
+ readonly ORB_UI_ICON_NOT_FOUND: "ORB_UI_ICON_NOT_FOUND";
592
+ readonly ORB_X_CIRCULAR_DEPENDENCY: "ORB_X_CIRCULAR_DEPENDENCY";
593
+ readonly ORB_X_CROSS_EMITTER_DECLARED_PAYLOAD_MISMATCH: "ORB_X_CROSS_EMITTER_DECLARED_PAYLOAD_MISMATCH";
594
+ readonly ORB_X_DUPLICATE_ENTITY: "ORB_X_DUPLICATE_ENTITY";
595
+ readonly ORB_X_EVENT_COLLISION: "ORB_X_EVENT_COLLISION";
596
+ readonly ORB_X_INTERNAL_EVENT_EXPOSED: "ORB_X_INTERNAL_EVENT_EXPOSED";
597
+ readonly ORB_X_LISTEN_SOURCE_UNRESOLVED: "ORB_X_LISTEN_SOURCE_UNRESOLVED";
598
+ readonly ORB_X_MISSING_ORBITAL_NAME: "ORB_X_MISSING_ORBITAL_NAME";
599
+ readonly ORB_X_ORPHAN_LISTENER: "ORB_X_ORPHAN_LISTENER";
600
+ readonly ORB_X_PAYLOAD_MISMATCH: "ORB_X_PAYLOAD_MISMATCH";
601
+ readonly ORB_X_RENDER_UI_EVENT_LITERAL_STALE: "ORB_X_RENDER_UI_EVENT_LITERAL_STALE";
602
+ readonly ORB_X_UNRESOLVED_PATTERN_FIELD_REF: "ORB_X_UNRESOLVED_PATTERN_FIELD_REF";
603
+ readonly ORB_X_UNUSED_EMISSION: "ORB_X_UNUSED_EMISSION";
604
+ readonly ORB_ID_UNKNOWN_REF: "ORB_ID_UNKNOWN_REF";
605
+ readonly ORB_ID_NAME_MISMATCH: "ORB_ID_NAME_MISMATCH";
606
+ readonly ORB_ID_KIND_MISMATCH: "ORB_ID_KIND_MISMATCH";
607
+ readonly ORB_ID_LEDGER_ORPHAN: "ORB_ID_LEDGER_ORPHAN";
608
+ };
609
+ /**
610
+ * Narrow union of the codes documented in `KNOWN_VALIDATION_ERROR_CODES`.
611
+ * Use this in exhaustive `switch` handlers; use the broader
612
+ * `ValidationErrorCode` (open `string`) anywhere a fresh validator-side
613
+ * code could plausibly arrive.
614
+ */
615
+ type KnownValidationErrorCode = typeof KNOWN_VALIDATION_ERROR_CODES[keyof typeof KNOWN_VALIDATION_ERROR_CODES];
616
+ /**
617
+ * Type guard: is the given code a known one? After the guard returns
618
+ * true, the code can be narrowed to `KnownValidationErrorCode` via a
619
+ * separate cast, because the type system can't track `in` against
620
+ * `as const` records without an explicit narrowing helper.
621
+ */
622
+ declare function isKnownValidationErrorCode(code: ValidationErrorCode): boolean;
623
+
624
+ /**
625
+ * Plan & Analysis Types
626
+ *
627
+ * Lifted from @almadar-io/rabit's coordinator types. These are the
628
+ * language-level contracts for the planner/analysis pipeline — the
629
+ * session/* and workspace/* substrate operators produce and consume
630
+ * these shapes. Defined here (not in rabit) so both the compiled path
631
+ * (orbital-rust codegen → @almadar/server) and the interpreted path
632
+ * (@almadar/runtime) reference the same types without depending on rabit.
633
+ *
634
+ * @packageDocumentation
635
+ */
636
+
637
+ type ClarificationLevel = 'organism' | 'molecule' | 'atom_trait';
638
+ interface ClarificationCandidate {
639
+ id: string;
640
+ label: string;
641
+ description: string;
642
+ whyThisFits: string;
643
+ }
644
+ interface Clarification {
645
+ level: ClarificationLevel;
646
+ scope: {
647
+ orbitalName?: string;
648
+ traitName?: string;
649
+ };
650
+ question: string;
651
+ candidates: ClarificationCandidate[];
652
+ skipDefault: string;
653
+ skippable: true;
654
+ }
655
+ interface AnalysisPageOverride {
656
+ name: string;
657
+ path?: string;
658
+ linkedEntity?: string;
659
+ traits?: PageTraitRef[];
660
+ }
661
+ interface ExtraTraitRef extends Pick<TraitReference, 'ref' | 'name' | 'linkedEntity' | 'config' | 'events' | 'listens' | 'emitsScope'> {
662
+ from: string;
663
+ as: string;
664
+ }
665
+ interface AnalysisOrbitalParams {
666
+ fields?: EntityField[];
667
+ pagePath?: string;
668
+ persistence?: EntityPersistence;
669
+ entityName?: string;
670
+ collection?: string;
671
+ traitOverrides?: Record<string, Pick<MakeTraitRefOpts, 'config' | 'linkedEntity' | 'events' | 'name' | 'emitsScope' | 'listens'>>;
672
+ extraTraits?: ExtraTraitRef[];
673
+ pages?: AnalysisPageOverride[];
674
+ }
675
+ interface AnalysisOrbital {
676
+ orbitalName: string;
677
+ suggestedBehavior: string | null;
678
+ entityName?: string;
679
+ pageNames?: ReadonlyArray<string>;
680
+ params?: AnalysisOrbitalParams;
681
+ traitOverlay?: TraitOverlay;
682
+ paletteTopics?: string[];
683
+ primitiveHints?: string[];
684
+ }
685
+ interface AnalysisRename {
686
+ oldName: string;
687
+ newName: string;
688
+ }
689
+ interface ComplexityAssessment {
690
+ score: number;
691
+ category: 'simple' | 'moderate' | 'complex';
692
+ reasoning: string;
693
+ detectedEntities?: string[];
694
+ detectedFeatures?: string[];
695
+ }
696
+ interface AnalysisResult {
697
+ userRequest: string;
698
+ complexity: ComplexityAssessment;
699
+ route: 'direct' | 'direct_with_questions' | 'decompose';
700
+ organism: string;
701
+ appName: string;
702
+ organismReason: string;
703
+ orbitals: AnalysisOrbital[];
704
+ renames?: AnalysisRename[];
705
+ deletedOrbitals?: string[];
706
+ ruleOverlay?: RuleOverlay;
707
+ estimatedMinutes?: number;
708
+ schema: OrbitalSchema;
709
+ wiring?: EventWiringEntry[];
710
+ layout?: LayoutStrategy | 'detect';
711
+ themeOverrides?: Partial<ThemeDefinition>;
712
+ pendingClarifications?: Clarification[];
713
+ }
714
+ interface SpawnResult {
715
+ orbitalName: string;
716
+ ok: boolean;
717
+ traitNames: ReadonlyArray<string>;
718
+ error?: string;
719
+ durationMs: number;
720
+ }
721
+ type PlanSnapshotStatus = 'proposed' | 'confirmed' | 'built' | 'failed';
722
+ interface PlanSnapshot {
723
+ schemaVersion: 1;
724
+ status: PlanSnapshotStatus;
725
+ builtAt: string;
726
+ organism: string | null;
727
+ appName: string | null;
728
+ organismReason: string | null;
729
+ complexity: ComplexityAssessment | null;
730
+ themeOverrides: Partial<ThemeDefinition>;
731
+ ruleOverlay: RuleOverlay | null;
732
+ orbitals: ReadonlyArray<AnalysisOrbital>;
733
+ renames: ReadonlyArray<AnalysisRename>;
734
+ deletedOrbitals: ReadonlyArray<string>;
735
+ priorBuiltOrbitals: ReadonlyArray<AnalysisOrbital>;
736
+ spawnedOrbitalResults: ReadonlyArray<SpawnResult>;
737
+ skippedOrbitalNames: ReadonlyArray<string>;
738
+ pendingClarifications: ReadonlyArray<Clarification>;
739
+ paletteTopics?: string[];
740
+ }
741
+ /**
742
+ * Runtime guard for `PlanSnapshot` — narrows interpreter-produced `unknown`
743
+ * values at the `WorkspaceContext.writePlan` boundary. Discriminates on the
744
+ * snapshot envelope (schemaVersion, status, roster arrays), not deep contents.
745
+ */
746
+ declare function isPlanSnapshot(value: RuntimeValue): value is PlanSnapshot;
747
+ interface ComposeOptions {
748
+ appName?: string;
749
+ wiring?: EventWiringEntry[];
750
+ layout?: LayoutStrategy | 'auto';
751
+ themeOverrides?: Partial<ThemeDefinition>;
752
+ }
753
+ interface GitHubRepo {
754
+ id: number;
755
+ name: string;
756
+ full_name: string;
757
+ owner: {
758
+ login: string;
759
+ };
760
+ private: boolean;
761
+ html_url: string;
762
+ description: string | null;
763
+ default_branch: string;
764
+ clone_url: string;
765
+ }
766
+ interface GitHubIssue {
767
+ id: number;
768
+ number: number;
769
+ title: string;
770
+ body: string | null;
771
+ state: 'open' | 'closed';
772
+ html_url: string;
773
+ user: {
774
+ login: string;
775
+ };
776
+ created_at: string;
777
+ updated_at: string;
778
+ }
779
+
780
+ /**
781
+ * Agent Types
782
+ *
783
+ * Defines the AgentContext interface and related types for the agent/* operator namespace.
784
+ * These types are the contract between operators (language) and implementation (runtime).
785
+ *
786
+ * @packageDocumentation
787
+ */
788
+
789
+ /**
790
+ * Categories for agent memories.
791
+ */
792
+ type AgentMemoryCategory = 'preference' | 'correction' | 'pattern-affinity' | 'entity-template' | 'error-resolution';
793
+ /**
794
+ * A single memory record stored by the agent.
795
+ */
796
+ interface AgentMemoryRecord {
797
+ /** Unique memory identifier */
798
+ id: string;
799
+ /** Memory content (natural language) */
800
+ content: string;
801
+ /** Memory category */
802
+ category: AgentMemoryCategory;
803
+ /** Strength value (0.0-1.0), decays over time unless pinned */
804
+ strength: number;
805
+ /** Whether this memory is pinned (immune to decay) */
806
+ pinned: boolean;
807
+ /** Memory scope */
808
+ scope: 'global' | 'project';
809
+ /** ISO timestamp of last access */
810
+ lastAccessedAt: string;
811
+ /** ISO timestamp of creation */
812
+ createdAt: string;
813
+ }
814
+ /**
815
+ * Strategy for context compaction.
816
+ */
817
+ type AgentCompactStrategy = 'hybrid' | 'summarize' | 'truncate' | 'extract';
818
+ /**
819
+ * Result of a context compaction operation.
820
+ */
821
+ interface AgentCompactResult {
822
+ /** Token count before compaction */
823
+ before: number;
824
+ /** Token count after compaction */
825
+ after: number;
826
+ /** Strategy used */
827
+ strategy: AgentCompactStrategy;
828
+ /** Optional summary generated during compaction */
829
+ summary?: string;
830
+ }
831
+ /**
832
+ * Options for agent/generate calls.
833
+ */
834
+ interface AgentGenerateOptions {
835
+ /** LLM provider override */
836
+ provider?: string;
837
+ /** Model override */
838
+ model?: string;
839
+ /** Maximum tokens to generate */
840
+ maxTokens?: number;
841
+ }
842
+ /**
843
+ * A message in an LLM tool-calling conversation.
844
+ */
845
+ interface LlmMessage {
846
+ role: 'system' | 'user' | 'assistant' | 'tool';
847
+ content: string;
848
+ /** Present on assistant messages that called tools. */
849
+ toolCalls?: ReadonlyArray<LlmToolCall>;
850
+ /** Present on tool-role messages — matches the preceding toolCall's id. */
851
+ toolCallId?: string;
852
+ }
853
+ /**
854
+ * A tool call requested by the assistant.
855
+ */
856
+ interface LlmToolCall {
857
+ id: string;
858
+ name: string;
859
+ /** JSON-encoded arguments string (as returned by the LLM). */
860
+ arguments: string;
861
+ }
862
+ /**
863
+ * A tool definition passed to llm/call-tools.
864
+ */
865
+ interface LlmToolDef {
866
+ name: string;
867
+ description: string;
868
+ /** JSON Schema describing the tool's parameters. */
869
+ parameters: JsonSchema;
870
+ }
871
+ /**
872
+ * Result of llm/call-tools.
873
+ */
874
+ interface LlmCallToolsResult {
875
+ /** The assistant's text response (may be empty when only tool_calls fired). */
876
+ content: string;
877
+ /** Tool calls the assistant requested, if any. */
878
+ toolCalls?: ReadonlyArray<LlmToolCall>;
879
+ /** Token usage from the call. */
880
+ usage: LlmTokenUsage;
881
+ }
882
+ /**
883
+ * Token usage from an LLM call.
884
+ */
885
+ interface LlmTokenUsage {
886
+ prompt: number;
887
+ completion: number;
888
+ total: number;
889
+ }
890
+ /**
891
+ * Result from agent/search-code.
892
+ */
893
+ interface AgentCodeSearchResult {
894
+ /** Repository name (owner/repo) */
895
+ repo: string;
896
+ /** File path within the repository */
897
+ path: string;
898
+ /** URL to the file */
899
+ url: string;
900
+ }
901
+ /** Result of behavior/instantiate (factory path) or subagent build. */
902
+ interface BuilderResult {
903
+ method: string;
904
+ orbitalName: string;
905
+ success: boolean;
906
+ orbitalPath?: string;
907
+ traitCount?: number;
908
+ traitNames?: string[];
909
+ transitionCount?: number;
910
+ childCount?: number;
911
+ error?: string;
912
+ }
913
+ /** Result of validate/validate for a single orbital or the composed schema. */
914
+ interface ValidateResult {
915
+ valid: boolean;
916
+ errorCount: number;
917
+ errors: ValidationError[];
918
+ orbitalName?: string;
919
+ }
920
+ /** Result of compose/compose-all. */
921
+ interface ComposeAllResult {
922
+ orbitalCount: number;
923
+ composedPath: string;
924
+ success: boolean;
925
+ layout?: string;
926
+ wiringConnections?: number;
927
+ }
928
+ /** Result of compose/compose-children (recursive builds). */
929
+ interface ComposeChildrenResult {
930
+ parentName: string;
931
+ childCount: number;
932
+ orbitalName: string;
933
+ success: boolean;
934
+ }
935
+ /** Result of the repair service. */
936
+ interface RepairResult {
937
+ orbitalName: string;
938
+ success: boolean;
939
+ attempt: number;
940
+ paramsChanged: boolean;
941
+ error?: string;
942
+ }
943
+ /** Result of lolo/emit-body (free-lolo path). */
944
+ interface LoloEmitResult {
945
+ orbitalName: string;
946
+ success: boolean;
947
+ loloSource: string;
948
+ error?: string;
949
+ }
950
+ /** Result of the planner service. */
951
+ interface PlannerResult {
952
+ organism: string;
953
+ operationCount: number;
954
+ pendingQuestions: boolean;
955
+ cached: boolean;
956
+ success: boolean;
957
+ error?: string;
958
+ }
959
+ /** Result of the executor (spawn-subagents). */
960
+ interface ExecutePlanResult {
961
+ dispatchedOrbitals: string[];
962
+ noopForBuild: boolean;
963
+ success: boolean;
964
+ error?: string;
965
+ }
966
+ /** Result of dispatch-updates. */
967
+ interface DispatchUpdatesResult {
968
+ updatedOrbitals: string[];
969
+ updateCount: number;
970
+ success: boolean;
971
+ }
972
+ /** Discriminated union of all substrate service-call results. */
973
+ type ServiceCallResult = BuilderResult | ValidateResult | ComposeAllResult | ComposeChildrenResult | RepairResult | LoloEmitResult | PlannerResult | ExecutePlanResult | DispatchUpdatesResult;
974
+ /** A single entry in an orbital's session history (build/conversation log). */
975
+ interface SessionHistoryEntry {
976
+ /** Role of the entry's author (e.g. 'user', 'assistant', 'system') */
977
+ role: string;
978
+ /** Entry content (natural language or structured description) */
979
+ content: string;
980
+ /** Epoch milliseconds when the entry was recorded */
981
+ timestamp: number;
982
+ }
983
+ /**
984
+ * Runtime guard for `SessionHistoryEntry` — narrows interpreter-produced
985
+ * `unknown` values at the `SessionContext.appendHistory` boundary.
986
+ */
987
+ declare function isSessionHistoryEntry(value: RuntimeValue): value is SessionHistoryEntry;
988
+ /**
989
+ * AgentContext is the runtime contract for agent/* operators.
990
+ *
991
+ * The evaluator dispatches agent/* operators to methods on this interface.
992
+ * Pure methods (usable in guards) return synchronously.
993
+ * Effect methods return Promises.
994
+ *
995
+ * When ctx.agent is undefined, operators return safe defaults ([], 0, false, "").
996
+ * Implementations live in @almadar-io/agent-runtime (Phase 2B).
997
+ */
998
+ interface AgentContext {
999
+ recall(query: string, limit?: number): AgentMemoryRecord[];
1000
+ memories(category?: AgentMemoryCategory): AgentMemoryRecord[];
1001
+ memoryStrength(id: string): number;
1002
+ isPinned(id: string): boolean;
1003
+ memorize(content: string, category: AgentMemoryCategory, scope?: 'global' | 'project'): Promise<string>;
1004
+ forget(id: string): Promise<void>;
1005
+ pin(id: string): Promise<void>;
1006
+ reinforce(id: string): Promise<void>;
1007
+ decay(): Promise<number>;
1008
+ provider(): string;
1009
+ model(): string;
1010
+ generate(prompt: string, options?: AgentGenerateOptions): Promise<string>;
1011
+ switchProvider(provider: string, model?: string): void;
1012
+ tools(): string[];
1013
+ invoke(toolName: string, args: ServiceParams): Promise<EventPayloadValue>;
1014
+ tokenCount(): number;
1015
+ contextUsage(): number;
1016
+ compact(strategy?: AgentCompactStrategy): Promise<AgentCompactResult>;
1017
+ sessionId(): string;
1018
+ fork(label?: string): Promise<string>;
1019
+ label(text: string): void;
1020
+ searchCode(query: string, language?: string): Promise<AgentCodeSearchResult[]>;
1021
+ }
1022
+ /** Backs the llm/* operators (6 ops). */
1023
+ interface LlmContext {
1024
+ generate(prompt: string, options?: {
1025
+ json?: boolean;
1026
+ maxTokens?: number;
1027
+ provider?: string;
1028
+ model?: string;
1029
+ }): Promise<string>;
1030
+ callTools(messages: LlmMessage[], tools: LlmToolDef[]): Promise<LlmCallToolsResult>;
1031
+ embed(texts: string[]): Promise<number[][]>;
1032
+ tokenCount(): number;
1033
+ switchProvider(provider: string, model?: string): void;
1034
+ compact(strategy?: string): Promise<{
1035
+ before: number;
1036
+ after: number;
1037
+ }>;
1038
+ }
1039
+ /** Backs the workspace/* operators (11 ops). */
1040
+ interface WorkspaceContext {
1041
+ readOrbital(name: string): Promise<Orbital>;
1042
+ writeOrbital(name: string, content: Orbital): Promise<void>;
1043
+ readFile(path: string): Promise<string>;
1044
+ writeFile(path: string, content: string): Promise<void>;
1045
+ exists(path: string): boolean;
1046
+ listOrbitals(): string[];
1047
+ readSchema(): Promise<OrbitalSchema>;
1048
+ writeSchema(schema: OrbitalSchema): Promise<void>;
1049
+ readPlan(): Promise<PlanSnapshot>;
1050
+ writePlan(plan: PlanSnapshot): Promise<void>;
1051
+ archiveOrbital(name: string): Promise<void>;
1052
+ }
1053
+ /** Backs the session/* operators (9 ops). */
1054
+ interface SessionContext {
1055
+ readSpec(orbitalName: string): Promise<Orbital>;
1056
+ writeSpec(orbitalName: string, spec: Orbital): Promise<void>;
1057
+ readMemory(orbitalName: string): Promise<AgentMemoryRecord[]>;
1058
+ writeMemory(orbitalName: string, memory: AgentMemoryRecord[]): Promise<void>;
1059
+ readHistory(orbitalName: string): Promise<SessionHistoryEntry[]>;
1060
+ appendHistory(orbitalName: string, entry: SessionHistoryEntry): Promise<void>;
1061
+ readErrors(orbitalName: string): Promise<string[]>;
1062
+ writeErrors(orbitalName: string, errors: string[]): Promise<void>;
1063
+ readAnalysis(orbitalName: string): Promise<AnalysisResult>;
1064
+ }
1065
+ /** Backs the memory/* operators (3 ops). */
1066
+ interface MemoryContext {
1067
+ recall(query: string, limit?: number): AgentMemoryRecord[];
1068
+ store(content: string, category?: string, strength?: number): Promise<string>;
1069
+ list(category?: string): AgentMemoryRecord[];
1070
+ }
1071
+ /** Backs the trace/* operators (2 ops). */
1072
+ interface TraceContext {
1073
+ emit(event: string, payload?: EventPayloadValue): void;
1074
+ log(message: string, level?: 'log' | 'warn' | 'error', data?: EventPayloadValue): void;
1075
+ }
1076
+ /** Backs the integration/* operators (3 ops). */
1077
+ interface IntegrationContext {
1078
+ http(method: string, url: string, body?: FieldValue, headers?: Record<string, string>): Promise<JsonValue>;
1079
+ githubGetRepo(owner: string, repo: string): Promise<GitHubRepo>;
1080
+ githubCreateIssue(owner: string, repo: string, title: string, body?: string): Promise<GitHubIssue>;
1081
+ }
1082
+
1083
+ /**
1084
+ * Interaction Model Types
1085
+ *
1086
+ * Defines how users interact with entities in the application.
1087
+ * Used to drive trait selection and UI slot usage.
1088
+ *
1089
+ * @packageDocumentation
1090
+ */
1091
+
1092
+ /**
1093
+ * Create flow - how new items are created
1094
+ */
1095
+ type CreateFlow = 'modal' | 'page' | 'inline' | 'none';
1096
+ /**
1097
+ * Edit flow - how items are edited
1098
+ */
1099
+ type EditFlow = 'modal' | 'page' | 'inline' | 'none';
1100
+ /**
1101
+ * View flow - how item details are viewed
1102
+ */
1103
+ type ViewFlow = 'drawer' | 'page' | 'modal' | 'inline' | 'none';
1104
+ /**
1105
+ * Delete flow - how items are deleted
1106
+ */
1107
+ type DeleteFlow = 'confirm' | 'instant' | 'none';
1108
+ /**
1109
+ * List interaction - what happens when clicking list items
1110
+ */
1111
+ type ListInteraction = 'click-to-view' | 'click-to-edit' | 'inline-edit';
1112
+ /**
1113
+ * InteractionModel - defines how users interact with entities.
1114
+ *
1115
+ * This drives:
1116
+ * - Which traits to attach (EntityManagement, ModalEdit, etc.)
1117
+ * - How render_ui effects target slots (modal, drawer, page)
1118
+ * - What UI patterns to use
1119
+ */
1120
+ interface InteractionModel {
1121
+ /** How new items are created */
1122
+ createFlow: CreateFlow;
1123
+ /** How items are edited */
1124
+ editFlow: EditFlow;
1125
+ /** How item details are viewed */
1126
+ viewFlow: ViewFlow;
1127
+ /** How items are deleted */
1128
+ deleteFlow: DeleteFlow;
1129
+ /** What happens when clicking list items */
1130
+ listInteraction?: ListInteraction;
1131
+ /** Enable bulk actions (select multiple, delete all) */
1132
+ bulkActions?: boolean;
1133
+ /** Enable real-time updates */
1134
+ realtime?: boolean;
1135
+ }
1136
+ declare const InteractionModelSchema: z.ZodObject<{
1137
+ createFlow: z.ZodEnum<["modal", "page", "inline", "none"]>;
1138
+ editFlow: z.ZodEnum<["modal", "page", "inline", "none"]>;
1139
+ viewFlow: z.ZodEnum<["drawer", "page", "modal", "inline", "none"]>;
1140
+ deleteFlow: z.ZodEnum<["confirm", "instant", "none"]>;
1141
+ listInteraction: z.ZodOptional<z.ZodEnum<["click-to-view", "click-to-edit", "inline-edit"]>>;
1142
+ bulkActions: z.ZodOptional<z.ZodBoolean>;
1143
+ realtime: z.ZodOptional<z.ZodBoolean>;
1144
+ }, "strip", z.ZodTypeAny, {
1145
+ createFlow: "page" | "none" | "inline" | "modal";
1146
+ editFlow: "page" | "none" | "inline" | "modal";
1147
+ viewFlow: "page" | "none" | "inline" | "modal" | "drawer";
1148
+ deleteFlow: "none" | "instant" | "confirm";
1149
+ bulkActions?: boolean | undefined;
1150
+ listInteraction?: "click-to-view" | "click-to-edit" | "inline-edit" | undefined;
1151
+ realtime?: boolean | undefined;
1152
+ }, {
1153
+ createFlow: "page" | "none" | "inline" | "modal";
1154
+ editFlow: "page" | "none" | "inline" | "modal";
1155
+ viewFlow: "page" | "none" | "inline" | "modal" | "drawer";
1156
+ deleteFlow: "none" | "instant" | "confirm";
1157
+ bulkActions?: boolean | undefined;
1158
+ listInteraction?: "click-to-view" | "click-to-edit" | "inline-edit" | undefined;
1159
+ realtime?: boolean | undefined;
1160
+ }>;
1161
+ /**
1162
+ * Default interaction models for each domain type
1163
+ */
1164
+ declare const DEFAULT_INTERACTION_MODELS: Record<string, InteractionModel>;
1165
+ /**
1166
+ * Gets the interaction model for a domain.
1167
+ *
1168
+ * Retrieves the appropriate interaction model configuration based on the
1169
+ * specified domain. Falls back to the business model if no specific
1170
+ * domain match is found.
1171
+ *
1172
+ * @param {string} domain - Domain name (e.g., 'healthcare', 'education')
1173
+ * @returns {InteractionModel} Interaction model configuration
1174
+ *
1175
+ * @example
1176
+ * getInteractionModelForDomain('healthcare'); // returns healthcare-specific model
1177
+ * getInteractionModelForDomain('unknown'); // returns business fallback model
1178
+ */
1179
+ declare function getInteractionModelForDomain(domain: string): InteractionModel;
1180
+ type InteractionModelInput = z.input<typeof InteractionModelSchema>;
1181
+
1182
+ /**
1183
+ * Pattern Type for Orbital Units
1184
+ *
1185
+ * Re-exports pattern type definitions from @almadar/core/patterns,
1186
+ * which is the single source of truth for all pattern types.
1187
+ *
1188
+ * @packageDocumentation
1189
+ */
1190
+
1191
+ /**
1192
+ * Zod schema for pattern types.
1193
+ * Accepts any string - validation against full registry happens at runtime.
1194
+ */
1195
+ declare const PatternTypeSchema: z.ZodString;
1196
+
1197
+ /**
1198
+ * Changeset & Snapshot Types
1199
+ *
1200
+ * Unified types for schema change tracking, snapshots, and removal categorization.
1201
+ * Used by @almadar/server for Firestore storage and by consumers for type safety.
1202
+ */
1203
+
1204
+ /**
1205
+ * Value attached to a SchemaChange entry's `before` / `after`.
1206
+ *
1207
+ * Either a JSON-shaped LLM payload (`EventPayloadValue`), a single schema
1208
+ * fragment (`Orbital`, `Trait`, `Entity`, `Page`, `OrbitalSchema`), or an
1209
+ * array of such fragments. Mirrors the exact shapes the builder's changeset
1210
+ * writers actually persist when adding/replacing a slice of the schema.
1211
+ */
1212
+ type ChangesetValue = EventPayloadValue | OrbitalSchema | Orbital | Trait | Entity | Page | Orbital[] | Trait[] | Entity[] | Page[];
1213
+ /**
1214
+ * A single change within a changeset.
1215
+ */
1216
+ interface SchemaChange {
1217
+ id: string;
1218
+ operation: 'add' | 'modify' | 'remove' | 'rename';
1219
+ target: string;
1220
+ path: (string | number)[];
1221
+ before?: ChangesetValue;
1222
+ after?: ChangesetValue;
1223
+ description: string;
1224
+ reason?: string;
1225
+ dependsOn?: string[];
1226
+ }
1227
+ /**
1228
+ * Author of a changeset.
1229
+ */
1230
+ interface ChangeAuthor {
1231
+ type: 'agent' | 'user';
1232
+ id?: string;
1233
+ name?: string;
1234
+ }
1235
+ /**
1236
+ * Summary statistics for a changeset.
1237
+ */
1238
+ interface ChangeSummary {
1239
+ added: number;
1240
+ modified: number;
1241
+ removed: number;
1242
+ description: string;
1243
+ }
1244
+ /**
1245
+ * Complete changeset document.
1246
+ * Stored at: users/{uid}/apps/{appId}/changesets/{changeSetId}
1247
+ */
1248
+ interface ChangeSetDocument {
1249
+ id: string;
1250
+ version: number;
1251
+ timestamp: number;
1252
+ source: 'requirements-agent' | 'builder-agent' | 'user' | 'auto-fix';
1253
+ author: ChangeAuthor;
1254
+ trigger?: string;
1255
+ changes: SchemaChange[];
1256
+ summary: ChangeSummary;
1257
+ status: 'applied' | 'reverted' | 'pending';
1258
+ description: string;
1259
+ }
1260
+ /**
1261
+ * Schema snapshot document.
1262
+ * Stored at: users/{uid}/apps/{appId}/snapshots/{snapshotId}
1263
+ */
1264
+ interface SnapshotDocument {
1265
+ id: string;
1266
+ timestamp: number;
1267
+ schema: OrbitalSchema;
1268
+ reason: string;
1269
+ version?: number;
1270
+ }
1271
+ /**
1272
+ * Removals categorized by severity.
1273
+ */
1274
+ interface CategorizedRemovals {
1275
+ /** States, pages, entities — always require confirmation */
1276
+ critical: SchemaChange[];
1277
+ /** Fields, actions — auto-snapshotted */
1278
+ standard: SchemaChange[];
1279
+ /** Transitions, guards — tracked */
1280
+ minor: SchemaChange[];
1281
+ /** Implicit content removal within pages */
1282
+ pageContentReductions: PageContentReduction[];
1283
+ }
1284
+ /**
1285
+ * Detected reduction in page content (components, actions, displays removed).
1286
+ */
1287
+ interface PageContentReduction {
1288
+ pageName: string;
1289
+ componentsRemoved: number;
1290
+ actionsRemoved: number;
1291
+ displaysRemoved: number;
1292
+ before: {
1293
+ sections: number;
1294
+ actions: number;
1295
+ };
1296
+ after: {
1297
+ sections: number;
1298
+ actions: number;
1299
+ };
1300
+ isSignificant: boolean;
1301
+ }
1302
+ /**
1303
+ * History metadata stored in main app document for quick access.
1304
+ */
1305
+ interface HistoryMeta {
1306
+ latestSnapshotId?: string;
1307
+ latestChangeSetId?: string;
1308
+ snapshotCount: number;
1309
+ changeSetCount: number;
1310
+ }
1311
+ /**
1312
+ * Validation metadata stored in main app document for quick access.
1313
+ */
1314
+ interface ValidationMeta {
1315
+ errorCount: number;
1316
+ warningCount: number;
1317
+ validatedAt: number;
1318
+ }
1319
+ /**
1320
+ * What kind of .orb concept changed between two schema versions.
1321
+ * Used by canvas focus derivation, CLI narration, selective re-verification.
1322
+ */
1323
+ type SemanticChangeKind = 'orbital-added' | 'orbital-removed' | 'entity-fields-changed' | 'trait-added' | 'trait-removed' | 'state-machine-changed' | 'guard-changed' | 'effect-changed' | 'render-ui-changed' | 'event-wiring-changed' | 'page-changed' | 'behavior-composed';
1324
+ /**
1325
+ * A semantic change between two OrbitalSchema versions.
1326
+ * Identifies WHAT concept changed and WHERE in the schema.
1327
+ */
1328
+ interface SemanticSchemaChange {
1329
+ kind: SemanticChangeKind;
1330
+ orbitalName: string;
1331
+ traitName?: string;
1332
+ transitionEvent?: string;
1333
+ fieldName?: string;
1334
+ }
1335
+
1336
+ /**
1337
+ * App-Level Types
1338
+ *
1339
+ * Types for app summaries, stats, and save operations.
1340
+ */
1341
+
1342
+ /**
1343
+ * GitHub repository link metadata stored in Firestore.
1344
+ * Enables GitHub as the source of truth for schema files.
1345
+ */
1346
+ interface GitHubLink {
1347
+ repoUrl: string;
1348
+ owner: string;
1349
+ repo: string;
1350
+ defaultBranch: string;
1351
+ connectedAt: number;
1352
+ schemaFile?: string;
1353
+ }
1354
+ /**
1355
+ * Dashboard stats derived from schema.
1356
+ */
1357
+ interface StatsView {
1358
+ states: number;
1359
+ events: number;
1360
+ pages: number;
1361
+ entities: number;
1362
+ transitions: number;
1363
+ }
1364
+ /**
1365
+ * App summary for list views.
1366
+ */
1367
+ interface AppSummary {
1368
+ id: string;
1369
+ name: string;
1370
+ description?: string;
1371
+ updatedAt: number;
1372
+ createdAt: number;
1373
+ stats: StatsView;
1374
+ domain?: {
1375
+ category: string;
1376
+ subDomain?: string;
1377
+ };
1378
+ /**
1379
+ * Canonical domain classification + vocabulary projected onto the list
1380
+ * view. Same shape as `OrbitalSchema.domainContext`.
1381
+ */
1382
+ domainContext?: DomainContext;
1383
+ hasValidationErrors: boolean;
1384
+ github?: GitHubLink;
1385
+ }
1386
+ /**
1387
+ * Options for saving a schema.
1388
+ */
1389
+ interface SaveOptions {
1390
+ confirmRemovals?: boolean;
1391
+ snapshotReason?: string;
1392
+ skipProtection?: boolean;
1393
+ expectedVersion?: number;
1394
+ source?: 'requirements-agent' | 'builder-agent' | 'manual';
1395
+ }
1396
+ /**
1397
+ * Result of saving a schema.
1398
+ */
1399
+ interface SaveResult {
1400
+ success: boolean;
1401
+ requiresConfirmation?: boolean;
1402
+ removals?: CategorizedRemovals;
1403
+ error?: string;
1404
+ snapshotId?: string;
1405
+ }
1406
+ /**
1407
+ * Context attached to validation issues originating from LLM output.
1408
+ * Mirrors the `LLMErrorContext` shapes used by `@almadar/validation`
1409
+ * and the builder's fix-prompt pipeline.
1410
+ */
1411
+ interface LLMErrorContext {
1412
+ /** Preview of the raw LLM output */
1413
+ rawValuePreview?: string;
1414
+ /** Expected type or structure */
1415
+ expectedType?: string;
1416
+ /** Actual type received */
1417
+ actualType?: string;
1418
+ /** Where the error originated */
1419
+ source?: {
1420
+ agent: 'requirements' | 'builder' | 'view-planner';
1421
+ operation: string;
1422
+ promptHash?: string;
1423
+ };
1424
+ tokenUsage?: {
1425
+ prompt: number;
1426
+ completion: number;
1427
+ };
1428
+ }
1429
+ /**
1430
+ * Validation issue with optional LLM context.
1431
+ */
1432
+ interface ValidationIssue {
1433
+ code: string;
1434
+ message: string;
1435
+ path: (string | number)[];
1436
+ severity: 'error' | 'warning' | 'info';
1437
+ suggestion?: string;
1438
+ llmContext?: LLMErrorContext;
1439
+ }
1440
+ /**
1441
+ * Validation results.
1442
+ */
1443
+ interface ValidationResults {
1444
+ errors: ValidationIssue[];
1445
+ warnings: ValidationIssue[];
1446
+ validatedAt: number;
1447
+ }
1448
+ /**
1449
+ * Validation document stored in subcollection.
1450
+ */
1451
+ interface ValidationDocument {
1452
+ errors: ValidationIssue[];
1453
+ warnings: ValidationIssue[];
1454
+ validatedAt: number;
1455
+ }
1456
+
1457
+ /**
1458
+ * Service Contract Types
1459
+ *
1460
+ * Formalizes the two public surfaces of an Almadar service:
1461
+ * 1. Call-Service Contract — what the .orb schema can invoke on the TypeScript package
1462
+ * 2. Event Contract — what events enter/leave the service
1463
+ *
1464
+ * Plus internal-but-standardized patterns:
1465
+ * 3. StoreContract — database abstraction boundary
1466
+ * 4. LazyService — singleton lifecycle pattern
1467
+ *
1468
+ * @packageDocumentation
1469
+ */
1470
+
1471
+ /**
1472
+ * All known service action names across all contracts.
1473
+ * Kept in sync with `tools/almadar-service-sync/services-registry.json`.
1474
+ *
1475
+ * Persist operations are listed separately because they also appear
1476
+ * as `EffectResult.action` for persist effects.
1477
+ */
1478
+ type PersistActionName = "create" | "update" | "delete" | "list" | "query";
1479
+ /**
1480
+ * Union of all service action names across the registered service contracts.
1481
+ */
1482
+ type ServiceActionName = PersistActionName | "get" | "getById" | "set" | "remove" | "size" | "generate" | "classify" | "extract" | "summarize" | "send" | "sendMessage" | "sendSMS" | "sendWhatsApp" | "authorize" | "revoke" | "token" | "refresh" | "userinfo" | "register" | "cloneRepo" | "commit" | "createBranch" | "createPR" | "getPRComments" | "pull" | "push" | "build" | "compile" | "compileSchema" | "run" | "validate" | "validateSchema" | "publish" | "enqueue" | "dequeue" | "cancel" | "upload" | "download" | "getSignedUrl" | "search" | "getIssue" | "listIssues" | "generateAll" | "generateDomainLanguage" | "generateFix" | "generateOrbitals" | "cancelGeneration" | "getGenerationHistory" | "recordGeneration" | "startSpan" | "endSpan" | "getSpan" | "recordMetric" | "getMetrics" | "increment" | "logs" | "addEvent" | "emit" | "findEmitters" | "findListeners" | "getListenerCounts" | "getChannel" | "subscribe" | "getUserPreferences" | "updateUserPreferences" | "getThreadHistory" | "listDocuments" | "fetchDocument" | "getVideo" | "createPaymentIntent" | "confirmPayment" | "refund" | "complete" | "fail" | "expire" | "resume" | "status" | "stop" | "lock" | "unlock" | "clear";
1483
+ /**
1484
+ * Action definition for a service contract.
1485
+ *
1486
+ * - `params` is bus-payload-shaped (`ServiceParams`): JSON-serializable
1487
+ * key/value bag with optional nesting. Service contracts override this
1488
+ * with stricter shapes via the generic position on `ServiceContract`.
1489
+ *
1490
+ * - `result` is JSON-serializable too (`EventPayloadValue`): a primitive,
1491
+ * `null`/`undefined`, an array of values, or an `EventPayload` object.
1492
+ * This is the same recursive shape the bus accepts when an effect's
1493
+ * `success` event fires with the call-service result, so no boundary
1494
+ * widening is needed when the runtime forwards the value.
1495
+ */
1496
+ interface ServiceAction {
1497
+ params: ServiceParams;
1498
+ result: EventPayloadValue;
1499
+ }
1500
+ /**
1501
+ * What `["call-service", "name", "action", {...}]` actually calls at runtime.
1502
+ * Each service defines its action map as a Record<string, ServiceAction>.
1503
+ *
1504
+ * @example
1505
+ * ```typescript
1506
+ * type LLMActions = {
1507
+ * generate: {
1508
+ * params: { userPrompt: string; model: string; maxTokens: number };
1509
+ * result: { content: string; tokensUsed: number; latencyMs: number };
1510
+ * };
1511
+ * };
1512
+ *
1513
+ * class LLMService implements ServiceContract<LLMActions> {
1514
+ * async execute(action, params) { ... }
1515
+ * }
1516
+ * ```
1517
+ */
1518
+ interface ServiceContract<Actions extends Record<string, ServiceAction>> {
1519
+ execute<A extends keyof Actions & string>(action: A, params: Actions[A]["params"]): Promise<Actions[A]["result"]>;
1520
+ }
1521
+ /**
1522
+ * Event contract — what events the service emits/listens with typed payloads.
1523
+ * Derived from the `.orb` schema's `emits` and `listens` declarations.
1524
+ *
1525
+ * @example
1526
+ * ```typescript
1527
+ * type LLMEventMap = {
1528
+ * AGENT_LLM_REQUEST: { requestId: string; prompt: string };
1529
+ * LLM_RESPONSE: { requestId: string; content: string; tokensUsed: number };
1530
+ * LLM_ERROR: { requestId: string; error: string };
1531
+ * };
1532
+ *
1533
+ * const events: ServiceEvents<LLMEventMap> = getEventBus();
1534
+ * events.emit('LLM_RESPONSE', { requestId: '1', content: '...', tokensUsed: 42 });
1535
+ * ```
1536
+ */
1537
+ interface ServiceEvents<EventMap extends Record<string, EventPayload>> {
1538
+ emit<E extends keyof EventMap & string>(event: E, payload: EventMap[E]): void;
1539
+ on<E extends keyof EventMap & string>(event: E, handler: (payload: EventMap[E]) => void): () => void;
1540
+ }
1541
+ /**
1542
+ * Create a typed view of an untyped EventBus. Wraps the raw EventBus
1543
+ * with compile-time type checking while keeping runtime behavior identical.
1544
+ *
1545
+ * @example
1546
+ * ```typescript
1547
+ * type LLMEventMap = {
1548
+ * LLM_RESPONSE: { requestId: string; content: string };
1549
+ * LLM_ERROR: { requestId: string; error: string };
1550
+ * };
1551
+ *
1552
+ * const typedBus = createTypedEventBus<LLMEventMap>(getServerEventBus());
1553
+ * typedBus.emit('LLM_RESPONSE', { requestId: '1', content: '...' }); // type-safe
1554
+ * typedBus.on('LLM_ERROR', (payload) => { payload.error; }); // payload is typed
1555
+ * ```
1556
+ */
1557
+ /**
1558
+ * Creates a typed event bus from an untyped bus implementation.
1559
+ *
1560
+ * This wrapper adds TypeScript type safety to event emission and listening.
1561
+ * The generic `EventMap` defines the shape of all events and their payloads.
1562
+ *
1563
+ * @template EventMap - Type mapping event names to their payload types
1564
+ * @param {Object} bus - Untyped event bus implementation
1565
+ * @param {Function} bus.emit - Function to emit events
1566
+ * @param {Function} bus.on - Function to listen to events
1567
+ * @returns {ServiceEvents<EventMap>} Typed event bus interface
1568
+ *
1569
+ * @example
1570
+ * interface MyEvents {
1571
+ * 'user.created': { id: string; name: string };
1572
+ * 'user.deleted': { id: string };
1573
+ * }
1574
+ *
1575
+ * const typedBus = createTypedEventBus<MyEvents>(rawBus);
1576
+ * typedBus.emit('user.created', { id: '123', name: 'Alice' });
1577
+ */
1578
+ declare function createTypedEventBus<EventMap extends Record<string, EventPayload>>(bus: {
1579
+ emit(event: string, payload?: unknown, meta?: LogMeta): void;
1580
+ on(event: string, handler: (payload: unknown, meta?: LogMeta) => void): () => void;
1581
+ }): ServiceEvents<EventMap>;
1582
+ /** Filter operator for store queries. */
1583
+ type StoreFilterOp = "==" | "!=" | "<" | "<=" | ">" | ">=" | "in" | "not-in" | "contains";
1584
+ /** A single filter clause for store queries. */
1585
+ interface StoreFilter<T> {
1586
+ field: keyof T & string;
1587
+ op: StoreFilterOp;
1588
+ value: unknown;
1589
+ }
1590
+ /**
1591
+ * Database abstraction boundary. Services receive `StoreContract<T>`,
1592
+ * not raw database clients. Swappable per database engine.
1593
+ *
1594
+ * @example
1595
+ * ```typescript
1596
+ * interface LLMRequest { id: string; prompt: string; status: string }
1597
+ *
1598
+ * class FirestoreLLMRequestStore implements StoreContract<LLMRequest> {
1599
+ * async getById(id) { ... }
1600
+ * async create(data) { ... }
1601
+ * async update(id, data) { ... }
1602
+ * async delete(id) { ... }
1603
+ * async query(filters) { ... }
1604
+ * }
1605
+ * ```
1606
+ */
1607
+ interface StoreContract<T extends {
1608
+ id: string;
1609
+ }> {
1610
+ getById(id: string): Promise<T | null>;
1611
+ create(data: Omit<T, "id">): Promise<T>;
1612
+ update(id: string, data: Partial<T>): Promise<T>;
1613
+ delete(id: string): Promise<void>;
1614
+ query(filters: StoreFilter<T>[]): Promise<T[]>;
1615
+ }
1616
+ /**
1617
+ * Standardized singleton lifecycle. Replaces ad-hoc
1618
+ * `let x = null; export function getX()` patterns.
1619
+ *
1620
+ * @example
1621
+ * ```typescript
1622
+ * const llmClient = createLazyService(() => new LLMClient({ apiKey: process.env.LLM_KEY }));
1623
+ *
1624
+ * // In request handler:
1625
+ * const client = llmClient.get(); // created on first call, cached after
1626
+ *
1627
+ * // In test teardown:
1628
+ * llmClient.reset(); // next get() creates a fresh instance
1629
+ * ```
1630
+ */
1631
+ interface LazyService<T> {
1632
+ /** Get the singleton instance (creates on first call). */
1633
+ get(): T;
1634
+ /** Reset the singleton (next get() creates fresh). For test isolation. */
1635
+ reset(): void;
1636
+ }
1637
+ /**
1638
+ * Create a lazy singleton from a factory function.
1639
+ *
1640
+ * Creates a service that lazily initializes on first access and caches the instance.
1641
+ * Useful for expensive resources like database connections or API clients.
1642
+ *
1643
+ * @template T - The type of service to create
1644
+ * @param {() => T} factory - Factory function that creates the service instance
1645
+ * @returns {LazyService<T>} Lazy service with get() and reset() methods
1646
+ *
1647
+ * @example
1648
+ * const dbService = createLazyService(() => new DatabaseClient(config));
1649
+ * const db = dbService.get(); // Initializes on first call
1650
+ */
1651
+ declare function createLazyService<T>(factory: () => T): LazyService<T>;
1652
+
1653
+ /**
1654
+ * Transition source state specification.
1655
+ * - string: Single state name (e.g., 'Idle')
1656
+ * - '*': Wildcard - matches any current state
1657
+ * - string[]: Array of states - matches any of the listed states
1658
+ */
1659
+ type TransitionFrom = string | '*' | string[];
1660
+ interface ResolvedField {
1661
+ name: string;
1662
+ type: string;
1663
+ tsType: string;
1664
+ description?: string;
1665
+ /** Field default — JSON-shaped, mirroring `EntityField.default`. */
1666
+ default?: JsonValue;
1667
+ required: boolean;
1668
+ /** Validation constraints carried from the schema (enum whitelist). */
1669
+ validation?: {
1670
+ enum?: string[];
1671
+ };
1672
+ /** Enum values for enum or constrained string fields */
1673
+ values?: string[];
1674
+ /** Enum values (alias for values, for compatibility) */
1675
+ enumValues?: string[];
1676
+ /** Relation configuration for foreign key references */
1677
+ relation?: {
1678
+ entity: string;
1679
+ cardinality?: string;
1680
+ field?: string;
1681
+ };
1682
+ }
1683
+ interface ResolvedEntity {
1684
+ name: string;
1685
+ description?: string;
1686
+ icon?: string;
1687
+ collection: string;
1688
+ fields: ResolvedField[];
1689
+ /** Whether this entity only exists in runtime (not persisted to Firestore) */
1690
+ runtime?: boolean;
1691
+ /** Whether this entity's state is shared across every bound trait (vs a per-trait copy). Orthogonal to `runtime`. */
1692
+ shared?: boolean;
1693
+ /** Whether this entity has pre-authored instances in the schema */
1694
+ hasInstances?: boolean;
1695
+ /** Pre-authored instances from the schema (seed data or static reference data) */
1696
+ instances?: EntityRow[];
1697
+ /** Default field values from schema (for spawning singletons) */
1698
+ defaults?: Record<string, FieldValue>;
1699
+ usedByTraits: string[];
1700
+ usedByPages: string[];
1701
+ }
1702
+ interface ResolvedEntityBinding {
1703
+ /** Binding name in code */
1704
+ name: string;
1705
+ /** Entity being bound */
1706
+ entity: ResolvedEntity;
1707
+ /** CRUD operations to generate */
1708
+ operations: ('list' | 'get' | 'create' | 'update' | 'delete')[];
1709
+ }
1710
+ interface ResolvedTraitState {
1711
+ name: string;
1712
+ isInitial: boolean;
1713
+ isFinal: boolean;
1714
+ }
1715
+ interface ResolvedTraitEvent {
1716
+ key: string;
1717
+ name: string;
1718
+ payload?: Record<string, string>;
1719
+ }
1720
+ interface ResolvedTraitTransition {
1721
+ /** Source state(s): string, '*' for wildcard, or array of states */
1722
+ from: TransitionFrom;
1723
+ to: string;
1724
+ event: string;
1725
+ guard?: SExpr;
1726
+ effects: SExpr[];
1727
+ }
1728
+ interface ResolvedTraitGuard {
1729
+ name: string;
1730
+ condition: SExpr;
1731
+ }
1732
+ interface ResolvedTraitTick {
1733
+ name: string;
1734
+ /**
1735
+ * `number` (ms), `'frame'`, a duration string (`'5s'`/`'1m'`/`'1h'`), or a
1736
+ * 5-field cron expression (`'0 9 * * *'`) — `schema-to-ir.ts`'s
1737
+ * `interval: tick.interval || 0` passes the source schema's raw
1738
+ * `string | number` straight through with no normalization, so this must
1739
+ * match that reality rather than the narrower `number | 'frame'` it used
1740
+ * to declare (which made every non-'frame' string an unchecked cast at
1741
+ * every consumer).
1742
+ */
1743
+ interval: number | string;
1744
+ guard?: SExpr;
1745
+ effects: SExpr[];
1746
+ priority: number;
1747
+ appliesTo: string[];
1748
+ }
1749
+ interface ResolvedTraitListener {
1750
+ event: string;
1751
+ triggers: string;
1752
+ guard?: SExpr;
1753
+ /** `with { ... }` payload rewrite: `{ targetField: SExpr }`, evaluated against the source payload. */
1754
+ payloadMapping?: Record<string, SExpr>;
1755
+ /** Source scoping (see `ListenSource` in types/trait). */
1756
+ source?: ListenSource;
1757
+ }
1758
+ interface ResolvedTraitDataEntity {
1759
+ name: string;
1760
+ fields: ResolvedField[];
1761
+ runtime: boolean;
1762
+ singleton: boolean;
1763
+ }
1764
+ /**
1765
+ * UI binding for interaction traits - maps states to presentations
1766
+ */
1767
+ interface ResolvedTraitUIBinding {
1768
+ [stateName: string]: {
1769
+ /** Presentation type: modal, drawer, popover, inline, confirm-dialog */
1770
+ presentation: string;
1771
+ /** Content pattern(s) to render */
1772
+ content: AnyPatternConfig | AnyPatternConfig[];
1773
+ /** Presentation props */
1774
+ props?: {
1775
+ size?: string;
1776
+ position?: string;
1777
+ title?: string;
1778
+ closable?: boolean;
1779
+ width?: string;
1780
+ showProgress?: boolean;
1781
+ step?: number;
1782
+ totalSteps?: number;
1783
+ };
1784
+ };
1785
+ }
1786
+ /**
1787
+ * Fully resolved trait - expanded from schema OR library.
1788
+ * The compiler generates code from this structure universally,
1789
+ * without knowing which specific trait it is.
1790
+ */
1791
+ interface ResolvedTrait {
1792
+ /** Unique trait identifier */
1793
+ name: string;
1794
+ /** Human-readable description */
1795
+ description?: string;
1796
+ /** Where this trait came from */
1797
+ source: 'schema' | 'library' | 'inline';
1798
+ /** Category for organizing traits */
1799
+ category?: 'lifecycle' | 'temporal' | 'validation' | 'notification' | 'integration' | 'interaction' | 'agent' | 'game-core' | 'game-character' | 'game-ai' | 'game-combat' | 'game-items' | 'game-cards' | 'game-board' | 'game-puzzle';
1800
+ states: ResolvedTraitState[];
1801
+ events: ResolvedTraitEvent[];
1802
+ transitions: ResolvedTraitTransition[];
1803
+ guards: ResolvedTraitGuard[];
1804
+ ticks: ResolvedTraitTick[];
1805
+ listens: ResolvedTraitListener[];
1806
+ dataEntities: ResolvedTraitDataEntity[];
1807
+ /**
1808
+ * Atom-declared linked entity. The atom (e.g. std-pagination)
1809
+ * declares which entity its `@entity.X` bindings resolve against
1810
+ * (e.g. `PagedItem`). Distinct from the call-site rebind on
1811
+ * `ResolvedTraitBinding.linkedEntity`, which a molecule may use
1812
+ * to override the atom's default. Either side may be undefined
1813
+ * for traits that don't bind any entity (pure interaction).
1814
+ */
1815
+ linkedEntity?: string;
1816
+ /**
1817
+ * The trait's DECLARED `config { }` schema (per-field
1818
+ * `{ type, default? }`). Drives `@config.X` substitution: each
1819
+ * field's `default` seeds the binding context behind any caller-
1820
+ * supplied call-site `config: { ... }` override on the trait
1821
+ * reference. Authored on the atom; flows through verbatim from
1822
+ * `Trait.config`.
1823
+ *
1824
+ * (Caller-supplied call-site overrides live on the page-trait
1825
+ * binding's `config: TraitConfig` — see `ResolvedTraitBinding`.)
1826
+ */
1827
+ config?: DeclaredTraitConfig;
1828
+ ui?: ResolvedTraitUIBinding;
1829
+ }
1830
+ /**
1831
+ * Trait binding on a page - links a resolved trait to the page
1832
+ */
1833
+ interface ResolvedTraitBinding {
1834
+ /** Reference name */
1835
+ ref?: string;
1836
+ /** Fully resolved trait */
1837
+ trait: ResolvedTrait;
1838
+ /** Entity this trait operates on (if any) */
1839
+ linkedEntity?: string;
1840
+ /** Instance configuration */
1841
+ config?: TraitConfig;
1842
+ }
1843
+ interface ResolvedPattern {
1844
+ /** Pattern type (e.g., 'page-header', 'entity-list', 'game-canvas') */
1845
+ type: string;
1846
+ /** Pattern configuration */
1847
+ config: AnyPatternConfig;
1848
+ /** Shell component to use */
1849
+ shellComponent?: string;
1850
+ }
1851
+ interface ResolvedSectionEvent {
1852
+ event: string;
1853
+ action: string;
1854
+ target?: string;
1855
+ }
1856
+ interface ResolvedSection {
1857
+ /** Section identifier */
1858
+ id: string;
1859
+ /** Resolved pattern */
1860
+ pattern: ResolvedPattern;
1861
+ /** Events emitted by this section */
1862
+ events: ResolvedSectionEvent[];
1863
+ /** Position in page layout */
1864
+ position?: number;
1865
+ /** Entity binding for this section */
1866
+ binding?: ResolvedEntityBinding;
1867
+ }
1868
+ interface ResolvedNavigation {
1869
+ event?: string;
1870
+ from?: string;
1871
+ to: string;
1872
+ trigger?: string;
1873
+ params?: Record<string, string>;
1874
+ label?: string;
1875
+ path?: string;
1876
+ icon?: string;
1877
+ }
1878
+ interface ResolvedPage {
1879
+ /** Page identifier */
1880
+ name: string;
1881
+ /** URL path */
1882
+ path: string;
1883
+ /** Feature folder name */
1884
+ featureName: string;
1885
+ /** Layout component */
1886
+ layout?: string;
1887
+ /** View type (dashboard, list, detail, create, edit) */
1888
+ viewType?: 'dashboard' | 'list' | 'detail' | 'create' | 'edit';
1889
+ /** Resolved sections */
1890
+ sections: ResolvedSection[];
1891
+ /** Resolved trait bindings */
1892
+ traits: ResolvedTraitBinding[];
1893
+ /** Entity data bindings */
1894
+ entityBindings: ResolvedEntityBinding[];
1895
+ /** Navigation wiring */
1896
+ navigation: ResolvedNavigation[];
1897
+ /** Singleton entities to spawn on this page (runtime singletons) */
1898
+ singletonEntities: ResolvedEntity[];
1899
+ }
1900
+ /**
1901
+ * Complete resolved IR - all references expanded
1902
+ */
1903
+ interface ResolvedIR {
1904
+ /** App name */
1905
+ appName: string;
1906
+ /** App description */
1907
+ description?: string;
1908
+ /** App version */
1909
+ version?: string;
1910
+ /** All resolved entities (Map for lookup) */
1911
+ entities: Map<string, ResolvedEntity>;
1912
+ /** All resolved traits (Map for lookup) */
1913
+ traits: Map<string, ResolvedTrait>;
1914
+ /** All resolved pages (Map for lookup) */
1915
+ pages: Map<string, ResolvedPage>;
1916
+ /** Entity bindings (used for data hook generation) */
1917
+ entityBindings: ResolvedEntityBinding[];
1918
+ /** Raw data entities (used for instance data generation) */
1919
+ rawEntities?: Entity[];
1920
+ /** Generation timestamp */
1921
+ generatedAt: string;
1922
+ }
1923
+ /**
1924
+ * Create an empty resolved trait with defaults
1925
+ */
1926
+ declare function createEmptyResolvedTrait(name: string, source: 'schema' | 'library' | 'inline'): ResolvedTrait;
1927
+ /**
1928
+ * Create an empty resolved page with defaults
1929
+ */
1930
+ declare function createEmptyResolvedPage(name: string): ResolvedPage;
1931
+ /**
1932
+ * Infer TypeScript type from schema type
1933
+ */
1934
+ declare function inferTsType(schemaType: string): string;
1935
+ /**
1936
+ * Create a resolved field with TypeScript type inference
1937
+ */
1938
+ declare function createResolvedField(field: {
1939
+ name: string;
1940
+ type: string;
1941
+ description?: string;
1942
+ default?: JsonValue;
1943
+ required?: boolean;
1944
+ validation?: {
1945
+ enum?: string[];
1946
+ };
1947
+ values?: string[];
1948
+ }): ResolvedField;
1949
+ /**
1950
+ * Type guard to check if an object is a ResolvedIR.
1951
+ *
1952
+ * Validates that an unknown value conforms to the ResolvedIR structure.
1953
+ * Checks for required properties and correct types. Used for runtime
1954
+ * type checking and validation.
1955
+ *
1956
+ * @param {unknown} ir - Value to check
1957
+ * @returns {boolean} True if value is ResolvedIR, false otherwise
1958
+ *
1959
+ * @example
1960
+ * if (isResolvedIR(schema)) {
1961
+ * // Type-safe access to ResolvedIR properties
1962
+ * console.log('Valid IR:', schema.appName);
1963
+ * }
1964
+ */
1965
+ declare function isResolvedIR(ir: RuntimeValue): ir is ResolvedIR;
1966
+
1967
+ /**
1968
+ * Context Extensions (framework concept)
1969
+ *
1970
+ * Open interface for consumer-supplied context that flows through guards,
1971
+ * effects, and evaluation. Generated code imports `ContextExtensions`
1972
+ * instead of `Record<string, unknown>` / `unknown` for the extensions bag,
1973
+ * so downstream type-checking verifies that every read of a context key
1974
+ * lines up with a declared interface member.
1975
+ *
1976
+ * Declaration-merging pattern — consumers augment this interface with
1977
+ * their own optional fields:
1978
+ *
1979
+ * ```ts
1980
+ * declare module '@almadar/core' {
1981
+ * interface ContextExtensions {
1982
+ * agent?: AgentContext;
1983
+ * auth?: AuthContext;
1984
+ * }
1985
+ * }
1986
+ * ```
1987
+ *
1988
+ * With no augmentation the interface is `{}` — `ctx.extensions.foo` is
1989
+ * a type error, which is the desired behavior: if the codegen hits a
1990
+ * context field that nobody declared, the consumer project is expected
1991
+ * to add the declaration rather than widen to `unknown`.
1992
+ *
1993
+ * @packageDocumentation
1994
+ */
1995
+ interface ContextExtensions {
1996
+ }
1997
+
1998
+ /**
1999
+ * Bus Event Types (framework concept)
2000
+ *
2001
+ * Canonical event shape for Almadar's cross-package event bus. Hoisted into
2002
+ * `@almadar/core` so `@almadar/ui`, `@almadar/runtime`, and generated code
2003
+ * all agree on the same structure. Replaces the previously divergent
2004
+ * `KFlowEvent` (ui) and `RuntimeEvent` (runtime) definitions.
2005
+ *
2006
+ * @packageDocumentation
2007
+ */
2008
+
2009
+ /**
2010
+ * Declared event key. A trait's event names (INIT, SAVE, CLOSE,
2011
+ * CONFIRM_REMOVE, ...) flow through the orbital schema and the UI as
2012
+ * strings; this alias marks "this string is a declared event key, not
2013
+ * arbitrary text."
2014
+ *
2015
+ * Component props typed as `EventKey` are detected by the pattern-sync
2016
+ * tool (`tools/almadar-pattern-sync/parser.ts`) via a TS-type lookup and
2017
+ * marked as `kind: "event"` in the patterns registry
2018
+ * (`@almadar/patterns`). Consumers of the registry — the Rust compiler's
2019
+ * inline phase and the `@almadar/runtime` preprocess — read that marker
2020
+ * to apply call-site `events: { OLD: NEW }` renames to render-ui trees
2021
+ * without name-matching heuristics.
2022
+ *
2023
+ * Plain alias over `string`. Not branded because event keys originate
2024
+ * from user data at runtime (orb schema literals, bus emits), so cast
2025
+ * friction would buy nothing. The value of the alias is at the type
2026
+ * surface — it's a marker the pattern-sync tool can find via
2027
+ * `getSymbolAtLocation`.
2028
+ */
2029
+ type EventKey = string;
2030
+ /**
2031
+ * Phantom-typed brand for declarative bus-emit props on UI components.
2032
+ *
2033
+ * Used by component authors to BOTH mark a prop as a bus-event reference
2034
+ * AND document the payload shape that the component will fire onto the
2035
+ * bus when that prop is bound. Authors write:
2036
+ *
2037
+ * // Tabs.tsx
2038
+ * export interface TabsProps {
2039
+ * tabChangeEvent?: EventEmit<{ tabId: string }>;
2040
+ * }
2041
+ *
2042
+ * Consumers see only the structural `string` (no UX impact: passing a
2043
+ * literal `"TAB_CHANGED"` keeps working). The phantom `P` parameter
2044
+ * carries the bus-payload schema at the type level for pattern-sync to
2045
+ * extract.
2046
+ *
2047
+ * Pattern-sync (`tools/almadar-pattern-sync/parser.ts`) detects this
2048
+ * brand via TS type-lookup (mirrors how it detects `EventKey`) and
2049
+ * writes two registry fields per prop:
2050
+ * - `kind: "event-ref"` — the discriminant rules read in lolo / orb
2051
+ * validator to know "this prop's string value is a bus event name."
2052
+ * - `emitPayloadSchema` — the structural shape of `P`, serialized as
2053
+ * the same JSON-Schema-shaped record Almadar uses for trait
2054
+ * `payloadSchema`. Validator rules cross-check this against the
2055
+ * trait's declared `emits { EVENT { ... } }` payload to catch mismatches
2056
+ * at parse / validate time instead of runtime.
2057
+ *
2058
+ * Example payload bus emission inside the component (no wrapper —
2059
+ * `EventEmit<P>` erases to `string`):
2060
+ *
2061
+ * if (tabChangeEvent) eventBus.emit(`UI:${tabChangeEvent}`, { tabId });
2062
+ *
2063
+ * The brand is structurally an unused optional readonly property; TS
2064
+ * never asks for it at construction, so authors and consumers never
2065
+ * see it.
2066
+ */
2067
+ type EventEmit<P> = string & {
2068
+ readonly __emitPayload?: P;
2069
+ };
2070
+ /**
2071
+ * Phantom-typed brand for declarative bus-listen props on UI components.
2072
+ *
2073
+ * Mirror of `EventEmit<P>`. Used by future patterns where a UI component
2074
+ * subscribes to a bus event and forwards its payload upward via prop
2075
+ * (e.g. an editor pattern that listens for `EXTERNAL_RESET` and exposes
2076
+ * the consumed payload to the parent). Pattern-sync detects this brand
2077
+ * the same way as `EventEmit<P>` and writes:
2078
+ * - `kind: "event-listen"` (or a sub-discriminant of `event-ref`)
2079
+ * - `listenPayloadSchema` with the structural shape of `P`
2080
+ *
2081
+ * Validator rules use this to verify the trait the prop is bound to
2082
+ * actually emits a payload of the expected shape.
2083
+ *
2084
+ * Reserved for symmetry; no @almadar/ui component uses it as of this
2085
+ * commit. Add usages incrementally as patterns require them.
2086
+ */
2087
+ type EventListen<P> = string & {
2088
+ readonly __listenPayload?: P;
2089
+ };
2090
+ /**
2091
+ * Identifies the origin of a bus event. Used by cross-trait listeners to
2092
+ * filter emits from specific orbitals, traits, transitions, or ticks.
2093
+ *
2094
+ * `transition` and `tick` are optional runtime-internal details; most
2095
+ * consumers only care about `orbital` and `trait`.
2096
+ */
2097
+ interface BusEventSource {
2098
+ orbital?: string;
2099
+ /** V4 dual-carry id sibling of `orbital` — stable across an orbital rename. */
2100
+ orbitalId?: OrbitalId;
2101
+ trait?: string;
2102
+ /** V4 dual-carry id sibling of `trait` — stable across a trait rename. */
2103
+ traitId?: TraitId;
2104
+ /** V4 dual-carry id of the emitted event — stable across an event rename. */
2105
+ eventId?: EventId;
2106
+ transition?: string;
2107
+ tick?: string;
2108
+ /**
2109
+ * True when the orbital bridge re-broadcasts an event onto the bus
2110
+ * (any source — both echoes of the dispatched event and server-side
2111
+ * cascade emits via `(emit X)` / `fetch.emit.success`). Cross-trait
2112
+ * listeners filter on this flag so the click-time qualified emit
2113
+ * (which has no `fromBridge`) doesn't double-fire alongside the
2114
+ * post-server bridge confirmation. See `dispatched` for the narrower
2115
+ * "echo of the just-dispatched event" signal.
2116
+ */
2117
+ fromBridge?: boolean;
2118
+ /**
2119
+ * True ONLY for bridge echoes the receiving tab already processed, so
2120
+ * the originating trait's self-subscription skips them instead of
2121
+ * re-dispatching its own echo (infinite loop / double execution).
2122
+ * Set by path 1 of useOrbitalBridge (compiled shell — echo of the
2123
+ * just-dispatched event; server-side cascade emits there carry
2124
+ * `fromBridge: true` but NOT `dispatched`, so they still reach the
2125
+ * source trait's transition handler, e.g. `loading -> browsing` on a
2126
+ * fetch's `emit.success`) and by ServerBridge's response-cascade
2127
+ * re-emit (runtime path — every response entry echoes this tab's own
2128
+ * dispatch, already delivered locally via the click-time qualified
2129
+ * emit / bare-cascade subscription; cross-trait `listens` don't filter
2130
+ * on this flag, so their delivery is unaffected). Push-leg events from
2131
+ * OTHER tabs (multiplayer) are never stamped.
2132
+ */
2133
+ dispatched?: boolean;
2134
+ /**
2135
+ * The client that originated the dispatch whose effects emitted this
2136
+ * event (from `OrbitalEventRequest.clientId`); absent for headless
2137
+ * dispatches (ticks, circuit-router probes, walkers). The server-side
2138
+ * listens fan-out skips client-originated cascade emits — under dual
2139
+ * execution the originating client relays every cascade hop through the
2140
+ * bridge itself, so the server dispatching the same hop double-ran it
2141
+ * (one Send persisted two rows). Headless topology keeps the fan-out:
2142
+ * there is no client to drive the circuit.
2143
+ */
2144
+ originClientId?: string;
2145
+ }
2146
+ /**
2147
+ * An event flowing on the bus.
2148
+ *
2149
+ * The `source` field is structured so cross-trait listeners can match
2150
+ * `event.source?.orbital === 'X' && event.source?.trait === 'Y'` without
2151
+ * parsing a delimiter.
2152
+ */
2153
+ interface BusEvent {
2154
+ /** Event type identifier (e.g., 'CartItemLoaded', 'TASK_COMPLETED') */
2155
+ type: EventKey;
2156
+ /** Optional structured payload */
2157
+ payload?: EventPayload;
2158
+ /** Timestamp when the event was emitted */
2159
+ timestamp: number;
2160
+ /** Optional origin info for filtering */
2161
+ source?: BusEventSource;
2162
+ }
2163
+ /** Bus event listener callback. */
2164
+ type BusEventListener = (event: BusEvent) => void;
2165
+ /** Returned by `on()` / `once()` to detach a listener. */
2166
+ type Unsubscribe = () => void;
2167
+
2168
+ /**
2169
+ * Verification Types (framework concept)
2170
+ *
2171
+ * The `window.__orbitalVerification` bridge is the single observation
2172
+ * point Playwright-based verifiers (`orbital-verify`, `runtime-verify`,
2173
+ * `@almadar-io/verify`) use to read runtime state out of a live app.
2174
+ * Its shape was previously duplicated between `@almadar/ui`'s
2175
+ * `verificationRegistry.ts` (producer) and `@almadar-io/verify`'s
2176
+ * `state-bridge.ts` (consumer). Every added field had to be mirrored
2177
+ * by hand; one side drifting silently broke the other.
2178
+ *
2179
+ * Hoisting the wire types into `@almadar/core` closes that gap the same
2180
+ * way {@link BusEvent} closed the UI/runtime event-shape drift. The
2181
+ * registry still owns the state machine, the schedule, and the window
2182
+ * exposure — this module owns only the shapes both sides agree on.
2183
+ *
2184
+ * @packageDocumentation
2185
+ */
2186
+
2187
+ /**
2188
+ * Outcome of a single verification check. `warn` is non-fatal in the
2189
+ * overall pass/fail tally; `pending` means the check has been registered
2190
+ * but not yet resolved.
2191
+ */
2192
+ type CheckStatus = "pass" | "fail" | "pending" | "warn";
2193
+ interface VerificationCheck {
2194
+ id: string;
2195
+ label: string;
2196
+ status: CheckStatus;
2197
+ details?: string;
2198
+ /** Timestamp (ms since epoch) when the status last changed. */
2199
+ updatedAt: number;
2200
+ }
2201
+ /**
2202
+ * Trace of a single effect as it ran on a transition. `args` are the
2203
+ * effect tuple's trailing S-expressions; consumers narrow via `type`
2204
+ * before inspecting.
2205
+ */
2206
+ interface EffectTrace {
2207
+ type: string;
2208
+ /** For fetch/persist effects: the entity the effect addresses. */
2209
+ entityName?: string;
2210
+ args: SExpr[];
2211
+ status: "executed" | "failed" | "skipped";
2212
+ error?: string;
2213
+ durationMs?: number;
2214
+ }
2215
+ /** What the server returned for a forwarded event. */
2216
+ interface ServerResponseTrace {
2217
+ orbitalName: string;
2218
+ success: boolean;
2219
+ clientEffects: number;
2220
+ dataEntities: Record<string, number>;
2221
+ emittedEvents: string[];
2222
+ error?: string;
2223
+ timestamp: number;
2224
+ }
2225
+ interface TransitionTrace {
2226
+ id: string;
2227
+ traitName: string;
2228
+ from: string;
2229
+ to: string;
2230
+ event: string;
2231
+ guardExpression?: string;
2232
+ guardResult?: boolean;
2233
+ effects: EffectTrace[];
2234
+ /** Populated when the event round-tripped to the server. */
2235
+ serverResponse?: ServerResponseTrace;
2236
+ timestamp: number;
2237
+ }
2238
+ interface BridgeHealth {
2239
+ connected: boolean;
2240
+ eventsForwarded: number;
2241
+ eventsReceived: number;
2242
+ lastError?: string;
2243
+ lastHeartbeat: number;
2244
+ }
2245
+ interface VerificationSummary {
2246
+ totalChecks: number;
2247
+ passed: number;
2248
+ failed: number;
2249
+ warnings: number;
2250
+ pending: number;
2251
+ }
2252
+ /**
2253
+ * Per-trait state snapshot exposed to the verifier so it can assert
2254
+ * that reducer data (populated by fetch/persist transitions) and the
2255
+ * last dispatched payload land in the DOM correctly (VG4/VG6/VG11a/b/c).
2256
+ *
2257
+ * Mirrors what `useTraitStateMachine` / generated trait logic hooks
2258
+ * keep internally, without the verifier having to parse rendered text.
2259
+ */
2260
+ interface TraitStateSnapshot {
2261
+ /** Trait name as declared in the schema. */
2262
+ traitName: string;
2263
+ /** Current state machine state. */
2264
+ currentState: string;
2265
+ /** Declared state names for this trait (non-empty for healthy refs). */
2266
+ states: string[];
2267
+ /** Declared event keys for this trait (non-empty for healthy refs). */
2268
+ events: string[];
2269
+ /**
2270
+ * Entity data keyed by entity name. Uses {@link EntityRow} — the
2271
+ * canonical persisted-entity shape the server returns and the trait
2272
+ * reducer stores. Consumers that need full field-level types can cast
2273
+ * down to the generated entity (e.g. `data['CartItem'] as CartItem[]`).
2274
+ * Snapshot-on-read; mutating the returned arrays does not affect the
2275
+ * live reducer.
2276
+ */
2277
+ data: Record<string, EntityRow[]>;
2278
+ /** Payload of the last event the state machine processed, if any. */
2279
+ lastPayload?: EventPayload;
2280
+ /**
2281
+ * Last event the walker (or a UI click) dispatched into this trait.
2282
+ * Used by VG11a to resolve `@payload.X` expected values.
2283
+ */
2284
+ lastEventDispatched?: {
2285
+ event: string;
2286
+ payload?: EventPayload;
2287
+ source?: BusEventSource;
2288
+ timestamp: number;
2289
+ };
2290
+ /**
2291
+ * Bus events received from the server's `emittedEvents` cascade
2292
+ * since the last user dispatch. VG4 compares the length against the
2293
+ * number of `emit: { success/failure: ... }` entries on the
2294
+ * triggering transition.
2295
+ */
2296
+ cascadeReceived: Array<{
2297
+ event: string;
2298
+ payload?: EventPayload;
2299
+ timestamp: number;
2300
+ }>;
2301
+ }
2302
+ interface VerificationSnapshot {
2303
+ checks: VerificationCheck[];
2304
+ transitions: TransitionTrace[];
2305
+ bridge: BridgeHealth | null;
2306
+ summary: VerificationSummary;
2307
+ /**
2308
+ * Per-trait reducer snapshots. Empty on older runtimes that predate
2309
+ * the Foundation 1 expansion; non-empty once any trait hook has
2310
+ * registered a snapshot getter.
2311
+ */
2312
+ traits: TraitStateSnapshot[];
2313
+ }
2314
+ /** Asset load status exposed for canvas-based game verification. */
2315
+ type AssetLoadStatus = "loaded" | "failed" | "pending";
2316
+ /**
2317
+ * Entry recorded on the verification event log. The registry ring-buffers
2318
+ * the log to the last `MAX_EVENT_LOG` entries (evicting the oldest, never
2319
+ * the recent tail) so long runs don't grow unbounded — see
2320
+ * `verificationRegistry` and `eventLogDropped`.
2321
+ */
2322
+ interface EventLogEntry {
2323
+ type: string;
2324
+ payload?: EventPayload;
2325
+ timestamp: number;
2326
+ }
2327
+ /**
2328
+ * A drawable descriptor as exposed over the verification bridge. The
2329
+ * concrete `DrawableNode` union lives downstream in `@almadar/ui`
2330
+ * (`lib/drawable/paintDispatch.ts`) and cannot be imported here without
2331
+ * inverting the dependency axis; the bridge contract carries the `type`
2332
+ * discriminant (`draw-sprite`, `draw-shape`, …) that verifiers narrow on.
2333
+ */
2334
+ interface DrawableDescriptor {
2335
+ type: string;
2336
+ }
2337
+ /**
2338
+ * The object attached to `window.__orbitalVerification`. Every optional
2339
+ * member is wired up by a corresponding `bind*` / `register*` call on
2340
+ * the registry (e.g. `bindEventBus` populates `sendEvent`). Consumers
2341
+ * should null-check before calling — an older bundle might expose only
2342
+ * the core readers.
2343
+ */
2344
+ interface OrbitalVerificationAPI {
2345
+ getSnapshot: () => VerificationSnapshot;
2346
+ getChecks: () => VerificationCheck[];
2347
+ getTransitions: () => TransitionTrace[];
2348
+ getBridge: () => BridgeHealth | null;
2349
+ getSummary: () => VerificationSummary;
2350
+ /** Wait for a specific event to be processed. Resolves to null on timeout. */
2351
+ waitForTransition: (event: string, timeoutMs?: number) => Promise<TransitionTrace | null>;
2352
+ /**
2353
+ * Send an event into the runtime. Requires {@link bindEventBus} (in
2354
+ * `@almadar/ui`) to have run at least once. Payload typed as
2355
+ * {@link EventPayload} so callers can't slip non-bus-shaped data in.
2356
+ *
2357
+ * `traitScope` is the qualified `Orbital.Trait` (or `App.Trait`)
2358
+ * scope that bus listeners subscribe under. The bridge constructs
2359
+ * `UI:${traitScope}.${event}` and emits that on the bus, matching
2360
+ * the codegen-emitted subscription keys (gap #13). When omitted,
2361
+ * the legacy bare-prefix form `UI:${event}` is used — kept only
2362
+ * for system-scope events like `UI:NOTIFY`; trait-driven dispatch
2363
+ * MUST pass a `traitScope`.
2364
+ */
2365
+ sendEvent?: (event: string, payload?: EventPayload, traitScope?: string) => void;
2366
+ /** Current state name for a given trait, if known. */
2367
+ getTraitState?: (traitName: string) => string | undefined;
2368
+ /** Per-trait reducer snapshots (VG4/VG6/VG11a/b/c). */
2369
+ getTraitSnapshots?: () => TraitStateSnapshot[];
2370
+ /** Canvas frame capture. Populated by game organisms on mount. */
2371
+ captureFrame?: () => string | null;
2372
+ /** Last neutral drawables list received by the active canvas host. */
2373
+ getLastDrawables?: () => DrawableDescriptor[] | null;
2374
+ /** Asset-url → load-status map. Populated by game organisms. */
2375
+ assetStatus?: Record<string, AssetLoadStatus>;
2376
+ /** Rolling event bus log. Populated by `bindEventBus`. */
2377
+ eventLog?: EventLogEntry[];
2378
+ /**
2379
+ * Per-page-load nonce, set once when `bindEventBus` creates the log
2380
+ * (and bumped by `clearEventLog`). A verifier reading the log across
2381
+ * hermetic page reloads uses this — not the array length — to detect a
2382
+ * reset: the length can coincidentally refill to the same count after a
2383
+ * reload, which silently drops the post-reload delta. The epoch changing
2384
+ * is the only reliable reset signal.
2385
+ */
2386
+ eventLogEpoch?: string;
2387
+ /**
2388
+ * Count of entries evicted from the FRONT of the ring-buffered log this
2389
+ * page (see `MAX_EVENT_LOG`). The absolute index of `eventLog[i]` is
2390
+ * `eventLogDropped + i`, so a verifier can cursor by absolute position
2391
+ * even after eviction — the recent (driven) tail is never silently lost.
2392
+ */
2393
+ eventLogDropped?: number;
2394
+ /** Clear the event log in place (also bumps `eventLogEpoch`). */
2395
+ clearEventLog?: () => void;
2396
+ }
2397
+
2398
+ /**
2399
+ * Canonical SSE event types for the Almadar agent wire.
2400
+ *
2401
+ * These events are emitted by the rabit runtime (internal package
2402
+ * `@almadar-io/rabit`) and consumed by public SDK clients. Because the rabit
2403
+ * package is private, the SDK-relevant subset of the event surface is hoisted
2404
+ * here into `@almadar/core` so public consumers can type their `onEvent`
2405
+ * callbacks without depending on a private package.
2406
+ *
2407
+ * Rules for this file:
2408
+ * - Use only types already exported by `@almadar/core`.
2409
+ * - Do not import from `@almadar-io/rabit` or any other private package.
2410
+ * - Keep the discriminated union exhaustive over the included event types.
2411
+ */
2412
+
2413
+ type SSEEventType = 'start' | 'message' | 'tool_call' | 'tool_result' | 'todo_update' | 'todo_detail' | 'file_operation' | 'file_written' | 'schema_update' | 'generation_log' | 'subagent_event' | 'subagent_start' | 'subagent_progress' | 'subagent_complete' | 'interrupt' | 'error' | 'cancelled' | 'complete' | 'app_created' | 'schema_phase_validated' | 'schema_phase_update' | 'orbital_added' | 'orbital_schema_complete' | 'process_start' | 'process_complete' | 'process_error' | 'process_repair' | 'process_repair_complete' | 'params_repair_emitted' | 'changeset_recorded' | 'snapshot_created';
2414
+ interface SSEEventBase {
2415
+ type: SSEEventType;
2416
+ timestamp: number;
2417
+ }
2418
+ interface StartEvent extends SSEEventBase {
2419
+ type: 'start';
2420
+ data: {
2421
+ threadId: string;
2422
+ skill: string;
2423
+ workDir: string;
2424
+ };
2425
+ }
2426
+ interface MessageEvent extends SSEEventBase {
2427
+ type: 'message';
2428
+ data: {
2429
+ content: string;
2430
+ role: 'assistant' | 'user' | 'system';
2431
+ isComplete: boolean;
2432
+ };
2433
+ }
2434
+ interface ToolCallEvent extends SSEEventBase {
2435
+ type: 'tool_call';
2436
+ data: {
2437
+ tool: string;
2438
+ args: ToolArgs;
2439
+ };
2440
+ }
2441
+ interface ToolResultEvent extends SSEEventBase {
2442
+ type: 'tool_result';
2443
+ data: {
2444
+ tool: string;
2445
+ result: JsonValue;
2446
+ success: boolean;
2447
+ };
2448
+ }
2449
+ interface TodoUpdateEvent extends SSEEventBase {
2450
+ type: 'todo_update';
2451
+ data: {
2452
+ todos: Array<{
2453
+ id: string;
2454
+ task: string;
2455
+ status: 'pending' | 'in_progress' | 'completed';
2456
+ }>;
2457
+ };
2458
+ }
2459
+ type TodoActivityType = 'thinking' | 'tool_call' | 'tool_result' | 'code_change';
2460
+ interface TodoDetailEvent extends SSEEventBase {
2461
+ type: 'todo_detail';
2462
+ data: {
2463
+ todoId: string;
2464
+ activityType: TodoActivityType;
2465
+ content: string;
2466
+ tool?: string;
2467
+ args?: ToolArgs;
2468
+ success?: boolean;
2469
+ filePath?: string;
2470
+ diff?: string;
2471
+ };
2472
+ }
2473
+ interface FileOperationEvent extends SSEEventBase {
2474
+ type: 'file_operation';
2475
+ data: {
2476
+ operation: 'ls' | 'read_file' | 'write_file' | 'edit_file';
2477
+ path: string;
2478
+ success: boolean;
2479
+ };
2480
+ }
2481
+ interface FileWrittenEvent extends SSEEventBase {
2482
+ type: 'file_written';
2483
+ data: {
2484
+ path: string;
2485
+ fileType: 'schema' | 'orbital' | 'memory' | 'domain' | 'other';
2486
+ orbitalName?: string;
2487
+ };
2488
+ }
2489
+ interface SchemaUpdateEvent extends SSEEventBase {
2490
+ type: 'schema_update';
2491
+ data: {
2492
+ appId: string;
2493
+ version: number;
2494
+ schema: OrbitalSchema;
2495
+ isNew: boolean;
2496
+ snapshotId?: string;
2497
+ changesetId?: string;
2498
+ };
2499
+ }
2500
+ interface GenerationLogEvent extends SSEEventBase {
2501
+ type: 'generation_log';
2502
+ data: {
2503
+ level: 'info' | 'warn' | 'error' | 'debug';
2504
+ message: string;
2505
+ data?: JsonObject;
2506
+ orbitalName?: string;
2507
+ };
2508
+ }
2509
+ interface SubagentEvent extends SSEEventBase {
2510
+ type: 'subagent_event';
2511
+ data: {
2512
+ orbitalName: string;
2513
+ orbitalIndex: number;
2514
+ totalOrbitals: number;
2515
+ event: {
2516
+ type: Exclude<SSEEventType, 'subagent_event'>;
2517
+ data: JsonObject;
2518
+ timestamp: number;
2519
+ };
2520
+ };
2521
+ }
2522
+ interface SubagentStartEvent extends SSEEventBase {
2523
+ type: 'subagent_start';
2524
+ data: {
2525
+ subagentId: string;
2526
+ name: string;
2527
+ role: string;
2528
+ orbitalName?: string;
2529
+ parentId?: string;
2530
+ task: string;
2531
+ };
2532
+ }
2533
+ interface SubagentProgressEvent extends SSEEventBase {
2534
+ type: 'subagent_progress';
2535
+ data: {
2536
+ subagentId: string;
2537
+ orbitalName?: string;
2538
+ message: string;
2539
+ toolCall?: {
2540
+ tool: string;
2541
+ argsPreview?: string;
2542
+ };
2543
+ };
2544
+ }
2545
+ interface SubagentCompleteEvent extends SSEEventBase {
2546
+ type: 'subagent_complete';
2547
+ data: {
2548
+ subagentId: string;
2549
+ orbitalName?: string;
2550
+ success: boolean;
2551
+ durationMs: number;
2552
+ summary?: string;
2553
+ };
2554
+ }
2555
+ interface InterruptEvent extends SSEEventBase {
2556
+ type: 'interrupt';
2557
+ data: {
2558
+ threadId: string;
2559
+ actionRequests: Array<{
2560
+ tool: string;
2561
+ args: ToolArgs;
2562
+ allowedDecisions: ('approve' | 'edit' | 'reject')[];
2563
+ description?: string;
2564
+ }>;
2565
+ };
2566
+ }
2567
+ interface ErrorEvent extends SSEEventBase {
2568
+ type: 'error';
2569
+ data: {
2570
+ error: string;
2571
+ code?: string;
2572
+ /** Orbital names that failed, when a generation run ends in failure. */
2573
+ failedOrbitals?: string[];
2574
+ /** Typed validate/failure lines backing `error` (same format as `cache_demoted.errors`). */
2575
+ errors?: string[];
2576
+ };
2577
+ }
2578
+ interface CancelledEvent extends SSEEventBase {
2579
+ type: 'cancelled';
2580
+ data: {
2581
+ threadId: string;
2582
+ message: string;
2583
+ };
2584
+ }
2585
+ interface CompleteEvent extends SSEEventBase {
2586
+ type: 'complete';
2587
+ data: {
2588
+ threadId: string;
2589
+ skill: string;
2590
+ workDir: string;
2591
+ schemaGenerated: boolean;
2592
+ appCompiled: boolean;
2593
+ schema?: OrbitalSchema;
2594
+ appId?: string;
2595
+ schemaPersisted?: boolean;
2596
+ snapshotId?: string;
2597
+ changesetId?: string;
2598
+ };
2599
+ }
2600
+ interface AppCreatedEvent extends SSEEventBase {
2601
+ type: 'app_created';
2602
+ data: {
2603
+ appId: string;
2604
+ name?: string;
2605
+ orbitalCount?: number;
2606
+ fromOrbitalPersistence?: boolean;
2607
+ };
2608
+ }
2609
+ interface SchemaPhaseValidatedEvent extends SSEEventBase {
2610
+ type: 'schema_phase_validated';
2611
+ data: {
2612
+ appId: string;
2613
+ success: boolean;
2614
+ errors?: JsonValue[];
2615
+ };
2616
+ }
2617
+ interface SchemaPhaseUpdateEvent extends SSEEventBase {
2618
+ type: 'schema_phase_update';
2619
+ data: JsonObject;
2620
+ }
2621
+ interface OrbitalAddedEvent extends SSEEventBase {
2622
+ type: 'orbital_added';
2623
+ data: {
2624
+ appId: string;
2625
+ orbitalName: string;
2626
+ orbitalIndex: number;
2627
+ totalOrbitals: number;
2628
+ isNew?: boolean;
2629
+ orbitalSchema?: OrbitalDefinition;
2630
+ };
2631
+ }
2632
+ interface OrbitalSchemaCompleteEvent extends SSEEventBase {
2633
+ type: 'orbital_schema_complete';
2634
+ data: {
2635
+ appId: string;
2636
+ totalOrbitals: number;
2637
+ orbitalNames: string[];
2638
+ };
2639
+ }
2640
+ interface ProcessStartEvent extends SSEEventBase {
2641
+ type: 'process_start';
2642
+ data: {
2643
+ orbitalName: string;
2644
+ method: 'deterministic' | 'llm';
2645
+ behavior?: string;
2646
+ };
2647
+ }
2648
+ interface ProcessCompleteEvent extends SSEEventBase {
2649
+ type: 'process_complete';
2650
+ data: {
2651
+ orbitalName: string;
2652
+ method: 'deterministic' | 'llm';
2653
+ traitCount?: number;
2654
+ transitionCount?: number;
2655
+ duration?: number;
2656
+ };
2657
+ }
2658
+ interface ProcessErrorEvent extends SSEEventBase {
2659
+ type: 'process_error';
2660
+ data: {
2661
+ orbitalName: string;
2662
+ method: 'deterministic' | 'llm';
2663
+ error: string;
2664
+ /** Typed validate/failure lines for this orbital (from `orbital_failed.errors`). */
2665
+ errors?: string[];
2666
+ };
2667
+ }
2668
+ interface ProcessRepairEvent extends SSEEventBase {
2669
+ type: 'process_repair';
2670
+ data: {
2671
+ orbitalName: string;
2672
+ errorCount: number;
2673
+ attempt: number;
2674
+ };
2675
+ }
2676
+ interface ProcessRepairCompleteEvent extends SSEEventBase {
2677
+ type: 'process_repair_complete';
2678
+ data: {
2679
+ orbitalName: string;
2680
+ };
2681
+ }
2682
+ interface ParamsRepairEmittedEvent extends SSEEventBase {
2683
+ type: 'params_repair_emitted';
2684
+ data: {
2685
+ orbitalName: string;
2686
+ attempt: number;
2687
+ };
2688
+ }
2689
+ interface ChangesetRecordedEvent extends SSEEventBase {
2690
+ type: 'changeset_recorded';
2691
+ data: {
2692
+ appId: string;
2693
+ changesetId: string;
2694
+ version: number;
2695
+ trackingMode: 'initial' | 'update';
2696
+ summary: {
2697
+ added: number;
2698
+ modified: number;
2699
+ removed: number;
2700
+ };
2701
+ source?: string;
2702
+ };
2703
+ }
2704
+ interface SnapshotCreatedEvent extends SSEEventBase {
2705
+ type: 'snapshot_created';
2706
+ data: {
2707
+ appId: string;
2708
+ snapshotId: string;
2709
+ version: number;
2710
+ reason: string;
2711
+ };
2712
+ }
2713
+ type SSEEvent = StartEvent | MessageEvent | ToolCallEvent | ToolResultEvent | TodoUpdateEvent | TodoDetailEvent | FileOperationEvent | FileWrittenEvent | SchemaUpdateEvent | GenerationLogEvent | SubagentEvent | SubagentStartEvent | SubagentProgressEvent | SubagentCompleteEvent | InterruptEvent | ErrorEvent | CancelledEvent | CompleteEvent | AppCreatedEvent | SchemaPhaseValidatedEvent | SchemaPhaseUpdateEvent | OrbitalAddedEvent | OrbitalSchemaCompleteEvent | ProcessStartEvent | ProcessCompleteEvent | ProcessErrorEvent | ProcessRepairEvent | ProcessRepairCompleteEvent | ParamsRepairEmittedEvent | ChangesetRecordedEvent | SnapshotCreatedEvent;
2714
+
2715
+ /**
2716
+ * Living Orbital Schema — Golden Data Structure type system.
2717
+ *
2718
+ * The Living layer treats an `OrbitalSchema` as a heterogeneous attributed
2719
+ * graph: every vertex (orbital, entity, trait, state, transition, page, field,
2720
+ * event, effect, config-knob) carries a `SemanticAnnotation` + an embedding
2721
+ * vector, and the whole object can embed / validate / compile / similarity-
2722
+ * search / evolve itself. These are the canonical TYPE definitions shared by
2723
+ * the masar (Python) implementation and any TS implementation (rabit, Phase 5);
2724
+ * the numeric implementation lives outside @almadar/core.
2725
+ *
2726
+ * See `docs/Almadar_Masar_Golden_Data_Structure.md` §II/§III/§VIII. Existing
2727
+ * core vocabulary is reused, never re-defined: `SchemaChange`/`SemanticChangeKind`
2728
+ * (changeset.ts) back the evolution delta, `ValidationError`/`ValidationResult`
2729
+ * (validation.ts) back `validate()`, and the per-vertex payloads ARE the existing
2730
+ * structural types.
2731
+ *
2732
+ * @packageDocumentation
2733
+ */
2734
+
2735
+ /**
2736
+ * Decision-kind tier for the annotation layer. SUPERSET of the validator-
2737
+ * enforced `FactoryConfigTier` (`domain`/`policy`/`infra`/`presentation`/
2738
+ * `internal`), adding `essential` and `customization` for non-knob (event)
2739
+ * vertices that still carry the old vocabulary. Every `FactoryConfigTier`
2740
+ * value must be a member so `widenTier` stays a valid identity widen.
2741
+ */
2742
+ type AnnotationTier = "essential" | "domain" | "policy" | "infra" | "presentation" | "customization" | "internal";
2743
+ /** Widen a knob's `FactoryConfigTier` into the annotation-layer `AnnotationTier`. */
2744
+ declare function widenTier(tier: FactoryConfigTier): AnnotationTier;
2745
+ /**
2746
+ * The natural-language metadata attached to every living vertex — the text that
2747
+ * gets embedded for `similar()`/`match_intent()`. Today these four members live
2748
+ * scattered inline across core types (`EntityField.description`/`synonyms`,
2749
+ * `Event`/`TraitEventContract`.`description`/`synonyms`/`tier`,
2750
+ * `FactoryConfigParam.label`/`description`/`synonyms`/`tier`); `SemanticAnnotation`
2751
+ * is the uniform bundle of them, generalized to every vertex.
2752
+ */
2753
+ interface SemanticAnnotation {
2754
+ description: string;
2755
+ synonyms: string[];
2756
+ label: string;
2757
+ tier: AnnotationTier;
2758
+ }
2759
+ /**
2760
+ * A dense semantic embedding. In-memory form is `Float32Array`; the at-rest
2761
+ * JSON form (e.g. rabit's `knob-embeddings.json`) is `number[]`.
2762
+ */
2763
+ type SemanticVector = Float32Array;
2764
+ /** A probability in `[0, 1]`. */
2765
+ type Probability = number;
2766
+ /** Whether a semantic gate's transition is open, closed, or ~0.5 ambiguous. */
2767
+ type GateState = "open" | "closed" | "ambiguous";
2768
+ /** The typed vertex kinds of the living attributed graph (§II.1 `V_*`). */
2769
+ type VertexType = "orbital" | "entity" | "trait" | "state" | "transition" | "page" | "field" | "event" | "effect" | "value";
2770
+ /**
2771
+ * A stable, structural, embedding-independent vertex id (path style, e.g.
2772
+ * `orb:Cart/trt:AddItem/st:Open`). Re-embedding never changes it.
2773
+ */
2774
+ type VertexId = string;
2775
+ /** The typed directed edge kinds of the living attributed graph (§II.1 `E_*`). */
2776
+ type EdgeType = "belongs_to" | "has_trait" | "has_state" | "has_transition" | "from_state" | "to_state" | "on_event" | "emits" | "listens" | "cross_orbital" | "has_effect" | "effect_seq" | "data_flow" | "ref_in_effect" | "has_page" | "has_field" | "ref";
2777
+ /**
2778
+ * An effect vertex's payload. Effects are positional S-expression tuples
2779
+ * (`Effect`), so the synthesized coordinates (operator, owning transition,
2780
+ * positional index) carry the addressing the raw tuple lacks.
2781
+ */
2782
+ interface EffectPayload {
2783
+ sexpr: Effect;
2784
+ operator: string;
2785
+ transitionId: VertexId;
2786
+ index: number;
2787
+ }
2788
+ /**
2789
+ * A config-knob vertex's payload — joins a `Trait.config` dict key with its
2790
+ * declaration (no single core type carries both).
2791
+ */
2792
+ interface KnobPayload {
2793
+ name: string;
2794
+ declaration: ConfigFieldDeclaration;
2795
+ traitId: VertexId;
2796
+ }
2797
+ /** The union of every kind of vertex payload (the existing structural types). */
2798
+ type VertexPayload = OrbitalDefinition | Entity | Trait | State | Transition | Page | EntityField | Event | EffectPayload | KnobPayload;
2799
+ /**
2800
+ * One vertex of the living graph: a structural payload plus its annotation and
2801
+ * embedding. Identity is `id` (structural); annotation/embedding are derived.
2802
+ */
2803
+ interface LivingVertex<P extends VertexPayload = VertexPayload> {
2804
+ id: VertexId;
2805
+ vtype: VertexType;
2806
+ payload: P;
2807
+ annotation: SemanticAnnotation;
2808
+ /** Lazily populated — undefined until the schema's `embed()` runs. */
2809
+ embedding?: SemanticVector;
2810
+ }
2811
+ type LivingOrbital = LivingVertex<OrbitalDefinition>;
2812
+ type LivingEntity = LivingVertex<Entity>;
2813
+ type LivingTrait = LivingVertex<Trait>;
2814
+ type LivingState = LivingVertex<State>;
2815
+ type LivingTransition = LivingVertex<Transition>;
2816
+ type LivingPage = LivingVertex<Page>;
2817
+ type LivingField = LivingVertex<EntityField>;
2818
+ type LivingEvent = LivingVertex<Event>;
2819
+ type LivingEffect = LivingVertex<EffectPayload>;
2820
+ type LivingValue = LivingVertex<KnobPayload>;
2821
+ /**
2822
+ * One directed edge. `via` carries the transition vertex for the ternary
2823
+ * `has_transition(from, via, to)` decomposition; `seq` carries the ordering for
2824
+ * `effect_seq`.
2825
+ */
2826
+ interface LivingEdge {
2827
+ etype: EdgeType;
2828
+ src: VertexId;
2829
+ dst: VertexId;
2830
+ via?: VertexId;
2831
+ seq?: number;
2832
+ }
2833
+ /**
2834
+ * A single evolution step over the living graph. `modified` reuses the canonical
2835
+ * `SchemaChange` (changeset.ts) rather than inventing a parallel operation enum;
2836
+ * `intent` is the natural-language delta that caused the change.
2837
+ */
2838
+ interface EvolutionDelta {
2839
+ added: VertexId[];
2840
+ removed: VertexId[];
2841
+ modified: SchemaChange[];
2842
+ intent: string;
2843
+ }
2844
+ /** One immutable entry in a living schema's evolution lineage (§6.2). */
2845
+ interface LineageEntry {
2846
+ root: string;
2847
+ parent: string;
2848
+ delta: EvolutionDelta;
2849
+ intent: string;
2850
+ time: number;
2851
+ valid: boolean;
2852
+ }
2853
+ /** The result of simulating one effect's S-expression (§4.6) — pure, no I/O. */
2854
+ interface EffectResult {
2855
+ result: SExpr;
2856
+ sideEffects: string[];
2857
+ emittedEvents: string[];
2858
+ }
2859
+ /**
2860
+ * The operation surface of a living orbital schema. This interface is the shared
2861
+ * CONTRACT; the numeric implementation (embedding, cosine, validator shelling)
2862
+ * is language-specific. `compile()` is the bridge back to the canonical
2863
+ * `OrbitalSchema` (the ML surface — annotations beyond `description`, embeddings,
2864
+ * gates — is stripped).
2865
+ */
2866
+ interface LivingOrbitalSchema {
2867
+ orbitals: LivingOrbital[];
2868
+ addOrbital(name: string): LivingOrbital;
2869
+ removeOrbital(name: string): void;
2870
+ getOrbital(name: string): LivingOrbital;
2871
+ annotations: Map<VertexId, SemanticAnnotation>;
2872
+ embeddings: Map<VertexId, SemanticVector>;
2873
+ embed(): void;
2874
+ compile(): OrbitalSchema;
2875
+ validate(): ValidationResult;
2876
+ similar(query: string | SemanticVector, k: number, type?: VertexType): LivingVertex[];
2877
+ matchIntent(intent: string, threshold?: number): {
2878
+ vertex: LivingVertex;
2879
+ score: number;
2880
+ }[];
2881
+ predictConfig(intent: string, trait: Trait): Record<string, TraitConfigValue>;
2882
+ predictPresence(intent: string): Set<string>;
2883
+ suggestOrbital(intent: string): LivingOrbital[];
2884
+ suggestEntity(intent: string): LivingEntity[];
2885
+ suggestTrait(intent: string): LivingTrait[];
2886
+ evolve(intentDelta: string): LivingOrbitalSchema;
2887
+ compose(other: LivingOrbitalSchema): LivingOrbitalSchema;
2888
+ repair(errors: ValidationError[]): LivingOrbitalSchema;
2889
+ wireEvents(source: LivingEvent, target: LivingEvent): void;
2890
+ findWiringGaps(): LivingEvent[];
2891
+ simulateEffect(effect: LivingEffect, context: EvalContext): EffectResult;
2892
+ simulateInteraction(effect: LivingEffect, path: string[]): {
2893
+ event: LivingEvent;
2894
+ payload: EventPayload;
2895
+ };
2896
+ traceDataFlow(transition: LivingTransition, inputEntity: LivingEntity): LivingEffect[];
2897
+ evaluateGates(intentEmbedding: SemanticVector): Map<VertexId, GateState[]>;
2898
+ sampleTrajectory(intentEmbedding: SemanticVector, steps: number): LivingVertex[];
2899
+ lineage: LineageEntry[];
2900
+ checkout(hash: string): LivingOrbitalSchema;
2901
+ diff(hash1: string, hash2: string): EvolutionDelta;
2902
+ }
2903
+
2904
+ /**
2905
+ * Parsed AST — LLM-emit relaxed views of the canonical orbital types.
2906
+ *
2907
+ * Every `Parsed*` type mirrors its canonical counterpart in this module
2908
+ * (`Trait`, `StateMachine`, `Transition`, `State`, `Event`, `OrbitalDefinition`,
2909
+ * `PageRefObject`, etc.) but loosens required fields to optional. The
2910
+ * loosening exists for one reason: the LLM can emit a partial orbital
2911
+ * (mid-stream, mid-tool-call, mid-LoLo lowering) and consumer code
2912
+ * needs to walk it WITHOUT casting to the strict canonical type before
2913
+ * every field access.
2914
+ *
2915
+ * Discipline:
2916
+ *
2917
+ * - **No `unknown`.** Every field has a concrete type, sourced from
2918
+ * this same module where the type already exists (`EntityField`,
2919
+ * `EntityPersistence`, `TraitCategory`, `TraitScope`, `SExpr`,
2920
+ * `PageTraitRef`, `TraitEventContract`, `TraitEventListener`).
2921
+ *
2922
+ * - **No index signatures.** If the LLM emits a key the schema doesn't
2923
+ * know about, the validator rejects it. The `Parsed*` types do not
2924
+ * pretend to accept unknown keys at the type level.
2925
+ *
2926
+ * - **Required fields stay required.** `name` on `ParsedOrbital` is
2927
+ * required because no orbital can exist without one. `name` /
2928
+ * `linkedEntity` on `ParsedTrait` are required because the orbital
2929
+ * compiler rejects traits missing either. Only fields the LLM
2930
+ * legitimately omits during construction are optional.
2931
+ *
2932
+ * Use site: walkers that observe an orbital before it's fully
2933
+ * validated. Construct it as `ParsedOrbital`, narrow to
2934
+ * `OrbitalDefinition` after validation.
2935
+ *
2936
+ * @packageDocumentation
2937
+ */
2938
+
2939
+ /**
2940
+ * Top-level orbital as the LLM emits it. Relaxed view of
2941
+ * `OrbitalDefinition`: traits and pages may be partial, the domain
2942
+ * context + design hints may be missing.
2943
+ */
2944
+ interface ParsedOrbital {
2945
+ name: string;
2946
+ entity: ParsedEntity;
2947
+ traits: ParsedTrait[];
2948
+ pages: ParsedPage[];
2949
+ domainContext?: ParsedDomainContext;
2950
+ design?: ParsedDesign;
2951
+ }
2952
+ /**
2953
+ * Entity nucleus of an orbital. `name` + `fields` are required; the
2954
+ * factory canonical defaults can fill `persistence` and `collection`
2955
+ * when omitted.
2956
+ */
2957
+ interface ParsedEntity {
2958
+ name: string;
2959
+ fields: EntityField[];
2960
+ persistence?: EntityPersistence;
2961
+ collection?: string;
2962
+ }
2963
+ /**
2964
+ * One trait on an orbital. `name` + `linkedEntity` are required (the
2965
+ * compiler rejects either omission); state machine + scope + category
2966
+ * are filled by defaults when the LLM doesn't specify them.
2967
+ */
2968
+ interface ParsedTrait {
2969
+ name: string;
2970
+ linkedEntity: string;
2971
+ category?: TraitCategory;
2972
+ scope?: TraitScope;
2973
+ description?: string;
2974
+ config?: ParsedTraitConfig;
2975
+ emits?: ParsedEmitDeclaration[];
2976
+ listens?: ParsedListenDeclaration[];
2977
+ stateMachine?: ParsedStateMachine;
2978
+ capabilities?: string[];
2979
+ }
2980
+ /**
2981
+ * Trait `config { }` block — the LLM-emit shape carries each declared
2982
+ * config key as a typed value drawn from the JSON primitive set. A
2983
+ * stricter view (`DeclaredTraitConfig` in `trait.ts`) captures the
2984
+ * authored field descriptors with type+default+label+tier metadata;
2985
+ * `ParsedTraitConfig` is the in-flight value map.
2986
+ */
2987
+ type ParsedTraitConfig = {
2988
+ [key: string]: string | number | boolean | null | ReadonlyArray<string | number | boolean | null>;
2989
+ };
2990
+ /**
2991
+ * State-machine of a trait. Every field optional because the LLM may
2992
+ * emit the trait header before its body. A canonical
2993
+ * `StateMachine` (`state-machine.ts`) requires at least one state +
2994
+ * one transition.
2995
+ */
2996
+ interface ParsedStateMachine {
2997
+ states?: ParsedState[];
2998
+ events?: ParsedEvent[];
2999
+ transitions?: ParsedTransition[];
3000
+ initial?: string;
3001
+ }
3002
+ /**
3003
+ * One state of a `ParsedStateMachine`. Mirrors `State` from
3004
+ * `state-machine.ts` with name optional during construction.
3005
+ */
3006
+ interface ParsedState {
3007
+ name?: string;
3008
+ isInitial?: boolean;
3009
+ }
3010
+ /**
3011
+ * One event of a `ParsedStateMachine`. Mirrors `Event` from
3012
+ * `state-machine.ts`. `payloadSchema` is the canonical shape — an
3013
+ * array of `EntityField`s describing the event's payload.
3014
+ */
3015
+ interface ParsedEvent {
3016
+ key?: string;
3017
+ name?: string;
3018
+ payloadSchema?: EntityField[];
3019
+ }
3020
+ /**
3021
+ * One transition of a `ParsedStateMachine`. `effects` + `guard` use
3022
+ * `SExpr` from `expression.ts` — the canonical S-expression shape the
3023
+ * runtime evaluates.
3024
+ */
3025
+ interface ParsedTransition {
3026
+ from?: string;
3027
+ to?: string;
3028
+ event?: string;
3029
+ effects?: SExpr[];
3030
+ guard?: SExpr;
3031
+ }
3032
+ /**
3033
+ * Trait-emit declaration. Aliases `TraitEventContract` from
3034
+ * `trait.ts` with every field optional. The canonical contract
3035
+ * carries `event`, `scope`, `payload`; here all three are optional so
3036
+ * an in-flight emit (just the name, no payload yet) types correctly.
3037
+ */
3038
+ interface ParsedEmitDeclaration {
3039
+ event?: string;
3040
+ scope?: 'internal' | 'external';
3041
+ payload?: EntityField[];
3042
+ }
3043
+ /**
3044
+ * Trait-listen declaration. Mirrors `TraitEventListener` from
3045
+ * `trait.ts` with the source remap and trigger key optional.
3046
+ */
3047
+ interface ParsedListenDeclaration {
3048
+ event?: string;
3049
+ triggers?: string;
3050
+ scope?: 'internal' | 'external';
3051
+ payloadMapping?: {
3052
+ [key: string]: SExpr;
3053
+ };
3054
+ }
3055
+ /**
3056
+ * One page entry on an orbital. Mirrors `PageRefObject` /
3057
+ * `OrbitalPage`; `path` is the URL, `name` is the canonical
3058
+ * identifier the molecule references.
3059
+ */
3060
+ interface ParsedPage {
3061
+ path?: string;
3062
+ name?: string;
3063
+ primaryEntity?: string;
3064
+ traits?: PageTraitRef[];
3065
+ }
3066
+ /**
3067
+ * Domain-context decorations the analyzer attaches to an orbital
3068
+ * (vocabulary, category, original request). Mirrors `DomainContext`
3069
+ * from `domain.ts` for the fields used in the parsed-AST surface; the
3070
+ * full `DomainContext` carries semantic-role overlays + custom-pattern
3071
+ * maps too, which the LLM doesn't emit in this surface.
3072
+ */
3073
+ interface ParsedDomainContext {
3074
+ request?: string;
3075
+ category?: string;
3076
+ vocabulary?: {
3077
+ [key: string]: string;
3078
+ };
3079
+ }
3080
+ /**
3081
+ * Design hints (style + UX cues) the analyzer attaches. Mirrors
3082
+ * `DesignPreferences` from `domain.ts`.
3083
+ */
3084
+ interface ParsedDesign {
3085
+ style?: string;
3086
+ uxHints?: {
3087
+ [key: string]: string;
3088
+ };
3089
+ }
3090
+
3091
+ /**
3092
+ * Render-UI structural editing — the single canonical pattern-tree navigator,
3093
+ * mutators, and overlay application. Promoted out of apps/builder so the studio
3094
+ * client, rabit's contextual-edit path, and the overlay replay share ONE
3095
+ * implementation (no shadow copies).
3096
+ *
3097
+ * Operates on the SERIALIZABLE structural pattern node — the resolved `.orb`
3098
+ * render-ui shape (`{ type, children, ...props }`, props are strings/numbers/
3099
+ * booleans/bindings/arrays). It never holds function-typed props: those exist
3100
+ * only in the React-component `AnyPatternConfig`, never in resolved IR. A node
3101
+ * to insert/swap is built as a structural literal and validated against the
3102
+ * pattern registry by the caller — `AnyPatternConfig` is never assigned in.
3103
+ */
3104
+
3105
+ /** A serializable value inside a render-ui pattern node. No functions. */
3106
+ type PatternValue = string | number | boolean | Date | null | undefined | PatternNode | readonly PatternValue[];
3107
+ /** One node in a render-ui pattern tree as it appears in resolved `.orb`. */
3108
+ interface PatternNode {
3109
+ type?: string;
3110
+ children?: PatternNode[];
3111
+ [prop: string]: PatternValue | PatternNode[] | undefined;
3112
+ }
3113
+ type EditFocusLevel = 'node' | 'slot' | 'field' | 'effect' | 'trait' | 'page' | 'orbital';
3114
+ /** A pointed-at element. Plain data — constructible with or without a DOM. */
3115
+ interface EditFocus {
3116
+ level: EditFocusLevel;
3117
+ orbital: string;
3118
+ trait?: string;
3119
+ transition?: string;
3120
+ state?: string;
3121
+ slot?: string;
3122
+ path?: string;
3123
+ patternType?: string;
3124
+ entity?: string;
3125
+ source?: string;
3126
+ label: string;
3127
+ }
3128
+ type RenderUiPatchOp = 'replace' | 'insert' | 'remove' | 'set-prop' | 'rebind';
3129
+ interface RenderUiPatchAddress {
3130
+ trait: string;
3131
+ transition: string;
3132
+ state?: string;
3133
+ slot: string;
3134
+ /** patternPath, e.g. `root.children.2`. For `insert`, the PARENT path. */
3135
+ path: string;
3136
+ }
3137
+ interface RenderUiPatch {
3138
+ op: RenderUiPatchOp;
3139
+ address: RenderUiPatchAddress;
3140
+ /** Structural fingerprint of the pre-edit node, used to re-anchor the patch
3141
+ * if a later factory rebuild shifts `address.path`. */
3142
+ fingerprint?: string;
3143
+ /** For `replace` / `insert`: the concrete node to place. */
3144
+ node?: PatternNode;
3145
+ /** For `insert`: index within the parent's children (default: append). */
3146
+ index?: number;
3147
+ /** For `set-prop` / `rebind`: the prop key. */
3148
+ prop?: string;
3149
+ /** For `set-prop`: the new value. For `rebind`: pass the binding via `value`. */
3150
+ value?: PatternValue;
3151
+ }
3152
+ /** Navigate a dot-separated path (`root`, `root.children.0`, …) to a node. */
3153
+ declare function navigatePatternPath(root: PatternNode, path: string): PatternNode | null;
3154
+ /** Set a prop on the node at `path`. Returns false if the path misses. */
3155
+ declare function setPropAtPath(root: PatternNode, path: string, prop: string, value: PatternValue): boolean;
3156
+ /** Replace the node at a child path (`<parent>.children.<i>`) with `node`. */
3157
+ declare function replaceChildAtPath(root: PatternNode, path: string, node: PatternNode): boolean;
3158
+ /** Insert `node` into the parent's `children` at `index` (clamped to end). */
3159
+ declare function insertChildAtPath(root: PatternNode, parentPath: string, index: number, node: PatternNode): boolean;
3160
+ /** Remove the node at a child path. */
3161
+ declare function removeChildAtPath(root: PatternNode, path: string): boolean;
3162
+ /** Deterministic structural fingerprint of a node (excludes child contents;
3163
+ * identifies the base node so a patch can re-anchor after a path shift). */
3164
+ declare function fingerprintNode(node: PatternNode): string;
3165
+ interface RenderOverlayResult {
3166
+ applied: number;
3167
+ /** Patches whose target node could not be resolved (path gone + fingerprint
3168
+ * unmatched). Surfaced as `patch_stale` — never silently dropped. */
3169
+ stale: RenderUiPatch[];
3170
+ }
3171
+ /**
3172
+ * Replay render-ui patches onto a resolved orbital, in place. Deterministic:
3173
+ * given the same base + patches, produces the same tree. Patches that cannot be
3174
+ * anchored are returned in `stale` (never silently dropped or misapplied).
3175
+ */
3176
+ declare function applyRenderOverlay(orbital: OrbitalDefinition, patches: readonly RenderUiPatch[]): RenderOverlayResult;
3177
+
3178
+ export { DEFAULT_INTERACTION_MODELS as $, ANONYMOUS_USER as A, BINDING_CONTEXT_RULES as B, type ChangesetValue as C, type BridgeHealth as D, type BuilderResult as E, type BusEvent as F, type BusEventListener as G, type BusEventSource as H, type CancelledEvent as I, type ChangeAuthor as J, type ChangeSetDocument as K, type ChangeSummary as L, type ChangesetRecordedEvent as M, type CheckStatus as N, type Clarification as O, type PageContentReduction as P, type ClarificationCandidate as Q, type ResolvedIR as R, type SchemaChange as S, type ClarificationLevel as T, type CompleteEvent as U, type ComplexityAssessment as V, type ComposeAllResult as W, type ComposeChildrenResult as X, type ComposeOptions as Y, type ContextExtensions as Z, type CreateFlow as _, type ResolvedEntity as a, type OrbitalSchemaCompleteEvent as a$, DEFAULT_VIEWER as a0, DEV_TOKEN_PREFIX as a1, type DeleteFlow as a2, type DispatchUpdatesResult as a3, type DrawableDescriptor as a4, type EdgeType as a5, type EditFlow as a6, type EditFocus as a7, type EditFocusLevel as a8, type EffectPayload as a9, type LLMErrorContext as aA, type LazyService as aB, type LineageEntry as aC, type ListInteraction as aD, type LivingEdge as aE, type LivingEffect as aF, type LivingEntity as aG, type LivingEvent as aH, type LivingField as aI, type LivingOrbital as aJ, type LivingOrbitalSchema as aK, type LivingPage as aL, type LivingState as aM, type LivingTrait as aN, type LivingTransition as aO, type LivingValue as aP, type LivingVertex as aQ, type LlmCallToolsResult as aR, type LlmContext as aS, type LlmMessage as aT, type LlmTokenUsage as aU, type LlmToolCall as aV, type LlmToolDef as aW, type LoloEmitResult as aX, type MemoryContext as aY, type MessageEvent as aZ, type OrbitalAddedEvent as a_, type EffectResult as aa, type EffectTrace as ab, type ErrorEvent as ac, type EventEmit as ad, type EventKey as ae, type EventListen as af, type EventLogEntry as ag, type EvolutionDelta as ah, type ExecutePlanResult as ai, type ExtraTraitRef as aj, type FileOperationEvent as ak, type FileWrittenEvent as al, type GateState as am, type GenerationLogEvent as an, type GitHubIssue as ao, type GitHubLink as ap, type GitHubRepo as aq, type HistoryMeta as ar, type IntegrationContext as as, type InteractionModel as at, type InteractionModelInput as au, InteractionModelSchema as av, type InterruptEvent as aw, KNOWN_VALIDATION_ERROR_CODES as ax, type KnobPayload as ay, type KnownValidationErrorCode as az, type ResolvedPage as b, type ServiceAction as b$, type OrbitalVerificationAPI as b0, type ParamsRepairEmittedEvent as b1, type ParsedDesign as b2, type ParsedDomainContext as b3, type ParsedEmitDeclaration as b4, type ParsedEntity as b5, type ParsedEvent as b6, type ParsedListenDeclaration as b7, type ParsedOrbital as b8, type ParsedPage as b9, type ResolvedEntityBinding as bA, type ResolvedField as bB, type ResolvedNavigation as bC, type ResolvedPattern as bD, type ResolvedSection as bE, type ResolvedSectionEvent as bF, type ResolvedTraitBinding as bG, type ResolvedTraitDataEntity as bH, type ResolvedTraitEvent as bI, type ResolvedTraitGuard as bJ, type ResolvedTraitListener as bK, type ResolvedTraitState as bL, type ResolvedTraitTick as bM, type ResolvedTraitTransition as bN, type ResolvedTraitUIBinding as bO, type SSEEvent as bP, type SSEEventBase as bQ, type SSEEventType as bR, type SaveOptions as bS, type SaveResult as bT, type SchemaPhaseUpdateEvent as bU, type SchemaPhaseValidatedEvent as bV, type SchemaUpdateEvent as bW, type SemanticAnnotation as bX, type SemanticChangeKind as bY, type SemanticVector as bZ, type ServerResponseTrace as b_, type ParsedState as ba, type ParsedStateMachine as bb, type ParsedTrait as bc, type ParsedTraitConfig as bd, type ParsedTransition as be, type PatternNode as bf, PatternTypeSchema as bg, type PatternValue as bh, type PersistActionName as bi, type PlanSnapshot as bj, type PlanSnapshotStatus as bk, type PlannerResult as bl, type Probability as bm, type ProcessCompleteEvent as bn, type ProcessErrorEvent as bo, type ProcessRepairCompleteEvent as bp, type ProcessRepairEvent as bq, type ProcessStartEvent as br, RENDER_BINDING_MARKER as bs, type RawUserClaims as bt, type RenderBindingMarker as bu, type RenderOverlayResult as bv, type RenderUiPatch as bw, type RenderUiPatchAddress as bx, type RenderUiPatchOp as by, type RepairResult as bz, type ResolvedTrait as c, isKnownValidationErrorCode as c$, type ServiceActionName as c0, type ServiceCallResult as c1, type ServiceContract as c2, type ServiceEvents as c3, type SessionContext as c4, type SessionHistoryEntry as c5, type SnapshotCreatedEvent as c6, type SnapshotDocument as c7, type SpawnResult as c8, type StartEvent as c9, type ValidationMeta as cA, type ValidationResult as cB, type ValidationResults as cC, type VerificationCheck as cD, type VerificationSnapshot as cE, type VerificationSummary as cF, type VertexId as cG, type VertexPayload as cH, type VertexType as cI, type ViewFlow as cJ, type WorkspaceContext as cK, applyRenderOverlay as cL, containsEntityBinding as cM, containsPayloadBinding as cN, createEmptyResolvedPage as cO, createEmptyResolvedTrait as cP, createLazyService as cQ, createResolvedField as cR, createTypedEventBus as cS, decodeDevIdentityToken as cT, encodeDevIdentityToken as cU, findPersonaInRoster as cV, fingerprintNode as cW, getBindingExamples as cX, getInteractionModelForDomain as cY, inferTsType as cZ, insertChildAtPath as c_, type StatsView as ca, type StoreContract as cb, type StoreFilter as cc, type StoreFilterOp as cd, type SubagentCompleteEvent as ce, type SubagentEvent as cf, type SubagentProgressEvent as cg, type SubagentStartEvent as ch, type TodoActivityType as ci, type TodoDetailEvent as cj, type TodoUpdateEvent as ck, type ToolCallEvent as cl, type ToolResultEvent as cm, type TraceContext as cn, type TraitFieldRef as co, TraitFieldRefSchema as cp, type TraitStateSnapshot as cq, type TransitionFrom as cr, type TransitionTrace as cs, type Unsubscribe as ct, type UserContext as cu, type ValidateResult as cv, type ValidationDocument as cw, type ValidationError as cx, type ValidationErrorCode as cy, type ValidationIssue as cz, type CategorizedRemovals as d, isPlanSnapshot as d0, isRenderBindingMarker as d1, isResolvedIR as d2, isSessionHistoryEntry as d3, isTraitFieldRef as d4, navigatePatternPath as d5, normalizeUserContext as d6, personaFromIdentityRow as d7, removeChildAtPath as d8, replaceChildAtPath as d9, resolveDefaultViewer as da, resolvePersonaSpec as db, setPropAtPath as dc, toBindingRoot as dd, validateBindingInContext as de, widenTier as df, type SemanticSchemaChange as e, type AgentCodeSearchResult as f, type AgentCompactResult as g, type AgentCompactStrategy as h, type AgentContext as i, type AgentGenerateOptions as j, type AgentMemoryCategory as k, type AgentMemoryRecord as l, type AnalysisOrbital as m, type AnalysisOrbitalParams as n, type AnalysisPageOverride as o, type AnalysisRename as p, type AnalysisResult as q, type AnnotationTier as r, type AppCreatedEvent as s, type AppSummary as t, type AssetLoadStatus as u, BINDING_DOCS as v, BINDING_ROOTS as w, type BindingContext as x, type BindingRoot as y, BindingSchema as z };