@almadar/core 4.4.2 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builders.d.ts +47 -3
- package/dist/builders.js +159 -27
- package/dist/builders.js.map +1 -1
- package/dist/{compose-behaviors-Da0YDcli.d.ts → compose-behaviors-Bp32KayC.d.ts} +1 -1
- package/dist/domain-language/index.d.ts +1 -1
- package/dist/domain-language/index.js +57 -26
- package/dist/domain-language/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +60 -26
- package/dist/index.js.map +1 -1
- package/dist/{schema-B0Yin-RM.d.ts → schema-CLFPg1xW.d.ts} +98 -47
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +57 -26
- package/dist/types/index.js.map +1 -1
- package/package.json +6 -6
package/dist/builders.d.ts
CHANGED
|
@@ -1,8 +1,52 @@
|
|
|
1
|
-
import { T as TraitEventContract, E as EntityField,
|
|
2
|
-
export { C as ComposeBehaviorsInput, a as ComposeBehaviorsResult, E as EventWiringEntry, L as LayoutStrategy, b as applyEventWiring, c as composeBehaviors, d as detectLayoutStrategy } from './compose-behaviors-
|
|
1
|
+
import { T as TraitReference, a as TraitEventContract, E as EntityField, b as EntityPersistence, c as EntityRow, O as OrbitalDefinition, d as OrbitalSchema, e as Trait, f as Entity, P as Page } from './schema-CLFPg1xW.js';
|
|
2
|
+
export { C as ComposeBehaviorsInput, a as ComposeBehaviorsResult, E as EventWiringEntry, L as LayoutStrategy, b as applyEventWiring, c as composeBehaviors, d as detectLayoutStrategy } from './compose-behaviors-Bp32KayC.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import '@almadar/patterns';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Explode Behavior Composition
|
|
8
|
+
*
|
|
9
|
+
* Human-authoring primitive (Phase 5.3 of Almadar_Agent_Behaviors_Plan).
|
|
10
|
+
*
|
|
11
|
+
* Reads a behavior's compiled `.orb` from the sibling `@almadar/std`
|
|
12
|
+
* registry on disk and returns the flat list of `TraitReference` objects
|
|
13
|
+
* it's composed from — each with `from`, `ref`, `linkedEntity`, and any
|
|
14
|
+
* call-site overrides. **Not exposed to the agent or LLM.** The helper
|
|
15
|
+
* exists for developers designing new molecules or debugging compositions.
|
|
16
|
+
*
|
|
17
|
+
* The function is Node-only. It walks the filesystem under
|
|
18
|
+
* `packages/almadar-std/behaviors/registry/{atoms,molecules,organisms}/`
|
|
19
|
+
* relative to this source file and will throw a descriptive error if the
|
|
20
|
+
* behavior cannot be resolved.
|
|
21
|
+
*
|
|
22
|
+
* When the target is a leaf atom (no `uses:` / composition), the function
|
|
23
|
+
* returns a single synthetic `TraitReference` pointing at the atom's own
|
|
24
|
+
* inline trait so consumers always get something useful.
|
|
25
|
+
*
|
|
26
|
+
* @packageDocumentation
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Flatten a behavior's `.orb` composition into the list of
|
|
31
|
+
* `TraitReference` objects it's built from.
|
|
32
|
+
*
|
|
33
|
+
* For composed behaviors (molecules, organisms) this returns every
|
|
34
|
+
* `TraitReference` entry from every orbital's `traits:` array, carrying
|
|
35
|
+
* the call-site `ref`, backfilled `from` (looked up against the orbital's
|
|
36
|
+
* `uses:` imports when omitted), `linkedEntity`, `events`, `effects`, and
|
|
37
|
+
* any other override fields declared at the call site.
|
|
38
|
+
*
|
|
39
|
+
* For leaf atoms (no composition, only an inline trait) the function
|
|
40
|
+
* returns a single synthetic `TraitReference` pointing at the atom's own
|
|
41
|
+
* trait, so consumers always get a non-empty array they can iterate.
|
|
42
|
+
*
|
|
43
|
+
* @param behaviorName - Registry name of the behavior (e.g. `"std-cart"`,
|
|
44
|
+
* `"std-browse"`).
|
|
45
|
+
* @returns Flat list of every `TraitReference` the behavior is composed of.
|
|
46
|
+
* @throws Error when the behavior cannot be found in any registry level.
|
|
47
|
+
*/
|
|
48
|
+
declare function explodeBehaviorComposition(behaviorName: string): TraitReference[];
|
|
49
|
+
|
|
6
50
|
/**
|
|
7
51
|
* Orbital Builders
|
|
8
52
|
*
|
|
@@ -103,4 +147,4 @@ declare function compose(orbitals: (OrbitalDefinition | OrbitalSchema)[], pages:
|
|
|
103
147
|
*/
|
|
104
148
|
declare function pipe(orbitals: (OrbitalDefinition | OrbitalSchema)[], events: TraitEventContract[], appName?: string): OrbitalSchema;
|
|
105
149
|
|
|
106
|
-
export { type ComposeConnection, type ComposePage, type MakeEntityOpts, type MakePageOpts, compose, connect, ensureIdField, extractTrait, makeEntity, makeOrbital, makePage, makeSchema, mergeOrbitals, pipe, plural, wire };
|
|
150
|
+
export { type ComposeConnection, type ComposePage, type MakeEntityOpts, type MakePageOpts, compose, connect, ensureIdField, explodeBehaviorComposition, extractTrait, makeEntity, makeOrbital, makePage, makeSchema, mergeOrbitals, pipe, plural, wire };
|
package/dist/builders.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { resolve, dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
2
5
|
|
|
3
6
|
// src/types/orbital.ts
|
|
4
7
|
var FieldTypeSchema = z.enum([
|
|
@@ -46,34 +49,61 @@ var FieldFormatSchema = z.enum([
|
|
|
46
49
|
"datetime",
|
|
47
50
|
"uuid"
|
|
48
51
|
]);
|
|
52
|
+
var FIELD_TYPE_ALIASES = {
|
|
53
|
+
text: "string",
|
|
54
|
+
int: "number",
|
|
55
|
+
float: "number",
|
|
56
|
+
ts: "timestamp"
|
|
57
|
+
};
|
|
49
58
|
var EntityFieldSchema = z.lazy(
|
|
50
|
-
() => z.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
items: EntityFieldSchema.optional(),
|
|
61
|
-
relation: RelationConfigSchema.optional()
|
|
62
|
-
}).refine(
|
|
63
|
-
(field) => field.type !== "relation" || field.relation !== void 0,
|
|
64
|
-
{ message: 'Relation config is required when type is "relation"', path: ["relation"] }
|
|
65
|
-
).refine(
|
|
66
|
-
// Enum fields must carry their allowed values. Without this refine,
|
|
67
|
-
// the type was lying about what's valid — bare `type: 'enum'` without
|
|
68
|
-
// `values` passed zod but failed `orb validate` downstream with
|
|
69
|
-
// ORB_E_EMPTY_ENUM_VALUES, stalling the agent pipeline for 20 minutes.
|
|
70
|
-
// `enum` is the legacy field-name alias; accept either.
|
|
71
|
-
(field) => {
|
|
72
|
-
if (field.type !== "enum") return true;
|
|
73
|
-
const vals = field.values ?? field.enum;
|
|
74
|
-
return Array.isArray(vals) && vals.length > 0;
|
|
59
|
+
() => z.preprocess(
|
|
60
|
+
(input) => {
|
|
61
|
+
if (input !== null && typeof input === "object" && "type" in input && typeof input.type === "string") {
|
|
62
|
+
const raw = input.type;
|
|
63
|
+
const canonical = FIELD_TYPE_ALIASES[raw];
|
|
64
|
+
if (canonical !== void 0) {
|
|
65
|
+
return { ...input, type: canonical };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return input;
|
|
75
69
|
},
|
|
76
|
-
{
|
|
70
|
+
z.object({
|
|
71
|
+
name: z.string().min(1, "Field name is required"),
|
|
72
|
+
type: FieldTypeSchema,
|
|
73
|
+
required: z.boolean().optional(),
|
|
74
|
+
default: z.unknown().optional(),
|
|
75
|
+
values: z.array(z.string()).optional(),
|
|
76
|
+
enum: z.array(z.string()).optional(),
|
|
77
|
+
format: FieldFormatSchema.optional(),
|
|
78
|
+
min: z.number().optional(),
|
|
79
|
+
max: z.number().optional(),
|
|
80
|
+
items: EntityFieldSchema.optional(),
|
|
81
|
+
relation: RelationConfigSchema.optional()
|
|
82
|
+
}).refine(
|
|
83
|
+
(field) => field.type !== "relation" || field.relation !== void 0,
|
|
84
|
+
{ message: 'Relation config is required when type is "relation"', path: ["relation"] }
|
|
85
|
+
).refine(
|
|
86
|
+
// Enum fields must carry their allowed values. Without this refine,
|
|
87
|
+
// the type was lying about what's valid — bare `type: 'enum'` without
|
|
88
|
+
// `values` passed zod but failed `orb validate` downstream with
|
|
89
|
+
// ORB_E_EMPTY_ENUM_VALUES, stalling the agent pipeline for 20 minutes.
|
|
90
|
+
// `enum` is the legacy field-name alias; accept either.
|
|
91
|
+
(field) => {
|
|
92
|
+
if (field.type !== "enum") return true;
|
|
93
|
+
const vals = field.values ?? field.enum;
|
|
94
|
+
return Array.isArray(vals) && vals.length > 0;
|
|
95
|
+
},
|
|
96
|
+
{ message: "Enum field requires a non-empty `values` array", path: ["values"] }
|
|
97
|
+
).refine(
|
|
98
|
+
// Array fields must describe their element shape. Bare `type: 'array'`
|
|
99
|
+
// with no `items` forces downstream consumers (builders, UI renderers,
|
|
100
|
+
// persistence) to guess, so reject it at the schema boundary.
|
|
101
|
+
(field) => {
|
|
102
|
+
if (field.type !== "array") return true;
|
|
103
|
+
return field.items !== void 0;
|
|
104
|
+
},
|
|
105
|
+
{ message: "Array field requires an `items` schema describing each element", path: ["items"] }
|
|
106
|
+
)
|
|
77
107
|
)
|
|
78
108
|
);
|
|
79
109
|
var ENTITY_ROLES = [
|
|
@@ -370,6 +400,8 @@ var RequiredFieldSchema = z.object({
|
|
|
370
400
|
});
|
|
371
401
|
z.object({
|
|
372
402
|
ref: z.string().min(1),
|
|
403
|
+
// Phase 1.2: optional registry path disambiguator, pairs with `ref`.
|
|
404
|
+
from: z.string().optional(),
|
|
373
405
|
linkedEntity: z.string().optional(),
|
|
374
406
|
name: z.string().optional(),
|
|
375
407
|
events: z.record(
|
|
@@ -735,6 +767,8 @@ var PageRefStringSchema = z.string().regex(
|
|
|
735
767
|
);
|
|
736
768
|
var PageRefObjectSchema = z.object({
|
|
737
769
|
ref: PageRefStringSchema,
|
|
770
|
+
// Phase 1.2: optional registry path disambiguator, pairs with `ref`.
|
|
771
|
+
from: z.string().optional(),
|
|
738
772
|
path: z.string().startsWith("/").optional(),
|
|
739
773
|
linkedEntity: z.string().optional(),
|
|
740
774
|
traits: z.array(TraitRefSchema).optional()
|
|
@@ -1007,6 +1041,104 @@ function composeBehaviors(input) {
|
|
|
1007
1041
|
}
|
|
1008
1042
|
};
|
|
1009
1043
|
}
|
|
1044
|
+
function registryRoot() {
|
|
1045
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
1046
|
+
return resolve(here, "..", "..", "..", "almadar-std", "behaviors", "registry");
|
|
1047
|
+
}
|
|
1048
|
+
var LEVELS = ["atoms", "molecules", "organisms"];
|
|
1049
|
+
function resolveBehavior(behaviorName) {
|
|
1050
|
+
const root = registryRoot();
|
|
1051
|
+
const searched = [];
|
|
1052
|
+
for (const level of LEVELS) {
|
|
1053
|
+
const path = resolve(root, level, `${behaviorName}.orb`);
|
|
1054
|
+
searched.push(path);
|
|
1055
|
+
let source;
|
|
1056
|
+
try {
|
|
1057
|
+
source = readFileSync(path, "utf8");
|
|
1058
|
+
} catch {
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
let parsed;
|
|
1062
|
+
try {
|
|
1063
|
+
parsed = JSON.parse(source);
|
|
1064
|
+
} catch (err) {
|
|
1065
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1066
|
+
throw new Error(
|
|
1067
|
+
`explodeBehaviorComposition: failed to parse ${path} as JSON: ${message}`
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
return { level, path, schema: parsed };
|
|
1071
|
+
}
|
|
1072
|
+
throw new Error(
|
|
1073
|
+
`explodeBehaviorComposition: behavior "${behaviorName}" not found. Searched:
|
|
1074
|
+
- ${searched.join("\n - ")}`
|
|
1075
|
+
);
|
|
1076
|
+
}
|
|
1077
|
+
function isTraitReferenceObject(entry) {
|
|
1078
|
+
return typeof entry === "object" && entry !== null && "ref" in entry && typeof entry.ref === "string" && !isInlineTrait(entry);
|
|
1079
|
+
}
|
|
1080
|
+
function aliasToFromMap(uses) {
|
|
1081
|
+
const map = /* @__PURE__ */ new Map();
|
|
1082
|
+
if (!uses) return map;
|
|
1083
|
+
for (const use of uses) {
|
|
1084
|
+
map.set(use.as, use.from);
|
|
1085
|
+
}
|
|
1086
|
+
return map;
|
|
1087
|
+
}
|
|
1088
|
+
function extractAlias(ref) {
|
|
1089
|
+
const match = ref.match(/^([A-Z][a-zA-Z0-9]*)\.traits\.[A-Z][a-zA-Z0-9]*$/);
|
|
1090
|
+
return match ? match[1] : null;
|
|
1091
|
+
}
|
|
1092
|
+
function findAtomInlineTrait(orbital) {
|
|
1093
|
+
for (const entry of orbital.traits) {
|
|
1094
|
+
if (typeof entry === "object" && entry !== null && isInlineTrait(entry)) {
|
|
1095
|
+
return entry;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return void 0;
|
|
1099
|
+
}
|
|
1100
|
+
function syntheticLeafReference(behaviorName, orbital, trait) {
|
|
1101
|
+
const base = behaviorName.replace(/^std-/, "");
|
|
1102
|
+
const alias = base.split("-").filter((segment) => segment.length > 0).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("") || "Behavior";
|
|
1103
|
+
const entityName = typeof orbital.entity === "string" ? orbital.entity : "name" in orbital.entity && typeof orbital.entity.name === "string" ? orbital.entity.name : void 0;
|
|
1104
|
+
const reference = {
|
|
1105
|
+
ref: `${alias}.traits.${trait.name}`,
|
|
1106
|
+
from: `std/behaviors/${behaviorName}`
|
|
1107
|
+
};
|
|
1108
|
+
if (trait.linkedEntity !== void 0) {
|
|
1109
|
+
reference.linkedEntity = trait.linkedEntity;
|
|
1110
|
+
} else if (entityName !== void 0) {
|
|
1111
|
+
reference.linkedEntity = entityName;
|
|
1112
|
+
}
|
|
1113
|
+
return reference;
|
|
1114
|
+
}
|
|
1115
|
+
function explodeBehaviorComposition(behaviorName) {
|
|
1116
|
+
const resolved = resolveBehavior(behaviorName);
|
|
1117
|
+
const orbitals = Array.isArray(resolved.schema.orbitals) ? resolved.schema.orbitals : [];
|
|
1118
|
+
const references = [];
|
|
1119
|
+
for (const orbital of orbitals) {
|
|
1120
|
+
const aliasMap = aliasToFromMap(orbital.uses);
|
|
1121
|
+
for (const entry of orbital.traits ?? []) {
|
|
1122
|
+
if (!isTraitReferenceObject(entry)) continue;
|
|
1123
|
+
const copy = { ...entry };
|
|
1124
|
+
if (copy.from === void 0) {
|
|
1125
|
+
const alias = extractAlias(copy.ref);
|
|
1126
|
+
const fromPath = alias !== null ? aliasMap.get(alias) : void 0;
|
|
1127
|
+
if (fromPath !== void 0) {
|
|
1128
|
+
copy.from = fromPath;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
references.push(copy);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
if (references.length > 0) return references;
|
|
1135
|
+
const firstOrbital = orbitals[0];
|
|
1136
|
+
const inlineTrait = firstOrbital ? findAtomInlineTrait(firstOrbital) : void 0;
|
|
1137
|
+
if (firstOrbital && inlineTrait) {
|
|
1138
|
+
return [syntheticLeafReference(behaviorName, firstOrbital, inlineTrait)];
|
|
1139
|
+
}
|
|
1140
|
+
return [];
|
|
1141
|
+
}
|
|
1010
1142
|
|
|
1011
1143
|
// src/builders.ts
|
|
1012
1144
|
function ensureIdField(fields) {
|
|
@@ -1196,6 +1328,6 @@ function pipe(orbitals, events, appName) {
|
|
|
1196
1328
|
};
|
|
1197
1329
|
}
|
|
1198
1330
|
|
|
1199
|
-
export { applyEventWiring, compose, composeBehaviors, connect, detectLayoutStrategy, ensureIdField, extractTrait, makeEntity, makeOrbital, makePage, makeSchema, mergeOrbitals, pipe, plural, wire };
|
|
1331
|
+
export { applyEventWiring, compose, composeBehaviors, connect, detectLayoutStrategy, ensureIdField, explodeBehaviorComposition, extractTrait, makeEntity, makeOrbital, makePage, makeSchema, mergeOrbitals, pipe, plural, wire };
|
|
1200
1332
|
//# sourceMappingURL=builders.js.map
|
|
1201
1333
|
//# sourceMappingURL=builders.js.map
|