@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.
- package/dist/builders.d.ts +3 -3
- package/dist/builders.js +5 -2
- package/dist/builders.js.map +1 -1
- package/dist/{effect-BH2k4oK6.d.ts → effect-CK9fn56C.d.ts} +30 -7
- package/dist/{entityAccess-QAurFO7l.d.ts → entityAccess-pgfWacod.d.ts} +1 -1
- package/dist/factory/index.d.ts +4 -4
- package/dist/factory/index.js +2 -0
- package/dist/factory/index.js.map +1 -1
- package/dist/factory-runtime/index.d.ts +3 -3
- package/dist/factory-runtime/index.js +5 -2
- package/dist/factory-runtime/index.js.map +1 -1
- package/dist/index-DMUBu17o.d.ts +3178 -0
- package/dist/index.d.ts +11 -98
- package/dist/index.js +841 -63
- package/dist/index.js.map +1 -1
- package/dist/mock/index.d.ts +4 -4
- package/dist/mock/index.js +8 -2
- package/dist/mock/index.js.map +1 -1
- package/dist/patterns/component-mapping.json +1 -1
- package/dist/patterns/event-contracts.json +1 -1
- package/dist/patterns/index.d.ts +1720 -76
- package/dist/patterns/index.js +829 -60
- package/dist/patterns/index.js.map +1 -1
- package/dist/patterns/patterns-registry.json +827 -58
- package/dist/patterns/registry.json +827 -58
- package/dist/{schema-Sk_irLOY.d.ts → schema-CVTOy4at.d.ts} +506 -506
- package/dist/{trait-Bw4nWHu1.d.ts → trait-BjPraUgs.d.ts} +2 -2
- package/dist/types/index.d.ts +8 -3095
- package/dist/types/index.js +10 -3
- package/dist/types/index.js.map +1 -1
- package/dist/{types-D71hY_4A.d.ts → types-Dopw3s2O.d.ts} +3 -3
- package/package.json +1 -1
|
@@ -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 };
|