@ai-matrx/associations 0.3.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # Changelog — @ai-matrx/associations
2
2
 
3
+ ## 0.4.0 — 2026-08-29 (unreleased; W4 completion)
4
+
5
+ The three faces STOPPED at the W3+W4 build for missing design-system
6
+ primitives, now built against `@ai-matrx/design-system` 0.3.0 (Command
7
+ family incl. CommandDialog, the Select family, the CreatablePicker
8
+ composite) — the optional peer floor moves to **`>=0.3.0`**. Behavior ported
9
+ VERBATIM from the matrx-frontend originals (each re-read in full
10
+ 2026-08-29); only the measured seams inverted, chrome never vendored.
11
+
12
+ - **`AssociationEntitySelect` (`src/react/components/AssociationEntitySelect.tsx`)**
13
+ — the canonical "name dropdown" (display / inline rename / switch / add new
14
+ / unlink), adapter-driven via the already-shipping
15
+ `AssociationEntitySelectAdapter` contract + default adapter hook. Seams:
16
+ `getEntityInfo` → the store's registry merge engine (`Icon: null` →
17
+ `DefaultEntityIcon`); `@/lib/toast` → the notifier port;
18
+ `EntityDoorControls` → the entityDoors port's `DoorControls` (absent → the
19
+ name and rows render without doors, matching the picker precedent); lucide
20
+ → inlined glyphs (C19).
21
+ - **`CategorySelect` (`src/react/components/CategorySelect.tsx`)** — THE
22
+ single-value picker over one `platform.categories` dimension, the
23
+ CreatablePicker composite with the hierarchy parent-select in
24
+ `createExtra`. Seams: the Redux active-organization read
25
+ (`selectOrganizationId`) → the identity port's optional `ensureOrgId()`
26
+ (`orgId` prop wins; with neither, create refuses LOUDLY — notifier + no
27
+ RPC); toasts → notifier. NOTE: the origin's two-part success toast
28
+ (message + description) is joined into the notifier's single success
29
+ message (the port's `success(msg)` carries no description); content
30
+ preserved.
31
+ - **`CategoryTagPicker` (`src/react/components/CategoryTagPicker.tsx`)** —
32
+ THE multi-select tagger over the canonical `entity → category` edge
33
+ (full-role `setTargets` semantics verbatim, one write at a time). Seams:
34
+ the host-shaped `ensureOrgId` (`@/lib/organizations/personalOrg`) →
35
+ `identity.ensureOrgId` per the design's seam table, with the loud
36
+ `ensure_org_missing` refusal when neither the `orgId` prop nor the port
37
+ can answer; `console.error` → errorSink
38
+ (`category_tag_set_targets_failed` / `category_tag_create_failed`);
39
+ toasts → notifier; the `icon` prop's `LucideIcon` type → the structural
40
+ `TagPickerIcon`.
41
+ - **`buildCategoryHierarchy` → `/core`
42
+ (`src/core/categoryHierarchy.ts`)** — the two-level display-order util
43
+ both category faces consume, ported verbatim from
44
+ `features/scopes/utils/categoryHierarchy.ts` (pure, React-free), exported
45
+ from `/core`.
46
+ - **Four new inlined glyphs (C19)**: `ChevronDownIcon`,
47
+ `ChevronsUpDownIcon`, `CornerDownRightIcon`, `TagIcon`.
48
+ - **Token vocabulary regenerated from the live registry: 651 → 654 tokens**
49
+ (`platform_continued_access`, `route_manifest_entry`, `short_link` landed
50
+ after the 0.3.0 generation; caught by the W5 swap agent's token-parity
51
+ gate). `check:entity-types` green against live.
52
+ - 16 new jsdom behavioral tests (render + interaction + degradations against
53
+ fake ports) → 147 total; full gate green (`typecheck`, `test`,
54
+ `check:package` incl. the packed-tarball canary).
55
+
56
+
3
57
  ## 0.3.0 — 2026-08-29 (unreleased; W3 + W4 of the extraction)
4
58
 
5
59
  Waves 3 and 4: the `/react` subpath — the seven hooks riding the /core store
@@ -26,6 +26,7 @@ __export(core_exports, {
26
26
  SELF_TEST_MISSING_RPC: () => SELF_TEST_MISSING_RPC,
27
27
  assertDemandedSchema: () => assertDemandedSchema,
28
28
  associationsKey: () => associationsKey,
29
+ buildCategoryHierarchy: () => buildCategoryHierarchy,
29
30
  createAssociationGuards: () => createAssociationGuards,
30
31
  createAssociationHelpers: () => createAssociationHelpers,
31
32
  createAssociationsService: () => createAssociationsService,
@@ -475,6 +476,7 @@ var ENTITY_TYPE_METADATA = {
475
476
  "platform_actor_session": { token: "platform_actor_session", schema: "platform", table: "actor_session", label: "Actor session", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
476
477
  "platform_actor_token": { token: "platform_actor_token", schema: "platform", table: "actor_token", label: "Actor token", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
477
478
  "platform_actor_token_event": { token: "platform_actor_token_event", schema: "platform", table: "actor_token_event", label: "Actor token event", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
479
+ "platform_continued_access": { token: "platform_continued_access", schema: "platform", table: "continued_access", label: "Continued Access", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
478
480
  "platform_outcome_event": { token: "platform_outcome_event", schema: "platform", table: "outcome_event", label: "Outcome Event", baseTier: 1, isComponent: false, isModule: false, isListed: true, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
479
481
  "platform_outsider_consumer": { token: "platform_outsider_consumer", schema: "platform", table: "outsider_consumer", label: "Outsider consumer", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
480
482
  "platform_saved_view": { token: "platform_saved_view", schema: "platform", table: "saved_view", label: "Saved view", baseTier: 1, isComponent: false, isModule: false, isListed: true, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
@@ -503,6 +505,7 @@ var ENTITY_TYPE_METADATA = {
503
505
  "research_tag": { token: "research_tag", schema: "research", table: "rs_tag", label: "Research Tag", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: "name", contentRole: null, referenceCategory: null },
504
506
  "research_template": { token: "research_template", schema: "research", table: "rs_template", label: "Research Template", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
505
507
  "research_topic": { token: "research_topic", schema: "research", table: "rs_topic", label: "Research Topic", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
508
+ "route_manifest_entry": { token: "route_manifest_entry", schema: "platform", table: "route_manifest", label: "Route Manifest Entry", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
506
509
  "rulebook": { token: "rulebook", schema: "platform", table: "rulebook", label: "Rulebook", baseTier: 1, isComponent: false, isModule: false, isListed: true, scopeable: true, category: "Knowledge", referencePickable: true, titleColumn: "name", contentRole: "source", referenceCategory: null },
507
510
  "sandbox_instance": { token: "sandbox_instance", schema: "public", table: "sandbox_instances", label: "Sandbox Instance", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
508
511
  "sch_agent_task": { token: "sch_agent_task", schema: "scheduler", table: "sch_agent_task", label: "Agent Task Config", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
@@ -581,6 +584,7 @@ var ENTITY_TYPE_METADATA = {
581
584
  "seo_topic": { token: "seo_topic", schema: "seo", table: "topic", label: "SEO Topic", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "seo", referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
582
585
  "seo_web_analytics_daily": { token: "seo_web_analytics_daily", schema: "seo", table: "web_analytics_daily", label: "Web Analytics Daily", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: "marketing", referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
583
586
  "shared_canvas_item": { token: "shared_canvas_item", schema: "canvas", table: "shared_canvas_items", label: "Shared Canvas Item", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "title", contentRole: null, referenceCategory: null },
587
+ "short_link": { token: "short_link", schema: "platform", table: "short_links", label: "Short Link", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
584
588
  "skill": { token: "skill", schema: "skill", table: "definition", label: "Skill", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "Skills", referencePickable: true, titleColumn: "label", contentRole: "utility", referenceCategory: null },
585
589
  "skill_render_definition": { token: "skill_render_definition", schema: "skill", table: "render_definition", label: "Skill Render Definition", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "Skills", referencePickable: true, titleColumn: "label", contentRole: null, referenceCategory: null },
586
590
  "sms_consent": { token: "sms_consent", schema: "communication", table: "sms_consent", label: "SMS Consent", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
@@ -1128,6 +1132,7 @@ var ENTITY_TYPE_TOKENS = [
1128
1132
  "platform_actor_session",
1129
1133
  "platform_actor_token",
1130
1134
  "platform_actor_token_event",
1135
+ "platform_continued_access",
1131
1136
  "platform_outcome_event",
1132
1137
  "platform_outsider_consumer",
1133
1138
  "platform_saved_view",
@@ -1156,6 +1161,7 @@ var ENTITY_TYPE_TOKENS = [
1156
1161
  "research_tag",
1157
1162
  "research_template",
1158
1163
  "research_topic",
1164
+ "route_manifest_entry",
1159
1165
  "rulebook",
1160
1166
  "sandbox_instance",
1161
1167
  "sch_agent_task",
@@ -1234,6 +1240,7 @@ var ENTITY_TYPE_TOKENS = [
1234
1240
  "seo_topic",
1235
1241
  "seo_web_analytics_daily",
1236
1242
  "shared_canvas_item",
1243
+ "short_link",
1237
1244
  "skill",
1238
1245
  "skill_render_definition",
1239
1246
  "sms_consent",
@@ -3190,4 +3197,68 @@ function isContentSourceEdge(sourceType, metadata) {
3190
3197
  if (isMembershipMetadata(metadata)) return false;
3191
3198
  return true;
3192
3199
  }
3200
+
3201
+ // src/core/categoryHierarchy.ts
3202
+ function buildCategoryHierarchy(categories) {
3203
+ const byId = new Map(categories.map((category) => [category.id, category]));
3204
+ const hasHierarchy = categories.some(
3205
+ (category) => category.parentId !== null && byId.has(category.parentId)
3206
+ );
3207
+ if (!hasHierarchy) {
3208
+ return {
3209
+ items: categories.map((category) => ({
3210
+ category,
3211
+ depth: 0,
3212
+ parent: null,
3213
+ displayName: category.name
3214
+ })),
3215
+ roots: categories.filter((category) => category.parentId === null),
3216
+ hasHierarchy: false
3217
+ };
3218
+ }
3219
+ const roots = categories.filter(
3220
+ (category) => category.parentId === null || !byId.has(category.parentId)
3221
+ );
3222
+ const childrenByParent = /* @__PURE__ */ new Map();
3223
+ for (const category of categories) {
3224
+ if (!category.parentId || !byId.has(category.parentId)) continue;
3225
+ const children = childrenByParent.get(category.parentId) ?? [];
3226
+ children.push(category);
3227
+ childrenByParent.set(category.parentId, children);
3228
+ }
3229
+ const items = [];
3230
+ const seen = /* @__PURE__ */ new Set();
3231
+ for (const root of roots) {
3232
+ items.push({
3233
+ category: root,
3234
+ depth: 0,
3235
+ parent: null,
3236
+ displayName: root.name
3237
+ });
3238
+ seen.add(root.id);
3239
+ for (const child of childrenByParent.get(root.id) ?? []) {
3240
+ items.push({
3241
+ category: child,
3242
+ depth: 1,
3243
+ parent: root,
3244
+ displayName: `${root.name} / ${child.name}`
3245
+ });
3246
+ seen.add(child.id);
3247
+ }
3248
+ }
3249
+ for (const category of categories) {
3250
+ if (seen.has(category.id)) continue;
3251
+ items.push({
3252
+ category,
3253
+ depth: 0,
3254
+ parent: null,
3255
+ displayName: category.name
3256
+ });
3257
+ }
3258
+ return {
3259
+ items,
3260
+ roots: categories.filter((category) => category.parentId === null),
3261
+ hasHierarchy: true
3262
+ };
3263
+ }
3193
3264
  //# sourceMappingURL=index.cjs.map