@ai-matrx/content-ir-react 0.10.0 → 0.11.1

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/db-component.d.cts +8 -8
  3. package/dist/db-component.d.ts +8 -8
  4. package/dist/directive-host-DAb7Keg8.d.cts +63 -0
  5. package/dist/directive-host-DAb7Keg8.d.ts +63 -0
  6. package/dist/directives.cjs +382 -0
  7. package/dist/directives.cjs.map +1 -0
  8. package/dist/directives.d.cts +70 -0
  9. package/dist/directives.d.ts +70 -0
  10. package/dist/directives.js +369 -0
  11. package/dist/directives.js.map +1 -0
  12. package/dist/{host-types-CDcLW0TD.d.cts → host-types-C8jR31Wk.d.cts} +9 -0
  13. package/dist/{host-types-CpItjcYh.d.ts → host-types-IUEDmso7.d.ts} +9 -0
  14. package/dist/host.cjs +14 -4
  15. package/dist/host.cjs.map +1 -1
  16. package/dist/host.d.cts +5 -4
  17. package/dist/host.d.ts +5 -4
  18. package/dist/host.js +14 -4
  19. package/dist/host.js.map +1 -1
  20. package/dist/index.cjs +474 -47
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +85 -21
  23. package/dist/index.d.ts +85 -21
  24. package/dist/index.js +479 -36
  25. package/dist/index.js.map +1 -1
  26. package/dist/react.cjs +401 -46
  27. package/dist/react.cjs.map +1 -1
  28. package/dist/react.d.cts +11 -10
  29. package/dist/react.d.ts +11 -10
  30. package/dist/react.js +404 -33
  31. package/dist/react.js.map +1 -1
  32. package/dist/{route-QL2Vqf2e.d.cts → route-B9U-9QCw.d.cts} +117 -3
  33. package/dist/{route-PUuEuEug.d.ts → route-gNpJ8zzW.d.ts} +117 -3
  34. package/dist/route.cjs +52 -2
  35. package/dist/route.cjs.map +1 -1
  36. package/dist/route.d.cts +1 -1
  37. package/dist/route.d.ts +1 -1
  38. package/dist/route.js +55 -2
  39. package/dist/route.js.map +1 -1
  40. package/package.json +15 -2
