@ship-it-ui/shipit 0.0.3 → 0.0.5

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/index.cjs CHANGED
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  CTAStrip: () => CTAStrip,
27
27
  Citation: () => Citation,
28
28
  ConfidenceIndicator: () => ConfidenceIndicator,
29
+ ConnectorCard: () => ConnectorCard,
29
30
  CopilotMessage: () => CopilotMessage,
30
31
  ENTITY_GLYPH: () => ENTITY_GLYPH,
31
32
  ENTITY_LABEL: () => ENTITY_LABEL,
@@ -45,6 +46,7 @@ __export(index_exports, {
45
46
  GraphMinimap: () => GraphMinimap,
46
47
  GraphNode: () => GraphNode,
47
48
  Hero: () => Hero,
49
+ NotifRow: () => NotifRow,
48
50
  PathOverlay: () => PathOverlay,
49
51
  PricingCard: () => PricingCard,
50
52
  ReasoningBlock: () => ReasoningBlock,
@@ -52,17 +54,22 @@ __export(index_exports, {
52
54
  SuggestionChip: () => SuggestionChip,
53
55
  Testimonial: () => Testimonial,
54
56
  ToolCallCard: () => ToolCallCard,
55
- cn: () => import_ui28.cn,
57
+ cn: () => import_ui30.cn,
56
58
  entityColumn: () => entityColumn,
57
- entityTypeColumn: () => entityTypeColumn
59
+ entityTypeColumn: () => entityTypeColumn,
60
+ getEntityTypeMeta: () => getEntityTypeMeta,
61
+ listEntityTypes: () => listEntityTypes,
62
+ registerEntityType: () => registerEntityType,
63
+ registerEntityTypes: () => registerEntityTypes,
64
+ resetEntityTypeRegistry: () => resetEntityTypeRegistry
58
65
  });
59
66
  module.exports = __toCommonJS(index_exports);
60
- var import_ui28 = require("@ship-it-ui/ui");
67
+ var import_ui30 = require("@ship-it-ui/ui");
61
68
 
62
69
  // src/ai/AskBar.tsx
63
70
  var import_ui = require("@ship-it-ui/ui");
64
- var import_react = require("react");
65
71
  var import_ui2 = require("@ship-it-ui/ui");
72
+ var import_react = require("react");
66
73
  var import_jsx_runtime = require("react/jsx-runtime");
67
74
  var AskBar = (0, import_react.forwardRef)(function AskBar2({
68
75
  value: valueProp,
@@ -74,10 +81,12 @@ var AskBar = (0, import_react.forwardRef)(function AskBar2({
74
81
  submitLabel = "Ask",
75
82
  disabled,
76
83
  maxWidth = 620,
84
+ density = "comfortable",
77
85
  className,
78
86
  children,
79
87
  ...props
80
88
  }, ref) {
89
+ const isTouch = density === "touch";
81
90
  const [value, setValue] = (0, import_ui.useControllableState)({
82
91
  value: valueProp,
83
92
  defaultValue: defaultValue ?? "",
@@ -105,16 +114,17 @@ var AskBar = (0, import_react.forwardRef)(function AskBar2({
105
114
  ref,
106
115
  role: "search",
107
116
  onSubmit: handleSubmit,
108
- style: { maxWidth },
117
+ style: { maxWidth: isTouch ? void 0 : maxWidth },
109
118
  className: (0, import_ui2.cn)(
110
- "border-border-strong bg-panel w-full rounded-xl border p-[14px] shadow",
119
+ "border-border-strong bg-panel w-full border",
120
+ isTouch ? "rounded-m-card p-3" : "rounded-xl p-[14px] shadow",
111
121
  "focus-within:border-accent focus-within:ring-accent-dim focus-within:ring-[3px]",
112
122
  className
113
123
  ),
114
124
  ...props,
115
125
  children: [
116
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mb-[10px] flex items-start gap-[10px]", children: [
117
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: "text-accent text-[16px]", children: "\u2726" }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_ui2.cn)("flex items-start gap-[10px]", isTouch ? "mb-2" : "mb-[10px]"), children: [
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: (0, import_ui2.cn)("text-accent", isTouch ? "text-[18px]" : "text-[16px]"), children: "\u2726" }),
118
128
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
119
129
  "textarea",
120
130
  {
@@ -126,8 +136,9 @@ var AskBar = (0, import_react.forwardRef)(function AskBar2({
126
136
  "aria-label": placeholder,
127
137
  rows: 1,
128
138
  className: (0, import_ui2.cn)(
129
- "text-text flex-1 resize-none border-0 bg-transparent text-[14px] leading-[1.5] outline-none",
130
- "placeholder:text-text-dim"
139
+ "text-text flex-1 resize-none border-0 bg-transparent leading-[1.5] outline-none",
140
+ "placeholder:text-text-dim",
141
+ isTouch ? "text-m-body" : "text-[14px]"
131
142
  )
132
143
  }
133
144
  ),
@@ -135,19 +146,23 @@ var AskBar = (0, import_react.forwardRef)(function AskBar2({
135
146
  "span",
136
147
  {
137
148
  "aria-hidden": true,
138
- className: "bg-accent mt-[3px] inline-block h-4 w-px animate-[ship-pulse_1s_infinite]"
149
+ className: (0, import_ui2.cn)(
150
+ "bg-accent mt-[3px] inline-block w-px animate-[ship-pulse_1s_infinite]",
151
+ isTouch ? "h-5" : "h-4"
152
+ )
139
153
  }
140
154
  )
141
155
  ] }),
142
156
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-[6px]", children: [
143
157
  children,
144
158
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ml-auto flex items-center gap-2", children: [
145
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: "text-text-dim font-mono text-[11px]", children: "\u2318\u21B5" }),
159
+ !isTouch && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: "text-text-dim font-mono text-[11px]", children: "\u2318\u21B5" }),
146
160
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
147
161
  import_ui.Button,
148
162
  {
149
163
  type: "submit",
150
- size: "sm",
164
+ size: isTouch ? "md" : "sm",
165
+ density: isTouch ? "touch" : void 0,
151
166
  variant: "primary",
152
167
  disabled: disabled || !(value ?? "").trim(),
153
168
  children: submitLabel
@@ -162,8 +177,8 @@ var AskBar = (0, import_react.forwardRef)(function AskBar2({
162
177
  AskBar.displayName = "AskBar";
163
178
 
164
179
  // src/ai/Citation.tsx
165
- var import_react2 = require("react");
166
180
  var import_ui3 = require("@ship-it-ui/ui");
181
+ var import_react2 = require("react");
167
182
  var import_jsx_runtime2 = require("react/jsx-runtime");
168
183
  var SUPERSCRIPTS = ["\u2070", "\xB9", "\xB2", "\xB3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"];
169
184
  function toSuperscript(n) {
@@ -204,8 +219,8 @@ var Citation = (0, import_react2.forwardRef)(function Citation2({ index, source,
204
219
  Citation.displayName = "Citation";
205
220
 
206
221
  // src/ai/ConfidenceIndicator.tsx
207
- var import_react3 = require("react");
208
222
  var import_ui4 = require("@ship-it-ui/ui");
223
+ var import_react3 = require("react");
209
224
  var import_jsx_runtime3 = require("react/jsx-runtime");
210
225
  var tierLabel = {
211
226
  high: "High",
@@ -273,12 +288,53 @@ ConfidenceIndicator.displayName = "ConfidenceIndicator";
273
288
 
274
289
  // src/ai/CopilotMessage.tsx
275
290
  var import_ui5 = require("@ship-it-ui/ui");
276
- var import_react4 = require("react");
277
291
  var import_ui6 = require("@ship-it-ui/ui");
292
+ var import_react4 = require("react");
278
293
  var import_jsx_runtime4 = require("react/jsx-runtime");
279
294
  var CopilotMessage = (0, import_react4.forwardRef)(
280
- function CopilotMessage2({ role, avatar, streaming, className, children, ...props }, ref) {
295
+ function CopilotMessage2({ role, avatar, streaming, density = "comfortable", className, children, ...props }, ref) {
281
296
  const isAssistant = role === "assistant";
297
+ const isTouch = density === "touch";
298
+ if (isTouch) {
299
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
300
+ "div",
301
+ {
302
+ ref,
303
+ className: (0, import_ui6.cn)(
304
+ "flex flex-col gap-[6px]",
305
+ isAssistant ? "items-start" : "items-end",
306
+ className
307
+ ),
308
+ "data-role": role,
309
+ ...props,
310
+ children: [
311
+ isAssistant && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-m-eyebrow text-accent inline-flex items-center gap-[6px] font-mono tracking-wide uppercase", children: [
312
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": true, children: "\u2726" }),
313
+ streaming ? "thinking" : "ShipIt"
314
+ ] }),
315
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
316
+ "div",
317
+ {
318
+ className: (0, import_ui6.cn)(
319
+ "rounded-m-card text-m-body max-w-[85%] px-[14px] py-3 leading-normal",
320
+ isAssistant ? "bg-panel border-border border" : "bg-accent text-on-accent"
321
+ ),
322
+ children: [
323
+ children,
324
+ streaming && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
325
+ "span",
326
+ {
327
+ "aria-hidden": true,
328
+ className: "bg-accent ml-[2px] inline-block h-4 w-px animate-[ship-pulse_1s_infinite] align-middle"
329
+ }
330
+ )
331
+ ]
332
+ }
333
+ )
334
+ ]
335
+ }
336
+ );
337
+ }
282
338
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
283
339
  "div",
284
340
  {
@@ -323,8 +379,8 @@ CopilotMessage.displayName = "CopilotMessage";
323
379
 
324
380
  // src/ai/ReasoningBlock.tsx
325
381
  var import_ui7 = require("@ship-it-ui/ui");
326
- var import_react5 = require("react");
327
382
  var import_ui8 = require("@ship-it-ui/ui");
383
+ var import_react5 = require("react");
328
384
  var import_jsx_runtime5 = require("react/jsx-runtime");
329
385
  var ReasoningBlock = (0, import_react5.forwardRef)(
330
386
  function ReasoningBlock2({
@@ -385,8 +441,8 @@ var ReasoningStep = (0, import_react5.forwardRef)(function ReasoningStep2({ step
385
441
  ReasoningStep.displayName = "ReasoningStep";
386
442
 
387
443
  // src/ai/SuggestionChip.tsx
388
- var import_react6 = require("react");
389
444
  var import_ui9 = require("@ship-it-ui/ui");
445
+ var import_react6 = require("react");
390
446
  var import_jsx_runtime6 = require("react/jsx-runtime");
391
447
  var SuggestionChip = (0, import_react6.forwardRef)(
392
448
  function SuggestionChip2({ glyph = "\u2726", className, children, type, ...props }, ref) {
@@ -415,8 +471,8 @@ SuggestionChip.displayName = "SuggestionChip";
415
471
 
416
472
  // src/ai/ToolCallCard.tsx
417
473
  var import_ui10 = require("@ship-it-ui/ui");
418
- var import_react7 = require("react");
419
474
  var import_ui11 = require("@ship-it-ui/ui");
475
+ var import_react7 = require("react");
420
476
  var import_jsx_runtime7 = require("react/jsx-runtime");
421
477
  var ToolCallCard = (0, import_react7.forwardRef)(function ToolCallCard2({ name, status, running, className, children, ...props }, ref) {
422
478
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
@@ -449,64 +505,140 @@ ToolCallCard.displayName = "ToolCallCard";
449
505
 
450
506
  // src/entity/EntityBadge.tsx
451
507
  var import_ui12 = require("@ship-it-ui/ui");
452
- var import_react8 = require("react");
453
508
  var import_ui13 = require("@ship-it-ui/ui");
509
+ var import_react8 = require("react");
454
510
 
455
511
  // src/entity/types.ts
512
+ var BUILTIN_META = {
513
+ service: {
514
+ glyph: "\u25C7",
515
+ label: "Service",
516
+ toneClass: "text-accent",
517
+ toneBg: "bg-accent-dim",
518
+ colorVar: "var(--color-accent)",
519
+ badgeVariant: "accent"
520
+ },
521
+ person: {
522
+ glyph: "\u25CB",
523
+ label: "Person",
524
+ toneClass: "text-text-muted",
525
+ toneBg: "bg-panel-2",
526
+ colorVar: "var(--color-purple)",
527
+ badgeVariant: "neutral"
528
+ },
529
+ document: {
530
+ glyph: "\u25A4",
531
+ label: "Document",
532
+ toneClass: "text-purple",
533
+ toneBg: "bg-[color-mix(in_oklab,var(--color-purple),transparent_85%)]",
534
+ colorVar: "var(--color-pink)",
535
+ badgeVariant: "purple"
536
+ },
537
+ deployment: {
538
+ glyph: "\u2191",
539
+ label: "Deployment",
540
+ toneClass: "text-ok",
541
+ toneBg: "bg-[color-mix(in_oklab,var(--color-ok),transparent_85%)]",
542
+ colorVar: "var(--color-ok)",
543
+ badgeVariant: "ok"
544
+ },
545
+ incident: {
546
+ glyph: "\u25CE",
547
+ label: "Incident",
548
+ toneClass: "text-err",
549
+ toneBg: "bg-[color-mix(in_oklab,var(--color-err),transparent_85%)]",
550
+ colorVar: "var(--color-warn)",
551
+ badgeVariant: "err"
552
+ },
553
+ ticket: {
554
+ glyph: "\u25A2",
555
+ label: "Ticket",
556
+ toneClass: "text-warn",
557
+ toneBg: "bg-[color-mix(in_oklab,var(--color-warn),transparent_85%)]",
558
+ colorVar: "var(--color-text-muted)",
559
+ badgeVariant: "warn"
560
+ }
561
+ };
562
+ var FALLBACK = BUILTIN_META.service;
563
+ var registry = new Map(Object.entries(BUILTIN_META));
564
+ function registerEntityType(type, meta) {
565
+ registry.set(type, meta);
566
+ return meta;
567
+ }
568
+ function registerEntityTypes(map) {
569
+ for (const [key, meta] of Object.entries(map)) {
570
+ registry.set(key, meta);
571
+ }
572
+ }
573
+ function getEntityTypeMeta(type) {
574
+ return registry.get(type) ?? FALLBACK;
575
+ }
576
+ function listEntityTypes() {
577
+ return Array.from(registry.entries());
578
+ }
579
+ function resetEntityTypeRegistry() {
580
+ registry.clear();
581
+ for (const key of Object.keys(BUILTIN_META)) {
582
+ registry.set(key, BUILTIN_META[key]);
583
+ }
584
+ }
456
585
  var ENTITY_GLYPH = {
457
- service: "\u25C7",
458
- person: "\u25CB",
459
- document: "\u25A4",
460
- deployment: "\u2191",
461
- incident: "\u25CE",
462
- ticket: "\u25A2"
586
+ service: BUILTIN_META.service.glyph,
587
+ person: BUILTIN_META.person.glyph,
588
+ document: BUILTIN_META.document.glyph,
589
+ deployment: BUILTIN_META.deployment.glyph,
590
+ incident: BUILTIN_META.incident.glyph,
591
+ ticket: BUILTIN_META.ticket.glyph
463
592
  };
464
593
  var ENTITY_LABEL = {
465
- service: "Service",
466
- person: "Person",
467
- document: "Document",
468
- deployment: "Deployment",
469
- incident: "Incident",
470
- ticket: "Ticket"
594
+ service: BUILTIN_META.service.label,
595
+ person: BUILTIN_META.person.label,
596
+ document: BUILTIN_META.document.label,
597
+ deployment: BUILTIN_META.deployment.label,
598
+ incident: BUILTIN_META.incident.label,
599
+ ticket: BUILTIN_META.ticket.label
471
600
  };
472
601
  var ENTITY_TONE_CLASS = {
473
- service: "text-accent",
474
- person: "text-text-muted",
475
- document: "text-purple",
476
- deployment: "text-ok",
477
- incident: "text-err",
478
- ticket: "text-warn"
602
+ service: BUILTIN_META.service.toneClass,
603
+ person: BUILTIN_META.person.toneClass,
604
+ document: BUILTIN_META.document.toneClass,
605
+ deployment: BUILTIN_META.deployment.toneClass,
606
+ incident: BUILTIN_META.incident.toneClass,
607
+ ticket: BUILTIN_META.ticket.toneClass
479
608
  };
480
609
  var ENTITY_TONE_BG = {
481
- service: "bg-accent-dim",
482
- person: "bg-panel-2",
483
- document: "bg-[color-mix(in_oklab,var(--color-purple),transparent_85%)]",
484
- deployment: "bg-[color-mix(in_oklab,var(--color-ok),transparent_85%)]",
485
- incident: "bg-[color-mix(in_oklab,var(--color-err),transparent_85%)]",
486
- ticket: "bg-[color-mix(in_oklab,var(--color-warn),transparent_85%)]"
610
+ service: BUILTIN_META.service.toneBg,
611
+ person: BUILTIN_META.person.toneBg,
612
+ document: BUILTIN_META.document.toneBg,
613
+ deployment: BUILTIN_META.deployment.toneBg,
614
+ incident: BUILTIN_META.incident.toneBg,
615
+ ticket: BUILTIN_META.ticket.toneBg
487
616
  };
488
617
 
489
618
  // src/entity/EntityBadge.tsx
490
619
  var import_jsx_runtime8 = require("react/jsx-runtime");
491
- var typeVariant = {
492
- service: "accent",
493
- person: "neutral",
494
- document: "purple",
495
- deployment: "ok",
496
- incident: "err",
497
- ticket: "warn"
498
- };
499
620
  var EntityBadge = (0, import_react8.forwardRef)(function EntityBadge2({ type, label, hideGlyph, className, children, ...props }, ref) {
500
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ui12.Badge, { ref, variant: typeVariant[type], className: (0, import_ui13.cn)(className), ...props, children: [
501
- !hideGlyph && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": true, className: "font-mono", children: ENTITY_GLYPH[type] }),
502
- children ?? label ?? ENTITY_LABEL[type]
503
- ] });
621
+ const meta = getEntityTypeMeta(type);
622
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
623
+ import_ui12.Badge,
624
+ {
625
+ ref,
626
+ variant: meta.badgeVariant,
627
+ "data-entity-type": type,
628
+ className: (0, import_ui13.cn)(className),
629
+ ...props,
630
+ children: [
631
+ !hideGlyph && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": true, className: "font-mono", children: meta.glyph }),
632
+ children ?? label ?? meta.label
633
+ ]
634
+ }
635
+ );
504
636
  });
505
637
  EntityBadge.displayName = "EntityBadge";
506
638
 
507
639
  // src/entity/EntityCard.tsx
508
- var import_react9 = require("react");
509
640
  var import_ui14 = require("@ship-it-ui/ui");
641
+ var import_react9 = require("react");
510
642
  var import_jsx_runtime9 = require("react/jsx-runtime");
511
643
  var statToneClass = {
512
644
  accent: "text-accent",
@@ -516,10 +648,12 @@ var statToneClass = {
516
648
  muted: "text-text-muted"
517
649
  };
518
650
  var EntityCard = (0, import_react9.forwardRef)(function EntityCard2({ type, title, subtitle, description, stats, actions, glyph, className, ...props }, ref) {
651
+ const meta = getEntityTypeMeta(type);
519
652
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
520
653
  "div",
521
654
  {
522
655
  ref,
656
+ "data-entity-type": type,
523
657
  className: (0, import_ui14.cn)(
524
658
  "rounded-base border-border bg-panel flex flex-col gap-3 border p-5",
525
659
  className
@@ -533,10 +667,10 @@ var EntityCard = (0, import_react9.forwardRef)(function EntityCard2({ type, titl
533
667
  "aria-hidden": true,
534
668
  className: (0, import_ui14.cn)(
535
669
  "rounded-base grid h-12 w-12 shrink-0 place-items-center text-[20px]",
536
- ENTITY_TONE_BG[type],
537
- ENTITY_TONE_CLASS[type]
670
+ meta.toneBg,
671
+ meta.toneClass
538
672
  ),
539
- children: glyph ?? ENTITY_GLYPH[type]
673
+ children: glyph ?? meta.glyph
540
674
  }
541
675
  ),
542
676
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "min-w-0 flex-1", children: [
@@ -576,8 +710,8 @@ var EntityCard = (0, import_react9.forwardRef)(function EntityCard2({ type, titl
576
710
  EntityCard.displayName = "EntityCard";
577
711
 
578
712
  // src/entity/EntityListRow.tsx
579
- var import_react10 = require("react");
580
713
  var import_ui15 = require("@ship-it-ui/ui");
714
+ var import_react10 = require("react");
581
715
  var import_jsx_runtime10 = require("react/jsx-runtime");
582
716
  var baseClassNames = (interactive, className) => (0, import_ui15.cn)(
583
717
  "flex w-full items-center gap-3 border-0 bg-transparent px-2 py-2 text-left",
@@ -592,15 +726,9 @@ function RowInner({
592
726
  meta,
593
727
  hideGlyph
594
728
  }) {
729
+ const typeMeta = getEntityTypeMeta(type);
595
730
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
596
- !hideGlyph && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
597
- "span",
598
- {
599
- "aria-hidden": true,
600
- className: (0, import_ui15.cn)("font-mono text-[14px] leading-none", ENTITY_TONE_CLASS[type]),
601
- children: ENTITY_GLYPH[type]
602
- }
603
- ),
731
+ !hideGlyph && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "aria-hidden": true, className: (0, import_ui15.cn)("font-mono text-[14px] leading-none", typeMeta.toneClass), children: typeMeta.glyph }),
604
732
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-text min-w-0 flex-1 truncate font-mono text-[12px]", children: name }),
605
733
  relation && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "border-border bg-panel-2 text-text-muted rounded-full border px-2 py-[2px] font-mono text-[10px]", children: relation }),
606
734
  meta && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-text-dim font-mono text-[10px]", children: meta })
@@ -608,7 +736,16 @@ function RowInner({
608
736
  }
609
737
  var EntityListRowDiv = (0, import_react10.forwardRef)(
610
738
  function EntityListRowDiv2({ type, name, relation, meta, hideGlyph, className, ...props }, ref) {
611
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref, className: baseClassNames(false, className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RowInner, { type, name, relation, meta, hideGlyph }) });
739
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
740
+ "div",
741
+ {
742
+ ref,
743
+ "data-entity-type": type,
744
+ className: baseClassNames(false, className),
745
+ ...props,
746
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RowInner, { type, name, relation, meta, hideGlyph })
747
+ }
748
+ );
612
749
  }
613
750
  );
614
751
  EntityListRowDiv.displayName = "EntityListRowDiv";
@@ -619,6 +756,7 @@ var EntityListRowButton = (0, import_react10.forwardRef)(
619
756
  {
620
757
  ref,
621
758
  type: "button",
759
+ "data-entity-type": type,
622
760
  onClick,
623
761
  className: baseClassNames(true, className),
624
762
  ...props,
@@ -704,8 +842,8 @@ var GraphEdge = (0, import_react11.forwardRef)(function GraphEdge2({ x1, y1, x2,
704
842
  GraphEdge.displayName = "GraphEdge";
705
843
 
706
844
  // src/graph/GraphInspector.tsx
707
- var import_react12 = require("react");
708
845
  var import_ui16 = require("@ship-it-ui/ui");
846
+ var import_react12 = require("react");
709
847
  var import_jsx_runtime12 = require("react/jsx-runtime");
710
848
  var GraphInspector = (0, import_react12.forwardRef)(
711
849
  function GraphInspector2({
@@ -771,21 +909,13 @@ var GraphInspector = (0, import_react12.forwardRef)(
771
909
  GraphInspector.displayName = "GraphInspector";
772
910
 
773
911
  // src/graph/GraphLegend.tsx
774
- var import_react13 = require("react");
775
912
  var import_ui17 = require("@ship-it-ui/ui");
913
+ var import_react13 = require("react");
776
914
  var import_jsx_runtime13 = require("react/jsx-runtime");
777
- var typeColorVar = {
778
- service: "var(--color-accent)",
779
- person: "var(--color-purple)",
780
- document: "var(--color-pink)",
781
- deployment: "var(--color-ok)",
782
- incident: "var(--color-warn)",
783
- ticket: "var(--color-text-muted)"
784
- };
785
915
  var DEFAULT_ENTRIES = [
786
- { type: "service", label: ENTITY_LABEL.service },
787
- { type: "person", label: ENTITY_LABEL.person },
788
- { type: "document", label: ENTITY_LABEL.document }
916
+ { type: "service" },
917
+ { type: "person" },
918
+ { type: "document" }
789
919
  ];
790
920
  var GraphLegend = (0, import_react13.forwardRef)(function GraphLegend2({ entries = DEFAULT_ENTRIES, heading = "Legend", className, children, ...props }, ref) {
791
921
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
@@ -800,10 +930,12 @@ var GraphLegend = (0, import_react13.forwardRef)(function GraphLegend2({ entries
800
930
  children: [
801
931
  heading && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-text-dim font-mono text-[9px] tracking-[1.4px] uppercase", children: heading }),
802
932
  children ?? entries.map((entry, i) => {
803
- const color = entry.color ?? (entry.type ? typeColorVar[entry.type] : "currentColor");
933
+ const meta = entry.type ? getEntityTypeMeta(entry.type) : void 0;
934
+ const color = entry.color ?? meta?.colorVar ?? "currentColor";
935
+ const label = entry.label ?? meta?.label ?? "";
804
936
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-[6px]", children: [
805
937
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": true, className: "h-2 w-2 rounded-full", style: { background: color } }),
806
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: entry.label })
938
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: label })
807
939
  ] }, i);
808
940
  })
809
941
  ]
@@ -813,8 +945,8 @@ var GraphLegend = (0, import_react13.forwardRef)(function GraphLegend2({ entries
813
945
  GraphLegend.displayName = "GraphLegend";
814
946
 
815
947
  // src/graph/GraphMinimap.tsx
816
- var import_react14 = require("react");
817
948
  var import_ui18 = require("@ship-it-ui/ui");
949
+ var import_react14 = require("react");
818
950
  var import_jsx_runtime14 = require("react/jsx-runtime");
819
951
  var GraphMinimap = (0, import_react14.forwardRef)(function GraphMinimap2({ points, viewport, width = 120, height = 72, className, ...props }, ref) {
820
952
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
@@ -865,19 +997,12 @@ var GraphMinimap = (0, import_react14.forwardRef)(function GraphMinimap2({ point
865
997
  GraphMinimap.displayName = "GraphMinimap";
866
998
 
867
999
  // src/graph/GraphNode.tsx
868
- var import_react15 = require("react");
869
1000
  var import_ui19 = require("@ship-it-ui/ui");
1001
+ var import_react15 = require("react");
870
1002
  var import_jsx_runtime15 = require("react/jsx-runtime");
871
- var typeColorVar2 = {
872
- service: "var(--color-accent)",
873
- person: "var(--color-purple)",
874
- document: "var(--color-pink)",
875
- deployment: "var(--color-ok)",
876
- incident: "var(--color-warn)",
877
- ticket: "var(--color-text-muted)"
878
- };
879
1003
  var GraphNode = (0, import_react15.forwardRef)(function GraphNode2({ type, state = "default", glyph, label, size = 52, pathColor, className, style, ...props }, ref) {
880
- const color = state === "path" ? pathColor ?? "var(--color-purple)" : typeColorVar2[type];
1004
+ const meta = getEntityTypeMeta(type);
1005
+ const color = state === "path" ? pathColor ?? "var(--color-purple)" : meta.colorVar;
881
1006
  const glowPct = state === "hover" ? 50 : 25;
882
1007
  const opacity = state === "dim" ? 0.35 : 1;
883
1008
  const showRing = state === "selected" || state === "path";
@@ -908,7 +1033,7 @@ var GraphNode = (0, import_react15.forwardRef)(function GraphNode2({ type, state
908
1033
  outlineOffset: showRing ? 4 : void 0,
909
1034
  opacity
910
1035
  },
911
- children: glyph ?? ENTITY_GLYPH[type]
1036
+ children: glyph ?? meta.glyph
912
1037
  }
913
1038
  ),
914
1039
  label && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-text-dim font-mono text-[10px]", children: label })
@@ -953,8 +1078,8 @@ var PathOverlay = (0, import_react16.forwardRef)(function PathOverlay2({ points,
953
1078
  PathOverlay.displayName = "PathOverlay";
954
1079
 
955
1080
  // src/marketing/CTAStrip.tsx
956
- var import_react17 = require("react");
957
1081
  var import_ui20 = require("@ship-it-ui/ui");
1082
+ var import_react17 = require("react");
958
1083
  var import_jsx_runtime17 = require("react/jsx-runtime");
959
1084
  var CTAStrip = (0, import_react17.forwardRef)(function CTAStrip2({ title, description, actions, className, ...props }, ref) {
960
1085
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
@@ -978,8 +1103,8 @@ var CTAStrip = (0, import_react17.forwardRef)(function CTAStrip2({ title, descri
978
1103
  CTAStrip.displayName = "CTAStrip";
979
1104
 
980
1105
  // src/marketing/FeatureGrid.tsx
981
- var import_react18 = require("react");
982
1106
  var import_ui21 = require("@ship-it-ui/ui");
1107
+ var import_react18 = require("react");
983
1108
  var import_jsx_runtime18 = require("react/jsx-runtime");
984
1109
  var colsClass = {
985
1110
  2: "md:grid-cols-2",
@@ -1004,8 +1129,8 @@ var FeatureGrid = (0, import_react18.forwardRef)(function FeatureGrid2({ feature
1004
1129
  FeatureGrid.displayName = "FeatureGrid";
1005
1130
 
1006
1131
  // src/marketing/Footer.tsx
1007
- var import_react19 = require("react");
1008
1132
  var import_ui22 = require("@ship-it-ui/ui");
1133
+ var import_react19 = require("react");
1009
1134
  var import_jsx_runtime19 = require("react/jsx-runtime");
1010
1135
  var Footer = (0, import_react19.forwardRef)(function Footer2({ brand, columns, copyright, closing, className, ...props }, ref) {
1011
1136
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("footer", { ref, className: (0, import_ui22.cn)("px-7 py-7", className), ...props, children: [
@@ -1033,8 +1158,8 @@ var Footer = (0, import_react19.forwardRef)(function Footer2({ brand, columns, c
1033
1158
  Footer.displayName = "Footer";
1034
1159
 
1035
1160
  // src/marketing/Hero.tsx
1036
- var import_react20 = require("react");
1037
1161
  var import_ui23 = require("@ship-it-ui/ui");
1162
+ var import_react20 = require("react");
1038
1163
  var import_jsx_runtime20 = require("react/jsx-runtime");
1039
1164
  var Hero = (0, import_react20.forwardRef)(function Hero2({ eyebrow, title, description, actions, visual, className, ...props }, ref) {
1040
1165
  const hasVisual = visual != null;
@@ -1072,8 +1197,8 @@ var Hero = (0, import_react20.forwardRef)(function Hero2({ eyebrow, title, descr
1072
1197
  Hero.displayName = "Hero";
1073
1198
 
1074
1199
  // src/marketing/PricingCard.tsx
1075
- var import_react21 = require("react");
1076
1200
  var import_ui24 = require("@ship-it-ui/ui");
1201
+ var import_react21 = require("react");
1077
1202
  var import_jsx_runtime21 = require("react/jsx-runtime");
1078
1203
  var PricingCard = (0, import_react21.forwardRef)(function PricingCard2({ tier, price, priceUnit, description, features, action, featured, className, ...props }, ref) {
1079
1204
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
@@ -1111,8 +1236,8 @@ PricingCard.displayName = "PricingCard";
1111
1236
 
1112
1237
  // src/marketing/Testimonial.tsx
1113
1238
  var import_ui25 = require("@ship-it-ui/ui");
1114
- var import_react22 = require("react");
1115
1239
  var import_ui26 = require("@ship-it-ui/ui");
1240
+ var import_react22 = require("react");
1116
1241
  var import_jsx_runtime22 = require("react/jsx-runtime");
1117
1242
  var Testimonial = (0, import_react22.forwardRef)(function Testimonial2({ quote, author, role, avatar, className, ...props }, ref) {
1118
1243
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
@@ -1137,23 +1262,121 @@ var Testimonial = (0, import_react22.forwardRef)(function Testimonial2({ quote,
1137
1262
  });
1138
1263
  Testimonial.displayName = "Testimonial";
1139
1264
 
1140
- // src/data/EntityTable.tsx
1265
+ // src/data/ConnectorCard.tsx
1266
+ var import_icons = require("@ship-it-ui/icons");
1141
1267
  var import_ui27 = require("@ship-it-ui/ui");
1142
1268
  var import_react23 = require("react");
1143
1269
  var import_jsx_runtime23 = require("react/jsx-runtime");
1270
+ var statusDot = {
1271
+ connected: "ok",
1272
+ syncing: "sync",
1273
+ error: "err",
1274
+ disconnected: "off"
1275
+ };
1276
+ var statusLabel = {
1277
+ connected: "Connected",
1278
+ syncing: "Syncing",
1279
+ error: "Error",
1280
+ disconnected: "Disconnected"
1281
+ };
1282
+ var ConnectorCard = (0, import_react23.forwardRef)(function ConnectorCard2({
1283
+ connector,
1284
+ name,
1285
+ status,
1286
+ lastSyncedAt,
1287
+ relativeNow,
1288
+ summary,
1289
+ actions,
1290
+ onClick,
1291
+ accessibleName,
1292
+ className,
1293
+ ...props
1294
+ }, ref) {
1295
+ const interactive = typeof onClick === "function";
1296
+ const time = lastSyncedAt ? (0, import_ui27.formatRelative)(lastSyncedAt, relativeNow ?? /* @__PURE__ */ new Date()) : "";
1297
+ const labelBlock = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
1298
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1299
+ "span",
1300
+ {
1301
+ "aria-hidden": true,
1302
+ className: "bg-panel-2 grid h-10 w-10 shrink-0 place-items-center rounded-md font-mono text-[16px]",
1303
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons.IconGlyph, { name: connector, kind: "connector" })
1304
+ }
1305
+ ),
1306
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "min-w-0 flex-1", children: [
1307
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
1308
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-[14px] font-medium", children: name }),
1309
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1310
+ import_ui27.StatusDot,
1311
+ {
1312
+ state: statusDot[status],
1313
+ pulse: status === "syncing",
1314
+ label: statusLabel[status]
1315
+ }
1316
+ )
1317
+ ] }),
1318
+ (summary || time) && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "text-text-muted mt-[2px] flex items-center gap-2 text-[12px]", children: [
1319
+ summary && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate", children: summary }),
1320
+ summary && time && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": true, className: "text-text-dim", children: "\xB7" }),
1321
+ time && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("time", { className: "text-text-dim font-mono text-[11px]", children: [
1322
+ "last synced ",
1323
+ time
1324
+ ] })
1325
+ ] })
1326
+ ] })
1327
+ ] });
1328
+ const labelRegionClass = (0, import_ui27.cn)(
1329
+ "flex flex-1 items-start gap-3 rounded-md p-1 text-left transition-colors duration-(--duration-micro)",
1330
+ interactive && "hover:bg-panel-2 focus-visible:ring-accent-dim cursor-pointer outline-none focus-visible:ring-[3px]"
1331
+ );
1332
+ const labelRegion = interactive ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1333
+ "button",
1334
+ {
1335
+ type: "button",
1336
+ onClick,
1337
+ "aria-label": accessibleName ?? (typeof name === "string" ? `${name} connector` : statusLabel[status]),
1338
+ className: labelRegionClass,
1339
+ children: labelBlock
1340
+ }
1341
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: labelRegionClass, children: labelBlock });
1342
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1343
+ "div",
1344
+ {
1345
+ ref,
1346
+ className: (0, import_ui27.cn)(
1347
+ "rounded-base border-border bg-panel flex items-start gap-2 border p-3",
1348
+ className
1349
+ ),
1350
+ ...props,
1351
+ children: [
1352
+ labelRegion,
1353
+ actions && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "shrink-0 self-center pr-1", children: actions })
1354
+ ]
1355
+ }
1356
+ );
1357
+ });
1358
+ ConnectorCard.displayName = "ConnectorCard";
1359
+
1360
+ // src/data/EntityTable.tsx
1361
+ var import_ui28 = require("@ship-it-ui/ui");
1362
+ var import_react24 = require("react");
1363
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1144
1364
  function EntityTable(props) {
1145
1365
  const { rowKey, ...rest } = props;
1146
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ui27.DataTable, { ...rest, rowKey: rowKey ?? ((row) => row.id) });
1366
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui28.DataTable, { ...rest, rowKey: rowKey ?? ((row) => row.id) });
1147
1367
  }
1148
1368
  function entityColumn(options = {}) {
1149
1369
  return {
1150
1370
  key: options.key ?? "name",
1151
1371
  header: options.header ?? "Name",
1152
1372
  accessor: (row) => row.name,
1153
- cell: (row) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "flex items-center gap-2 font-mono", children: [
1154
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": true, className: ENTITY_TONE_CLASS[row.type], children: ENTITY_GLYPH[row.type] }),
1155
- row.name
1156
- ] })
1373
+ cell: (row) => {
1374
+ const meta = getEntityTypeMeta(row.type);
1375
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "flex items-center gap-2 font-mono", "data-entity-type": row.type, children: [
1376
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { "aria-hidden": true, className: meta.toneClass, children: meta.glyph }),
1377
+ row.name
1378
+ ] });
1379
+ }
1157
1380
  };
1158
1381
  }
1159
1382
  function entityTypeColumn(options = {}) {
@@ -1161,15 +1384,98 @@ function entityTypeColumn(options = {}) {
1161
1384
  key: options.key ?? "type",
1162
1385
  header: options.header ?? "Type",
1163
1386
  accessor: (row) => row.type,
1164
- cell: (row) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EntityBadge, { type: row.type, size: "sm" })
1387
+ cell: (row) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EntityBadge, { type: row.type, size: "sm" })
1165
1388
  };
1166
1389
  }
1390
+
1391
+ // src/notifications/NotifRow.tsx
1392
+ var import_ui29 = require("@ship-it-ui/ui");
1393
+ var import_react25 = require("react");
1394
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1395
+ var toneClass = {
1396
+ ok: "bg-ok",
1397
+ warn: "bg-warn",
1398
+ err: "bg-err",
1399
+ neutral: "bg-accent-text"
1400
+ };
1401
+ var NotifRow = (0, import_react25.forwardRef)(function NotifRow2({
1402
+ title,
1403
+ body,
1404
+ time,
1405
+ tone = "neutral",
1406
+ unread,
1407
+ isFirst,
1408
+ isLast,
1409
+ href,
1410
+ className,
1411
+ onClick,
1412
+ ...props
1413
+ }, ref) {
1414
+ const content = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
1415
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pt-1", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1416
+ "div",
1417
+ {
1418
+ className: (0, import_ui29.cn)("h-2 w-2 rounded-full", unread ? toneClass[tone] : "bg-border-strong")
1419
+ }
1420
+ ) }),
1421
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "min-w-0 flex-1", children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
1423
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "truncate text-[14px] font-medium tracking-tight", children: title }),
1424
+ time != null && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-text-muted shrink-0 font-mono text-[11px] whitespace-nowrap", children: time })
1425
+ ] }),
1426
+ body && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-text-muted mt-[3px] text-[13px] leading-tight", children: body })
1427
+ ] })
1428
+ ] });
1429
+ const baseClass = (0, import_ui29.cn)(
1430
+ "flex gap-3 p-[14px] bg-panel border-border border-l border-r",
1431
+ isFirst ? "border-t rounded-t-m-card" : "",
1432
+ "border-b",
1433
+ isLast ? "rounded-b-m-card" : "",
1434
+ href || onClick ? "cursor-pointer hover:bg-panel-2" : "",
1435
+ className
1436
+ );
1437
+ if (href) {
1438
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1439
+ "a",
1440
+ {
1441
+ ref,
1442
+ href,
1443
+ onClick,
1444
+ className: (0, import_ui29.cn)(
1445
+ baseClass,
1446
+ "text-text focus-visible:ring-accent-dim no-underline outline-none focus-visible:ring-[3px]"
1447
+ ),
1448
+ ...props,
1449
+ children: content
1450
+ }
1451
+ );
1452
+ }
1453
+ if (onClick) {
1454
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1455
+ "button",
1456
+ {
1457
+ type: "button",
1458
+ ref,
1459
+ onClick,
1460
+ className: (0, import_ui29.cn)(
1461
+ baseClass,
1462
+ "focus-visible:ring-accent-dim text-left outline-none focus-visible:ring-[3px]"
1463
+ ),
1464
+ ...props,
1465
+ children: content
1466
+ }
1467
+ );
1468
+ }
1469
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref, className: baseClass, ...props, children: content });
1470
+ });
1471
+ NotifRow.displayName = "NotifRow";
1167
1472
  // Annotate the CommonJS export names for ESM import in node:
1168
1473
  0 && (module.exports = {
1169
1474
  AskBar,
1170
1475
  CTAStrip,
1171
1476
  Citation,
1172
1477
  ConfidenceIndicator,
1478
+ ConnectorCard,
1173
1479
  CopilotMessage,
1174
1480
  ENTITY_GLYPH,
1175
1481
  ENTITY_LABEL,
@@ -1189,6 +1495,7 @@ function entityTypeColumn(options = {}) {
1189
1495
  GraphMinimap,
1190
1496
  GraphNode,
1191
1497
  Hero,
1498
+ NotifRow,
1192
1499
  PathOverlay,
1193
1500
  PricingCard,
1194
1501
  ReasoningBlock,
@@ -1198,6 +1505,11 @@ function entityTypeColumn(options = {}) {
1198
1505
  ToolCallCard,
1199
1506
  cn,
1200
1507
  entityColumn,
1201
- entityTypeColumn
1508
+ entityTypeColumn,
1509
+ getEntityTypeMeta,
1510
+ listEntityTypes,
1511
+ registerEntityType,
1512
+ registerEntityTypes,
1513
+ resetEntityTypeRegistry
1202
1514
  });
1203
1515
  //# sourceMappingURL=index.cjs.map