@ai-matrx/associations 0.6.1 → 0.7.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.
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ComponentType } from 'react';
3
- import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-E0zSQBbc.cjs';
4
- export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-E0zSQBbc.cjs';
3
+ import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-HW4hLdsd.cjs';
4
+ export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-HW4hLdsd.cjs';
5
5
 
6
6
  interface AssociationsUiPorts {
7
7
  notifier?: AssociationsNotifier;
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ComponentType } from 'react';
3
- import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-E0zSQBbc.js';
4
- export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-E0zSQBbc.js';
3
+ import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-HW4hLdsd.js';
4
+ export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-HW4hLdsd.js';
5
5
 
6
6
  interface AssociationsUiPorts {
7
7
  notifier?: AssociationsNotifier;
@@ -366,6 +366,7 @@ var ENTITY_TYPE_TOKENS = [
366
366
  "commerce_asset_reshoot_request",
367
367
  "commerce_asset_review",
368
368
  "commerce_asset_unknown",
369
+ "commerce_certified_printer",
369
370
  "commerce_cloud_sync_connection",
370
371
  "commerce_ebay_business_policy",
371
372
  "commerce_ebay_category",
@@ -1051,6 +1052,12 @@ import {
1051
1052
  useRef as useRef3,
1052
1053
  useState
1053
1054
  } from "react";
1055
+ function metadataRecord(metadata) {
1056
+ if (metadata === null || typeof metadata !== "object" || Array.isArray(metadata)) {
1057
+ return metadata == null ? {} : null;
1058
+ }
1059
+ return Object.fromEntries(Object.entries(metadata));
1060
+ }
1054
1061
  function useContainerLinks(args) {
1055
1062
  const { containerType, containerId, orgId } = args;
1056
1063
  const store = useAssociationsStore();
@@ -1172,6 +1179,31 @@ function useContainerLinks(args) {
1172
1179
  }
1173
1180
  return result;
1174
1181
  };
1182
+ const setPinned = async (token, resourceId, pinned, role) => {
1183
+ if (!containerId) return { ok: false, error: "Missing container id" };
1184
+ const exactRole = role ?? null;
1185
+ const link = incoming.find(
1186
+ (candidate) => candidate.token === token && candidate.resourceId === resourceId && candidate.role === exactRole
1187
+ );
1188
+ if (!link) return { ok: false, error: "Association edge not found" };
1189
+ const currentMetadata = metadataRecord(link.metadata);
1190
+ if (!currentMetadata) {
1191
+ return {
1192
+ ok: false,
1193
+ error: "Association metadata is not an object and cannot be updated safely"
1194
+ };
1195
+ }
1196
+ return store.add({
1197
+ sourceType: token,
1198
+ sourceId: resourceId,
1199
+ targetType: containerType,
1200
+ targetId: containerId,
1201
+ ...orgId != null ? { orgId } : {},
1202
+ ...link.label != null ? { label: link.label } : {},
1203
+ ...role !== void 0 ? { role } : {},
1204
+ metadata: { ...currentMetadata, pinned }
1205
+ });
1206
+ };
1175
1207
  const reload = async () => {
1176
1208
  await Promise.all([
1177
1209
  reloadGeneric(),
@@ -1189,7 +1221,8 @@ function useContainerLinks(args) {
1189
1221
  attachedIdsFor,
1190
1222
  linksFor,
1191
1223
  attach,
1192
- detach
1224
+ detach,
1225
+ setPinned
1193
1226
  };
1194
1227
  }
1195
1228
 
@@ -2576,6 +2609,9 @@ function UniversalAssociationPicker(props) {
2576
2609
  import { useEffect as useEffect10, useState as useState9 } from "react";
2577
2610
  import { cn as cn5 } from "@ai-matrx/design-system";
2578
2611
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2612
+ function metadataIsPinned(metadata) {
2613
+ return metadata !== null && typeof metadata === "object" && !Array.isArray(metadata) && Reflect.get(metadata, "pinned") === true;
2614
+ }
2579
2615
  function AttachedItemsSheet(props) {
2580
2616
  const store = useAssociationsStore();
2581
2617
  const info = store.registry.getEntityInfo(props.token);
@@ -2611,7 +2647,8 @@ function AttachedItemsSheet(props) {
2611
2647
  enabled: props.open,
2612
2648
  links: props.links,
2613
2649
  ...props.onAdd ? { onAdd: props.onAdd } : {},
2614
- onDetach: props.onDetach
2650
+ onDetach: props.onDetach,
2651
+ ...props.onSetPinned ? { onSetPinned: props.onSetPinned } : {}
2615
2652
  }
2616
2653
  )
2617
2654
  }
@@ -2622,7 +2659,8 @@ function AttachedItemsBody({
2622
2659
  enabled,
2623
2660
  links,
2624
2661
  onAdd,
2625
- onDetach
2662
+ onDetach,
2663
+ onSetPinned
2626
2664
  }) {
2627
2665
  const store = useAssociationsStore();
2628
2666
  const notifier = useNotifier();
@@ -2664,11 +2702,12 @@ function AttachedItemsBody({
2664
2702
  cancelled = true;
2665
2703
  };
2666
2704
  }, [token, idKey, enabled, store]);
2667
- const detach = async (resourceId) => {
2705
+ const detach = async (link) => {
2706
+ const resourceId = link.resourceId;
2668
2707
  if (busyId) return;
2669
2708
  setBusyId(resourceId);
2670
2709
  try {
2671
- const res = await onDetach(resourceId);
2710
+ const res = await onDetach(resourceId, link.role);
2672
2711
  if (!res.ok) {
2673
2712
  notifier.error(`Couldn't detach${res.error ? `: ${res.error}` : ""}`);
2674
2713
  }
@@ -2676,6 +2715,20 @@ function AttachedItemsBody({
2676
2715
  setBusyId(null);
2677
2716
  }
2678
2717
  };
2718
+ const setPinned = async (link, pinned) => {
2719
+ if (!onSetPinned || busyId) return;
2720
+ setBusyId(link.resourceId);
2721
+ try {
2722
+ const res = await onSetPinned(link.resourceId, pinned, link.role);
2723
+ if (!res.ok) {
2724
+ notifier.error(
2725
+ `Couldn't ${pinned ? "pin" : "unpin"}${res.error ? `: ${res.error}` : ""}`
2726
+ );
2727
+ }
2728
+ } finally {
2729
+ setBusyId(null);
2730
+ }
2731
+ };
2679
2732
  return /* @__PURE__ */ jsxs7(Fragment2, { children: [
2680
2733
  titleError ? /* @__PURE__ */ jsxs7("div", { className: "mb-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-[12px] text-destructive", children: [
2681
2734
  "Showing names recorded at attach time \u2014 they may be out of date.",
@@ -2690,6 +2743,7 @@ function AttachedItemsBody({
2690
2743
  const missing = !titles.has(link.resourceId);
2691
2744
  const name = resolved ?? link.label ?? (missing ? null : "Untitled");
2692
2745
  const busy = busyId === link.resourceId;
2746
+ const pinned = metadataIsPinned(link.metadata);
2693
2747
  return /* @__PURE__ */ jsxs7(
2694
2748
  "li",
2695
2749
  {
@@ -2709,12 +2763,35 @@ function AttachedItemsBody({
2709
2763
  className: "text-foreground"
2710
2764
  }
2711
2765
  ) }),
2766
+ onSetPinned ? /* @__PURE__ */ jsx9(
2767
+ "button",
2768
+ {
2769
+ type: "button",
2770
+ disabled: busy,
2771
+ onClick: () => void setPinned(link, !pinned),
2772
+ title: pinned ? "Unpin (stops staying in agent context)" : "Pin \u2014 always in agent context",
2773
+ "aria-label": pinned ? "Unpin" : "Pin",
2774
+ className: cn5(
2775
+ "flex h-6 w-6 shrink-0 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50",
2776
+ pinned ? "text-primary" : "text-muted-foreground"
2777
+ ),
2778
+ children: /* @__PURE__ */ jsx9(
2779
+ PinIcon,
2780
+ {
2781
+ className: cn5(
2782
+ "h-3.5 w-3.5",
2783
+ pinned && "fill-primary/20"
2784
+ )
2785
+ }
2786
+ )
2787
+ }
2788
+ ) : null,
2712
2789
  /* @__PURE__ */ jsx9(
2713
2790
  "button",
2714
2791
  {
2715
2792
  type: "button",
2716
2793
  disabled: busy,
2717
- onClick: () => void detach(link.resourceId),
2794
+ onClick: () => void detach(link),
2718
2795
  title: "Detach",
2719
2796
  className: cn5(
2720
2797
  "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors",
@@ -2810,7 +2887,15 @@ function AssociationCard({
2810
2887
  const role = getContentRoleMeta(info.contentRole);
2811
2888
  const Icon = info.Icon ?? DefaultEntityIcon;
2812
2889
  const [listOpen, setListOpen] = useState10(false);
2813
- const { status, countFor, attachedIdsFor, linksFor, attach, detach } = useContainerLinks({
2890
+ const {
2891
+ status,
2892
+ countFor,
2893
+ attachedIdsFor,
2894
+ linksFor,
2895
+ attach,
2896
+ detach,
2897
+ setPinned
2898
+ } = useContainerLinks({
2814
2899
  containerType: container?.type ?? "organization",
2815
2900
  containerId: container?.id ?? null,
2816
2901
  orgId: container?.orgId ?? null
@@ -2907,7 +2992,8 @@ function AssociationCard({
2907
2992
  setOpen(true);
2908
2993
  }
2909
2994
  } : {},
2910
- onDetach: (resourceId) => detach(token, resourceId)
2995
+ onDetach: (resourceId, role2) => detach(token, resourceId, role2 ?? void 0),
2996
+ onSetPinned: (resourceId, pinned, role2) => setPinned(token, resourceId, pinned, role2 ?? void 0)
2911
2997
  }
2912
2998
  ),
2913
2999
  canAttach && /* @__PURE__ */ jsx10(
@@ -2966,6 +3052,9 @@ function AssociationCardGrid({
2966
3052
  import { useState as useState11 } from "react";
2967
3053
  import { cn as cn8, Skeleton } from "@ai-matrx/design-system";
2968
3054
  import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3055
+ function metadataIsPinned2(metadata) {
3056
+ return metadata !== null && typeof metadata === "object" && !Array.isArray(metadata) && Reflect.get(metadata, "pinned") === true;
3057
+ }
2969
3058
  function useContainerLinksAdapter(container, tokens) {
2970
3059
  const store = useAssociationsStore();
2971
3060
  const links = useContainerLinks({
@@ -2980,6 +3069,7 @@ function useContainerLinksAdapter(container, tokens) {
2980
3069
  resourceId: l.resourceId,
2981
3070
  label: l.label,
2982
3071
  role: l.role,
3072
+ pinned: metadataIsPinned2(l.metadata),
2983
3073
  removable: true
2984
3074
  }))
2985
3075
  ) : [];
@@ -2989,11 +3079,13 @@ function useContainerLinksAdapter(container, tokens) {
2989
3079
  reload: links.reload,
2990
3080
  rows,
2991
3081
  attach: async (token, id, title) => links.attach(token, id, title),
2992
- detach: async (token, id, role) => links.detach(token, id, role)
3082
+ detach: async (token, id, role) => links.detach(token, id, role),
3083
+ setPinned: async (token, id, pinned, role) => links.setPinned(token, id, pinned, role)
2993
3084
  };
2994
3085
  }
2995
3086
  function AssociationList(props) {
2996
3087
  const store = useAssociationsStore();
3088
+ const notifier = useNotifier();
2997
3089
  const ctxEntity = usePrimaryEntity();
2998
3090
  const container = props.container ?? ctxEntity ?? null;
2999
3091
  const defaultAdapter = useContainerLinksAdapter(
@@ -3006,6 +3098,7 @@ function AssociationList(props) {
3006
3098
  const [pickerToken, setPickerToken] = useState11(null);
3007
3099
  const [showUniversal, setShowUniversal] = useState11(false);
3008
3100
  const [removingKeys, setRemovingKeys] = useState11(/* @__PURE__ */ new Set());
3101
+ const [pinningKeys, setPinningKeys] = useState11(/* @__PURE__ */ new Set());
3009
3102
  const rows = tokenFilter ? adapter.rows.filter((r) => tokenFilter.includes(r.token)) : adapter.rows;
3010
3103
  const visibleRows = rows.filter((r) => !removingKeys.has(r.key));
3011
3104
  const { titleFor } = useEntityTitles(
@@ -3029,6 +3122,31 @@ function AssociationList(props) {
3029
3122
  });
3030
3123
  return res;
3031
3124
  };
3125
+ const handlePin = async (row, pinned) => {
3126
+ if (!adapter.setPinned) return;
3127
+ const info = store.registry.tryGetEntityInfo(row.token);
3128
+ if (!info) return;
3129
+ setPinningKeys((prev) => new Set(prev).add(row.key));
3130
+ try {
3131
+ const res = await adapter.setPinned(
3132
+ info.token,
3133
+ row.resourceId,
3134
+ pinned,
3135
+ row.role ?? void 0
3136
+ );
3137
+ if (!res.ok) {
3138
+ notifier.error(
3139
+ `Couldn't ${pinned ? "pin" : "unpin"} resource${res.error ? `: ${res.error}` : ""}`
3140
+ );
3141
+ }
3142
+ } finally {
3143
+ setPinningKeys((prev) => {
3144
+ const next = new Set(prev);
3145
+ next.delete(row.key);
3146
+ return next;
3147
+ });
3148
+ }
3149
+ };
3032
3150
  const openRow = (row) => {
3033
3151
  if (props.openEntity) {
3034
3152
  props.openEntity(row.token, row.resourceId);
@@ -3219,18 +3337,15 @@ function AssociationList(props) {
3219
3337
  "button",
3220
3338
  {
3221
3339
  type: "button",
3222
- onClick: () => void adapter.setPinned?.(
3223
- info.token,
3224
- row.resourceId,
3225
- !(row.pinned ?? false)
3226
- ),
3340
+ disabled: pinningKeys.has(row.key),
3341
+ onClick: () => void handlePin(row, !(row.pinned ?? false)),
3227
3342
  title: row.pinned ? "Unpin (stops staying in agent context)" : "Pin \u2014 always in agent context",
3228
3343
  "aria-label": row.pinned ? "Unpin" : "Pin",
3229
3344
  className: cn8(
3230
3345
  "shrink-0 rounded p-0.5 transition-colors hover:!text-foreground",
3231
3346
  row.pinned ? "text-primary" : "text-muted-foreground/0 group-hover:text-muted-foreground"
3232
3347
  ),
3233
- children: /* @__PURE__ */ jsx12(
3348
+ children: pinningKeys.has(row.key) ? /* @__PURE__ */ jsx12(SpinnerIcon, { className: "h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx12(
3234
3349
  PinIcon,
3235
3350
  {
3236
3351
  className: cn8(