package/dist/react.cjs CHANGED
@@ -45,14 +45,25 @@ __export(react_exports, {
45
45
  module.exports = __toCommonJS(react_exports);
46
46
 
47
47
  // react/use-kind-version.ts
48
- var import_react2 = require("react");
48
+ var import_react3 = require("react");
49
49
 
50
50
  // host/ContentIrProvider.tsx
51
+ var import_react2 = require("react");
52
+
53
+ // directives/directive-host.tsx
51
54
  var import_react = require("react");
52
55
  var import_jsx_runtime = require("react/jsx-runtime");
53
- var ContentIrHostContext = (0, import_react.createContext)(null);
56
+ var DirectiveHostContext = (0, import_react.createContext)(null);
57
+ var EMPTY_HOST = {};
58
+ function useDirectiveHost() {
59
+ return (0, import_react.useContext)(DirectiveHostContext) ?? EMPTY_HOST;
60
+ }
61
+
62
+ // host/ContentIrProvider.tsx
63
+ var import_jsx_runtime2 = require("react/jsx-runtime");
64
+ var ContentIrHostContext = (0, import_react2.createContext)(null);
54
65
  function useContentIrHostOrNull() {
55
- return (0, import_react.useContext)(ContentIrHostContext);
66
+ return (0, import_react2.useContext)(ContentIrHostContext);
56
67
  }
57
68
  function useContentIrHost() {
58
69
  const host = useContentIrHostOrNull();
@@ -76,7 +87,7 @@ function useContentIrKindVersion(kind, sources) {
76
87
  "[content-ir-react] useContentIrKindVersion needs either a ContentIrRenderProvider above it or explicit `sources`."
77
88
  );
78
89
  }
79
- const subscribe = (0, import_react2.useCallback)(
90
+ const subscribe = (0, import_react3.useCallback)(
80
91
  (onStoreChange) => {
81
92
  if (!kind || !resolved) return noopSubscribe();
82
93
  const unsubKinds = resolved.kinds.subscribeKind(kind, onStoreChange);
@@ -91,7 +102,7 @@ function useContentIrKindVersion(kind, sources) {
91
102
  },
92
103
  [resolved, kind]
93
104
  );
94
- const getSnapshot = (0, import_react2.useCallback)(
105
+ const getSnapshot = (0, import_react3.useCallback)(
95
106
  () => kind && resolved ? (
96
107
  // Both counters are monotonic, so the sum is monotonic — a change in
97
108
  // either registry produces a new snapshot value for this kind.
@@ -99,15 +110,346 @@ function useContentIrKindVersion(kind, sources) {
99
110
  ) : 0,
100
111
  [resolved, kind]
101
112
  );
102
- return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, zero);
113
+ return (0, import_react3.useSyncExternalStore)(subscribe, getSnapshot, zero);
103
114
  }
104
115
 
105
116
  // react/KindInstanceRender.tsx
106
- var import_react3 = require("react");
117
+ var import_react6 = require("react");
118
+ var import_content_ir6 = require("@ai-matrx/content-ir");
119
+
120
+ // directives/DirectiveRender.tsx
121
+ var import_content_ir4 = require("@ai-matrx/content-ir");
122
+
123
+ // directives/DirectiveFallbackCard.tsx
124
+ var import_content_ir = require("@ai-matrx/content-ir");
125
+
126
+ // directives/ApplyDirectiveButton.tsx
127
+ var import_react4 = require("react");
128
+
129
+ // directives/icons.tsx
130
+ var import_jsx_runtime3 = require("react/jsx-runtime");
131
+ function Svg({ children, ...props }) {
132
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
133
+ "svg",
134
+ {
135
+ xmlns: "http://www.w3.org/2000/svg",
136
+ viewBox: "0 0 24 24",
137
+ fill: "none",
138
+ stroke: "currentColor",
139
+ strokeWidth: 2,
140
+ strokeLinecap: "round",
141
+ strokeLinejoin: "round",
142
+ "aria-hidden": "true",
143
+ ...props,
144
+ children
145
+ }
146
+ );
147
+ }
148
+ var FilePlusIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
149
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4" }),
150
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
151
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M3 15h6" }),
152
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M6 12v6" })
153
+ ] });
154
+ var PencilIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
155
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 20h9" }),
156
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z" })
157
+ ] });
158
+ var TrashIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
159
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M3 6h18" }),
160
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
161
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" }),
162
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "10", x2: "10", y1: "11", y2: "17" }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "14", x2: "14", y1: "11", y2: "17" })
164
+ ] });
165
+ var PlayIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Svg, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { points: "6 3 20 12 6 21 6 3" }) });
166
+ var WebhookIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
167
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2" }),
168
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m6 17 3.13-5.78c.53-.97.1-2.01-.4-2.96A4 4 0 0 1 14 5.5c.63.42 1.13 1 1.44 1.66" }),
169
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8" })
170
+ ] });
171
+ var BoxesIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
172
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
173
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m7 16.5-4.74-2.85" }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m7 16.5 5-3" }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7 16.5v5.17" }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
177
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m17 16.5-5-3" }),
178
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m17 16.5 4.74-2.85" }),
179
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M17 16.5v5.17" }),
180
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
181
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 8 7.26 5.15" }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m12 8 4.74-2.85" }),
183
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 13.5V8" })
184
+ ] });
185
+ var ChevronDownIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Svg, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m6 9 6 6 6-6" }) });
186
+ var ChevronRightIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Svg, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m9 18 6-6-6-6" }) });
187
+ var MaximizeIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
188
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "15 3 21 3 21 9" }),
189
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "9 21 3 21 3 15" }),
190
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "21", x2: "14", y1: "3", y2: "10" }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "3", x2: "10", y1: "21", y2: "14" })
192
+ ] });
193
+ var LoaderIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Svg, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
194
+ var CheckCircleIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
195
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
196
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m9 12 2 2 4-4" })
197
+ ] });
198
+ var AlertIcon = (p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg, { ...p, children: [
199
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
200
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 9v4" }),
201
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 17h.01" })
202
+ ] });
203
+ var AGENT_NOUNS = /* @__PURE__ */ new Set(["create_agent", "create_agent_definition", "agent"]);
204
+ function classIcon(directiveClass, noun) {
205
+ if (directiveClass === "action" && AGENT_NOUNS.has(noun)) return WebhookIcon;
206
+ switch (directiveClass) {
207
+ case "create":
208
+ return FilePlusIcon;
209
+ case "update":
210
+ return PencilIcon;
211
+ case "delete":
212
+ return TrashIcon;
213
+ default:
214
+ return PlayIcon;
215
+ }
216
+ }
217
+
218
+ // directives/ApplyDirectiveButton.tsx
219
+ var import_jsx_runtime4 = require("react/jsx-runtime");
220
+ function ApplyDirectiveButton({
221
+ directive,
222
+ label = "Apply",
223
+ itemCount,
224
+ onApplied
225
+ }) {
226
+ const host = useDirectiveHost();
227
+ const [state, setState] = (0, import_react4.useState)({ status: "idle" });
228
+ const [elapsed, setElapsed] = (0, import_react4.useState)(0);
229
+ const startedAt = (0, import_react4.useRef)(null);
230
+ (0, import_react4.useEffect)(() => {
231
+ if (state.status !== "applying") return;
232
+ startedAt.current = Date.now();
233
+ const id = setInterval(
234
+ () => setElapsed(Math.round((Date.now() - (startedAt.current ?? 0)) / 1e3)),
235
+ 1e3
236
+ );
237
+ return () => clearInterval(id);
238
+ }, [state.status]);
239
+ if (!directive.parsed.executes) return null;
240
+ const confirm = host.confirm;
241
+ if (!confirm) return null;
242
+ const items = directive.items;
243
+ async function handleApply() {
244
+ if (!confirm) return;
245
+ setState({ status: "applying" });
246
+ try {
247
+ const result = await confirm({ __kind: directive.slug, items });
248
+ setState({ status: "applied", applied: result.applied, failed: result.failed });
249
+ onApplied?.();
250
+ } catch (error) {
251
+ setState({
252
+ status: "error",
253
+ message: error instanceof Error && error.message ? error.message : "That couldn't be applied just now. Please try again."
254
+ });
255
+ }
256
+ }
257
+ if (state.status === "applied") {
258
+ const bad = state.failed > 0;
259
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
260
+ "span",
261
+ {
262
+ className: `inline-flex items-center gap-1 text-xs ${bad ? "text-destructive" : "text-primary"}`,
263
+ children: [
264
+ bad ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertIcon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckCircleIcon, { className: "h-3.5 w-3.5" }),
265
+ "Applied ",
266
+ state.applied,
267
+ bad ? ` \xB7 ${state.failed} failed` : ""
268
+ ]
269
+ }
270
+ );
271
+ }
272
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
273
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
274
+ "button",
275
+ {
276
+ type: "button",
277
+ onClick: () => void handleApply(),
278
+ disabled: state.status === "applying" || items.length === 0,
279
+ className: "inline-flex items-center gap-1 rounded-md border border-border bg-background px-2 py-1 text-xs font-medium hover:bg-accent disabled:opacity-50",
280
+ children: [
281
+ state.status === "applying" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LoaderIcon, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PlayIcon, { className: "h-3.5 w-3.5" }),
282
+ state.status === "applying" ? `Applying${itemCount ? ` ${itemCount} ${itemCount === 1 ? "item" : "items"}` : ""}\u2026${elapsed ? ` ${elapsed}s` : ""}` : label
283
+ ]
284
+ }
285
+ ),
286
+ state.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "inline-flex max-w-sm items-start gap-1 text-xs text-destructive", children: [
287
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertIcon, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
288
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: state.message })
289
+ ] }) : null
290
+ ] });
291
+ }
292
+
293
+ // directives/DirectiveFallbackCard.tsx
294
+ var import_jsx_runtime5 = require("react/jsx-runtime");
295
+ function DirectiveFallbackCard({ directive, reason }) {
296
+ const host = useDirectiveHost();
297
+ const count = directive.items.length;
298
+ const display = (0, import_content_ir.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
299
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "my-3 inline-flex flex-wrap items-center gap-2 rounded-md border border-border bg-muted px-2.5 py-1 text-sm", children: [
300
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(BoxesIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
301
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-foreground", children: display.title }),
302
+ display.family ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-muted-foreground", children: [
303
+ "\xB7 ",
304
+ display.family
305
+ ] }) : null,
306
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-muted-foreground", children: [
307
+ "\xB7 ",
308
+ count,
309
+ " ",
310
+ count === 1 ? "item" : "items"
311
+ ] }),
312
+ reason ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-muted-foreground", children: [
313
+ "\xB7 ",
314
+ reason
315
+ ] }) : null,
316
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ApplyDirectiveButton, { directive })
317
+ ] });
318
+ }
319
+
320
+ // directives/registry.ts
107
321
  var import_content_ir2 = require("@ai-matrx/content-ir");
322
+ var REGISTRY_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.content-ir-react.directive-renderers");
323
+ var registry = globalThis[REGISTRY_SLOT] ??= {
324
+ bySlug: /* @__PURE__ */ new Map(),
325
+ byClass: /* @__PURE__ */ new Map()
326
+ };
327
+ function getDirectiveRenderer(directive) {
328
+ return registry.bySlug.get(directive.slug) ?? registry.byClass.get(directive.directiveClass) ?? null;
329
+ }
330
+
331
+ // directives/SideEffectDirectiveCard.tsx
332
+ var import_react5 = require("react");
333
+ var import_content_ir3 = require("@ai-matrx/content-ir");
334
+ var import_jsx_runtime6 = require("react/jsx-runtime");
335
+ var ROWS_BEFORE_FOLD = 3;
336
+ function ItemRow({
337
+ directive,
338
+ item,
339
+ index,
340
+ total
341
+ }) {
342
+ const host = useDirectiveHost();
343
+ const titleColumn = (0, import_content_ir3.nounTitleColumn)(directive.noun, host.nouns);
344
+ const title = (0, import_content_ir3.itemTitle)(item, titleColumn, index, total);
345
+ const subtitle = (0, import_content_ir3.itemSubtitle)(item);
346
+ const facts = (0, import_content_ir3.itemFacts)(item);
347
+ const kind = host.itemKind?.(directive.slug) ?? null;
348
+ const display = (0, import_content_ir3.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
349
+ const openItem = host.openItem;
350
+ const body = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
351
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "min-w-0 shrink-0 truncate font-medium text-foreground", children: title }),
352
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hidden min-w-0 flex-1 items-baseline gap-2 overflow-hidden sm:flex", children: facts.map((fact) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "truncate text-[11px] text-muted-foreground", children: [
353
+ fact.value,
354
+ " ",
355
+ fact.label
356
+ ] }, fact.key)) }),
357
+ subtitle && facts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hidden truncate text-[11px] text-muted-foreground sm:inline", children: subtitle }) : null,
358
+ openItem ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MaximizeIcon, { className: "ml-auto h-3 w-3 shrink-0 text-muted-foreground" }) : null
359
+ ] });
360
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
361
+ openItem ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
362
+ "button",
363
+ {
364
+ type: "button",
365
+ onClick: () => openItem({
366
+ // Stamped so the panel's kind pipeline types it from its own first key.
367
+ item: (0, import_content_ir3.asKindInstance)(item, kind) ?? item,
368
+ itemKind: kind,
369
+ title,
370
+ subtitle: `${display.title} \xB7 item ${index + 1} of ${total}`,
371
+ directive,
372
+ index,
373
+ total
374
+ }),
375
+ className: "flex min-w-0 flex-1 items-center gap-2 rounded px-1 py-0.5 text-left hover:bg-accent hover:text-accent-foreground",
376
+ title: "Open to read it",
377
+ children: body
378
+ }
379
+ ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "flex min-w-0 flex-1 items-center gap-2 px-1 py-0.5", children: body }),
380
+ host.renderCopy?.({ label: title, value: item, kind, size: "xs" })
381
+ ] });
382
+ }
383
+ function SideEffectDirectiveCard({ directive }) {
384
+ const host = useDirectiveHost();
385
+ const [expanded, setExpanded] = (0, import_react5.useState)(false);
386
+ const items = directive.items;
387
+ const total = items.length;
388
+ const display = (0, import_content_ir3.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
389
+ const Icon = classIcon(directive.directiveClass, directive.noun);
390
+ const shown = expanded ? items : items.slice(0, ROWS_BEFORE_FOLD);
391
+ const hidden = total - shown.length;
392
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "my-3 rounded-md border border-border bg-card px-2.5 py-1.5", "data-directive": directive.slug, children: [
393
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
394
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
395
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm font-medium text-foreground", children: display.title }),
396
+ display.family ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-xs text-muted-foreground", children: display.family }) : null,
397
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "text-xs tabular-nums text-muted-foreground", children: [
398
+ total,
399
+ " ",
400
+ total === 1 ? "item" : "items"
401
+ ] }),
402
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ml-auto flex items-center gap-1", children: [
403
+ host.renderCopy?.({ label: display.title, value: directive.shell, size: "icon" }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ApplyDirectiveButton, { directive, itemCount: total })
405
+ ] })
406
+ ] }),
407
+ total === 0 ? (
408
+ // Stated, never silent: an empty batch is a real (and suspicious) state.
409
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-1 text-xs text-muted-foreground", children: "No items \u2014 nothing would be written." })
410
+ ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mt-0.5 divide-y divide-border/60", children: shown.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ItemRow, { directive, item, index: i, total }, i)) }),
411
+ hidden > 0 || expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
412
+ "button",
413
+ {
414
+ type: "button",
415
+ onClick: () => setExpanded((v) => !v),
416
+ className: "mt-0.5 inline-flex items-center gap-1 rounded px-1 py-0.5 text-[11px] text-muted-foreground hover:text-foreground",
417
+ children: [
418
+ expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronDownIcon, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronRightIcon, { className: "h-3 w-3" }),
419
+ expanded ? "Show less" : `Show ${hidden} more`
420
+ ]
421
+ }
422
+ ) : null
423
+ ] });
424
+ }
425
+
426
+ // directives/DirectiveRender.tsx
427
+ var import_jsx_runtime7 = require("react/jsx-runtime");
428
+ function DirectiveRender({ content, className }) {
429
+ const host = useDirectiveHost();
430
+ const directive = (0, import_content_ir4.tryDecodeDirectiveContent)(content, (message) => {
431
+ const line = `[kind-directives] ${message}`;
432
+ if (host.reportError) host.reportError(line);
433
+ else console.error(line);
434
+ });
435
+ if (!directive) {
436
+ const raw = typeof content === "string" ? content : JSON.stringify(content, null, 2);
437
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
438
+ "pre",
439
+ {
440
+ className: `my-3 overflow-x-auto rounded-md border border-border bg-muted px-3 py-2 text-xs text-muted-foreground${className ? ` ${className}` : ""}`,
441
+ children: raw
442
+ }
443
+ );
444
+ }
445
+ const Renderer = getDirectiveRenderer(directive);
446
+ if (Renderer) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Renderer, { directive });
447
+ if (directive.parsed.executes) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SideEffectDirectiveCard, { directive });
448
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DirectiveFallbackCard, { directive });
449
+ }
108
450
 
109
451
  // route/kind-route.ts
110
- var import_content_ir = require("@ai-matrx/content-ir");
452
+ var import_content_ir5 = require("@ai-matrx/content-ir");
111
453
  var IR_ROUTE_KEY = "__ir_route";
112
454
  var GENERIC_STRUCTURED_COMPONENT_KEY = "generic_structured";
113
455
  var SOURCELESS_DB_ROW_SLOT = /* @__PURE__ */ Symbol.for(
@@ -126,17 +468,30 @@ function readIrRouteMarker(metadata) {
126
468
  }
127
469
 
128
470
  // react/KindInstanceRender.tsx
129
- var import_jsx_runtime2 = require("react/jsx-runtime");
471
+ var import_jsx_runtime8 = require("react/jsx-runtime");
130
472
  function isRecordValue(value) {
131
473
  return typeof value === "object" && value !== null && !Array.isArray(value);
132
474
  }
133
475
  function kindIsRoutable(kind, host) {
476
+ if ((0, import_content_ir6.isReservedDirectiveSlug)(kind)) return true;
134
477
  if (host.kinds.getDefinition(kind)?.legacyBlockType) return true;
135
478
  const resolution = host.components.resolve(kind, host.platform, "output");
136
479
  if (!resolution?.isActive) return false;
137
480
  return resolution.componentKey !== GENERIC_STRUCTURED_COMPONENT_KEY;
138
481
  }
139
- function KindInstanceRender({
482
+ function KindInstanceRender(props) {
483
+ if ((0, import_content_ir6.isReservedDirectiveSlug)(props.kind)) {
484
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
485
+ DirectiveRender,
486
+ {
487
+ content: props.value,
488
+ ...props.className === void 0 ? {} : { className: props.className }
489
+ }
490
+ );
491
+ }
492
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(KindInstanceRenderInner, { ...props });
493
+ }
494
+ function KindInstanceRenderInner({
140
495
  kind,
141
496
  value,
142
497
  showRoutingNote = true,
@@ -145,10 +500,10 @@ function KindInstanceRender({
145
500
  className
146
501
  }) {
147
502
  const host = useContentIrHost();
148
- const [routingStatus, setRoutingStatus] = (0, import_react3.useState)(
503
+ const [routingStatus, setRoutingStatus] = (0, import_react6.useState)(
149
504
  () => kindIsRoutable(kind, host) ? "routable" : "checking"
150
505
  );
151
- (0, import_react3.useEffect)(() => {
506
+ (0, import_react6.useEffect)(() => {
152
507
  let cancelled = false;
153
508
  let warmed = false;
154
509
  const syncRoutingStatus = () => {
@@ -180,26 +535,26 @@ function KindInstanceRender({
180
535
  content: JSON.stringify(value, null, 2),
181
536
  language: "json",
182
537
  metadata: {
183
- [import_content_ir2.IR_ENVELOPE_KEY]: (0, import_content_ir2.envelopeFromCompleteValue)(value, kind)
538
+ [import_content_ir6.IR_ENVELOPE_KEY]: (0, import_content_ir6.envelopeFromCompleteValue)(value, kind)
184
539
  }
185
540
  } : null;
186
541
  const frameClass = variant === "bare" ? void 0 : "rounded-md border border-border bg-card p-3";
187
542
  if (routingStatus === "unroutable" && unroutableFallback !== void 0) {
188
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: unroutableFallback });
543
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: unroutableFallback });
189
544
  }
190
545
  const onTheFloor = block === null || routingStatus === "unroutable";
191
546
  const notice = "This shape has no custom component yet, so it renders through the universal viewer \u2014 exactly what production shows today.";
192
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: className ? `space-y-3 ${className}` : "space-y-3", children: [
193
- showRoutingNote && routingStatus === "unroutable" ? host.renderNotice?.(notice) ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-xs text-amber-800 dark:text-amber-200", children: notice }) : null,
194
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: frameClass, children: onTheFloor ? host.renderValue({ value, kind }) : host.renderBlock(block) })
547
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: className ? `space-y-3 ${className}` : "space-y-3", children: [
548
+ showRoutingNote && routingStatus === "unroutable" ? host.renderNotice?.(notice) ?? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-xs text-amber-800 dark:text-amber-200", children: notice }) : null,
549
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: frameClass, children: onTheFloor ? host.renderValue({ value, kind }) : host.renderBlock(block) })
195
550
  ] });
196
551
  }
197
552
 
198
553
  // react/ProvisionalKindBoundary.tsx
199
- var import_react4 = __toESM(require("react"), 1);
554
+ var import_react7 = __toESM(require("react"), 1);
200
555
 
201
556
  // route/partial-kind-route.ts
202
- var import_content_ir3 = require("@ai-matrx/content-ir");
557
+ var import_content_ir7 = require("@ai-matrx/content-ir");
203
558
  var PARTIAL_UNSAFE_SLOT = /* @__PURE__ */ Symbol.for(
204
559
  "ai-matrx.content-ir-react.partial-unsafe-kinds"
205
560
  );
@@ -209,8 +564,8 @@ function markKindPartialUnsafe(kind) {
209
564
  }
210
565
 
211
566
  // react/ProvisionalKindBoundary.tsx
212
- var import_jsx_runtime3 = require("react/jsx-runtime");
213
- var ProvisionalKindBoundaryInner = class extends import_react4.default.Component {
567
+ var import_jsx_runtime9 = require("react/jsx-runtime");
568
+ var ProvisionalKindBoundaryInner = class extends import_react7.default.Component {
214
569
  state = { failed: false };
215
570
  static getDerivedStateFromError() {
216
571
  return { failed: true };
@@ -234,25 +589,25 @@ var ProvisionalKindBoundaryInner = class extends import_react4.default.Component
234
589
  };
235
590
  function ProvisionalKindBoundary(props) {
236
591
  const host = useContentIrHost();
237
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ProvisionalKindBoundaryInner, { ...props, reportError: host.reportError });
592
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ProvisionalKindBoundaryInner, { ...props, reportError: host.reportError });
238
593
  }
239
594
  function ProvisionalKindFrame({ children }) {
240
595
  const host = useContentIrHost();
241
596
  const label = "Still arriving";
242
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", "aria-busy": "true", children: [
597
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative", "aria-busy": "true", children: [
243
598
  children,
244
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pointer-events-none absolute -top-2 right-4 z-10 select-none rounded-full bg-background px-1.5 leading-4", children: host.renderShimmer?.(label) ?? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px] text-muted-foreground", children: label }) })
599
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "pointer-events-none absolute -top-2 right-4 z-10 select-none rounded-full bg-background px-1.5 leading-4", children: host.renderShimmer?.(label) ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-[10px] text-muted-foreground", children: label }) })
245
600
  ] });
246
601
  }
247
602
 
248
603
  // react/GenericStructuredView.tsx
249
- var import_react5 = require("react");
250
- var import_content_ir4 = require("@ai-matrx/content-ir");
251
- var import_jsx_runtime4 = require("react/jsx-runtime");
604
+ var import_react8 = require("react");
605
+ var import_content_ir8 = require("@ai-matrx/content-ir");
606
+ var import_jsx_runtime10 = require("react/jsx-runtime");
252
607
  function readStructuredValue(content, metadata) {
253
- const envelope = (0, import_content_ir4.readEnvelope)(metadata);
608
+ const envelope = (0, import_content_ir8.readEnvelope)(metadata);
254
609
  if (envelope) {
255
- return { value: (0, import_content_ir4.reconstructRegionValue)(envelope), recovered: true };
610
+ return { value: (0, import_content_ir8.reconstructRegionValue)(envelope), recovered: true };
256
611
  }
257
612
  try {
258
613
  return { value: JSON.parse(content), recovered: true };
@@ -267,25 +622,25 @@ function GenericStructuredView({
267
622
  className
268
623
  }) {
269
624
  const host = useContentIrHost();
270
- const envelope = (0, import_content_ir4.readEnvelope)(metadata);
625
+ const envelope = (0, import_content_ir8.readEnvelope)(metadata);
271
626
  const status = envelope?.root.status ?? "complete";
272
627
  const { value, recovered } = readStructuredValue(content, metadata);
273
- const kind = envelope?.root.kind ?? (typeof value === "object" && value !== null && !Array.isArray(value) ? (0, import_content_ir4.readObjectKind)(value) : null) ?? "";
628
+ const kind = envelope?.root.kind ?? (typeof value === "object" && value !== null && !Array.isArray(value) ? (0, import_content_ir8.readObjectKind)(value) : null) ?? "";
274
629
  const marker = readIrRouteMarker(metadata);
275
630
  const note = marker?.reason === "inactive" ? "a custom view is registered but held inactive" : marker?.reason === "broken-instance" ? "this instance did not match the shape's schema" : marker?.reason === "unregistered" ? "this shape isn't registered on this platform" : "no custom view yet";
276
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: className ? `my-2 min-w-0 ${className}` : "my-2 min-w-0", children: [
277
- status === "streaming" ? streamingIndicator ?? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mb-2 text-xs text-muted-foreground", children: "Still arriving\u2026" }) : null,
631
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: className ? `my-2 min-w-0 ${className}` : "my-2 min-w-0", children: [
632
+ status === "streaming" ? streamingIndicator ?? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mb-2 text-xs text-muted-foreground", children: "Still arriving\u2026" }) : null,
278
633
  recovered ? host.renderValue({ value, ...kind ? { kind } : {}, note }) : (
279
634
  // Zero-data-loss backstop: the region never parsed, so show the source
280
635
  // verbatim rather than swallowing it.
281
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { className: "max-h-96 overflow-auto font-mono text-xs leading-relaxed text-muted-foreground", children: content })
636
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "max-h-96 overflow-auto font-mono text-xs leading-relaxed text-muted-foreground", children: content })
282
637
  )
283
638
  ] });
284
639
  }
285
640
 
286
641
  // react/RuntimeWrapperViews.tsx
287
- var import_content_ir5 = require("@ai-matrx/content-ir");
288
- var import_jsx_runtime5 = require("react/jsx-runtime");
642
+ var import_content_ir9 = require("@ai-matrx/content-ir");
643
+ var import_jsx_runtime11 = require("react/jsx-runtime");
289
644
  function isRecord2(value) {
290
645
  return typeof value === "object" && value !== null && !Array.isArray(value);
291
646
  }
@@ -301,16 +656,16 @@ function DelegatedOutput({
301
656
  }) {
302
657
  const host = useContentIrHost();
303
658
  if (output === null || output === void 0) {
304
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyLabel });
659
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyLabel });
305
660
  }
306
661
  if (!isRecord2(output)) {
307
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: host.renderValue({ value: output }) });
662
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: host.renderValue({ value: output }) });
308
663
  }
309
- const kind = (0, import_content_ir5.readObjectKind)(output) ?? declaredKind;
664
+ const kind = (0, import_content_ir9.readObjectKind)(output) ?? declaredKind;
310
665
  if (!kind) {
311
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: fallback?.(output) ?? host.renderValue({ value: output }) });
666
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: fallback?.(output) ?? host.renderValue({ value: output }) });
312
667
  }
313
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
668
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
314
669
  KindInstanceRender,
315
670
  {
316
671
  kind,
@@ -324,10 +679,10 @@ function DelegatedOutput({
324
679
  function NodeOutcomeView({ serverData, fallback }) {
325
680
  const wrapper = readWrapperFrom(
326
681
  serverData,
327
- import_content_ir5.readNodeOutcomeValue
682
+ import_content_ir9.readNodeOutcomeValue
328
683
  );
329
684
  if (!wrapper) return null;
330
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
685
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
331
686
  DelegatedOutput,
332
687
  {
333
688
  output: wrapper.output,
@@ -339,17 +694,17 @@ function NodeOutcomeView({ serverData, fallback }) {
339
694
  function RunResultView({ serverData, fallback }) {
340
695
  const wrapper = readWrapperFrom(
341
696
  serverData,
342
- import_content_ir5.readRunResultValue
697
+ import_content_ir9.readRunResultValue
343
698
  );
344
699
  if (!wrapper) return null;
345
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "space-y-2", children: wrapper.outputs.length > 0 ? wrapper.outputs.map((outcome) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
700
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-2", children: wrapper.outputs.length > 0 ? wrapper.outputs.map((outcome) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
346
701
  NodeOutcomeView,
347
702
  {
348
703
  serverData: { wrapper: outcome },
349
704
  ...fallback === void 0 ? {} : { fallback }
350
705
  },
351
706
  `${outcome.node_id}:${outcome.attempt}`
352
- )) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
707
+ )) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
353
708
  DelegatedOutput,
354
709
  {
355
710
  output: wrapper.output,