@ai-matrx/content-ir-react 0.11.10 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/dist/directive-host-Bl-ZgJWp.d.cts +116 -0
- package/dist/directive-host-Bl-ZgJWp.d.ts +116 -0
- package/dist/directives.cjs +219 -25
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.d.cts +64 -3
- package/dist/directives.d.ts +64 -3
- package/dist/directives.js +209 -14
- package/dist/directives.js.map +1 -1
- package/dist/{host-types-C8jR31Wk.d.cts → host-types-BgROpyjE.d.cts} +1 -1
- package/dist/{host-types-IUEDmso7.d.ts → host-types-Cz-1pGHz.d.ts} +1 -1
- package/dist/host.cjs.map +1 -1
- package/dist/host.d.cts +3 -3
- package/dist/host.d.ts +3 -3
- package/dist/host.js.map +1 -1
- package/dist/index.cjs +278 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -4
- package/dist/index.d.ts +65 -4
- package/dist/index.js +256 -61
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +271 -85
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +248 -61
- package/dist/react.js.map +1 -1
- package/dist/{route-B9U-9QCw.d.cts → route-DxK1SoPh.d.cts} +54 -1
- package/dist/{route-gNpJ8zzW.d.ts → route-JGZfl2nL.d.ts} +54 -1
- package/dist/route.d.cts +1 -1
- package/dist/route.d.ts +1 -1
- package/package.json +1 -1
- package/dist/directive-host-DAb7Keg8.d.cts +0 -63
- package/dist/directive-host-DAb7Keg8.d.ts +0 -63
package/dist/react.cjs
CHANGED
|
@@ -115,16 +115,73 @@ function useContentIrKindVersion(kind, sources) {
|
|
|
115
115
|
|
|
116
116
|
// react/KindInstanceRender.tsx
|
|
117
117
|
var import_react6 = require("react");
|
|
118
|
-
var
|
|
118
|
+
var import_content_ir8 = require("@ai-matrx/content-ir");
|
|
119
119
|
|
|
120
120
|
// directives/DirectiveRender.tsx
|
|
121
|
-
var
|
|
121
|
+
var import_content_ir6 = require("@ai-matrx/content-ir");
|
|
122
122
|
|
|
123
123
|
// directives/DirectiveFallbackCard.tsx
|
|
124
|
-
var
|
|
124
|
+
var import_content_ir2 = require("@ai-matrx/content-ir");
|
|
125
125
|
|
|
126
126
|
// directives/ApplyDirectiveButton.tsx
|
|
127
127
|
var import_react4 = require("react");
|
|
128
|
+
var import_content_ir = require("@ai-matrx/content-ir");
|
|
129
|
+
|
|
130
|
+
// directives/item-changes.ts
|
|
131
|
+
var TARGETING_CLASSES = /* @__PURE__ */ new Set(["update", "delete"]);
|
|
132
|
+
var NOT_A_CHANGE = /* @__PURE__ */ new Set(["__kind", "id"]);
|
|
133
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
134
|
+
var CHANGE_VALUE_MAX = 60;
|
|
135
|
+
function itemRecordId(item) {
|
|
136
|
+
const id = item.id;
|
|
137
|
+
if (typeof id === "string" && id.trim()) return id.trim();
|
|
138
|
+
if (typeof id === "number") return String(id);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
function fieldLabel(key) {
|
|
142
|
+
const spaced = key.replace(/_/g, " ").trim();
|
|
143
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
144
|
+
}
|
|
145
|
+
function recordFallbackName(nounLabel3, id) {
|
|
146
|
+
const short = UUID_RE.test(id) ? id.slice(0, 8) : id.length > 12 ? `${id.slice(0, 12)}\u2026` : id;
|
|
147
|
+
return `${nounLabel3} ${short}`;
|
|
148
|
+
}
|
|
149
|
+
function describeValue(value) {
|
|
150
|
+
if (value === null || value === void 0) return { value: "cleared", full: "cleared", clears: true };
|
|
151
|
+
if (typeof value === "string") {
|
|
152
|
+
const trimmed = value.trim();
|
|
153
|
+
if (!trimmed) return { value: "cleared", full: "cleared", clears: true };
|
|
154
|
+
const oneLine = trimmed.replace(/\s+/g, " ");
|
|
155
|
+
const shown = oneLine.length > CHANGE_VALUE_MAX ? `${oneLine.slice(0, CHANGE_VALUE_MAX - 1)}\u2026` : oneLine;
|
|
156
|
+
return { value: shown, full: trimmed, clears: false };
|
|
157
|
+
}
|
|
158
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
159
|
+
return { value: String(value), full: String(value), clears: false };
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(value)) {
|
|
162
|
+
const n2 = value.length;
|
|
163
|
+
const text2 = n2 === 0 ? "cleared" : `${n2} ${n2 === 1 ? "entry" : "entries"}`;
|
|
164
|
+
return { value: text2, full: safeJson(value), clears: n2 === 0 };
|
|
165
|
+
}
|
|
166
|
+
const n = Object.keys(value).length;
|
|
167
|
+
const text = n === 0 ? "cleared" : `${n} ${n === 1 ? "field" : "fields"}`;
|
|
168
|
+
return { value: text, full: safeJson(value), clears: n === 0 };
|
|
169
|
+
}
|
|
170
|
+
function safeJson(value) {
|
|
171
|
+
try {
|
|
172
|
+
return JSON.stringify(value, null, 2);
|
|
173
|
+
} catch {
|
|
174
|
+
return String(value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function itemChanges(item) {
|
|
178
|
+
const out = [];
|
|
179
|
+
for (const [key, raw] of Object.entries(item)) {
|
|
180
|
+
if (NOT_A_CHANGE.has(key)) continue;
|
|
181
|
+
out.push({ key, label: fieldLabel(key), ...describeValue(raw) });
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
128
185
|
|
|
129
186
|
// directives/icons.tsx
|
|
130
187
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -242,10 +299,38 @@ function ApplyDirectiveButton({
|
|
|
242
299
|
const items = directive.items;
|
|
243
300
|
async function handleApply() {
|
|
244
301
|
if (!confirm) return;
|
|
302
|
+
if (host.ask) {
|
|
303
|
+
setState({ status: "asking" });
|
|
304
|
+
let ok = false;
|
|
305
|
+
try {
|
|
306
|
+
ok = await host.ask({
|
|
307
|
+
directive,
|
|
308
|
+
items,
|
|
309
|
+
nounLabel: (0, import_content_ir.nounLabel)(directive.noun, host.nouns)
|
|
310
|
+
});
|
|
311
|
+
} catch (error) {
|
|
312
|
+
setState({
|
|
313
|
+
status: "error",
|
|
314
|
+
message: error instanceof Error && error.message ? error.message : "We could not ask you to confirm this, so nothing was done."
|
|
315
|
+
});
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (!ok) {
|
|
319
|
+
setState({ status: "idle" });
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
setElapsed(0);
|
|
245
324
|
setState({ status: "applying" });
|
|
246
325
|
try {
|
|
247
326
|
const result = await confirm({ __kind: directive.slug, items });
|
|
248
|
-
setState({
|
|
327
|
+
setState({
|
|
328
|
+
status: "applied",
|
|
329
|
+
applied: result.applied,
|
|
330
|
+
failed: result.failed,
|
|
331
|
+
message: result.message?.trim() ? result.message.trim() : null,
|
|
332
|
+
records: result.records ?? []
|
|
333
|
+
});
|
|
249
334
|
onApplied?.();
|
|
250
335
|
} catch (error) {
|
|
251
336
|
setState({
|
|
@@ -256,15 +341,26 @@ function ApplyDirectiveButton({
|
|
|
256
341
|
}
|
|
257
342
|
if (state.status === "applied") {
|
|
258
343
|
const bad = state.failed > 0;
|
|
344
|
+
const trashed = directive.directiveClass === "delete";
|
|
345
|
+
const label2 = (0, import_content_ir.nounLabel)(directive.noun, host.nouns);
|
|
346
|
+
const records = host.renderRecord ? state.records : [];
|
|
259
347
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
260
348
|
"span",
|
|
261
349
|
{
|
|
262
|
-
className: `inline-flex items-center gap-1 text-xs ${bad ? "text-destructive" : "text-primary"}`,
|
|
350
|
+
className: `inline-flex min-w-0 flex-wrap items-center gap-1 text-xs ${bad ? "text-destructive" : "text-primary"}`,
|
|
351
|
+
"data-apply-state": "applied",
|
|
263
352
|
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
|
-
|
|
266
|
-
|
|
267
|
-
|
|
353
|
+
bad ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertIcon, { className: "h-3.5 w-3.5 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
354
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
|
|
355
|
+
state.message ?? `Applied ${state.applied}`,
|
|
356
|
+
bad && !state.message ? ` \xB7 ${state.failed} failed` : ""
|
|
357
|
+
] }),
|
|
358
|
+
records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "inline-flex min-w-0 items-center", children: host.renderRecord?.({
|
|
359
|
+
...record,
|
|
360
|
+
fallback: recordFallbackName(label2, record.id),
|
|
361
|
+
context: "applied",
|
|
362
|
+
trashed
|
|
363
|
+
}) }, `${record.noun}:${record.id}`))
|
|
268
364
|
]
|
|
269
365
|
}
|
|
270
366
|
);
|
|
@@ -275,7 +371,7 @@ function ApplyDirectiveButton({
|
|
|
275
371
|
{
|
|
276
372
|
type: "button",
|
|
277
373
|
onClick: () => void handleApply(),
|
|
278
|
-
disabled: state.status === "applying" || items.length === 0,
|
|
374
|
+
disabled: state.status === "applying" || state.status === "asking" || items.length === 0,
|
|
279
375
|
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
376
|
children: [
|
|
281
377
|
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" }),
|
|
@@ -295,7 +391,7 @@ var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
|
295
391
|
function DirectiveFallbackCard({ directive, reason }) {
|
|
296
392
|
const host = useDirectiveHost();
|
|
297
393
|
const count = directive.items.length;
|
|
298
|
-
const display = (0,
|
|
394
|
+
const display = (0, import_content_ir2.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
|
|
299
395
|
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
396
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(BoxesIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
301
397
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-foreground", children: display.title }),
|
|
@@ -317,8 +413,48 @@ function DirectiveFallbackCard({ directive, reason }) {
|
|
|
317
413
|
] });
|
|
318
414
|
}
|
|
319
415
|
|
|
416
|
+
// directives/DirectiveProvisionalCard.tsx
|
|
417
|
+
var import_content_ir3 = require("@ai-matrx/content-ir");
|
|
418
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
419
|
+
var COMPLETE_SLUG_RE = /^\{\s*"__kind"\s*:\s*"([^"]+)"/;
|
|
420
|
+
function provisionalDirectiveSlug(content) {
|
|
421
|
+
const match = content.trimStart().match(COMPLETE_SLUG_RE);
|
|
422
|
+
return match?.[1] ?? null;
|
|
423
|
+
}
|
|
424
|
+
function DirectiveProvisionalCard({ content, streaming, className }) {
|
|
425
|
+
const host = useDirectiveHost();
|
|
426
|
+
const slug = provisionalDirectiveSlug(content);
|
|
427
|
+
const known = slug ? (0, import_content_ir3.parseDirectiveSlug)(slug) : null;
|
|
428
|
+
const display = known ? (0, import_content_ir3.directiveDisplay)(known.directiveClass, known.noun, host.nouns) : null;
|
|
429
|
+
const Icon = known ? classIcon(known.directiveClass, known.noun) : BoxesIcon;
|
|
430
|
+
const title = display?.title ?? "Structured action";
|
|
431
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
432
|
+
"div",
|
|
433
|
+
{
|
|
434
|
+
className: `my-3 rounded-md border border-border bg-card px-2.5 py-1.5${className ? ` ${className}` : ""}`,
|
|
435
|
+
"data-directive": slug ?? void 0,
|
|
436
|
+
"data-directive-state": streaming ? "streaming" : "incomplete",
|
|
437
|
+
children: [
|
|
438
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
439
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
440
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
441
|
+
display?.family ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-xs text-muted-foreground", children: display.family }) : null,
|
|
442
|
+
streaming ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", role: "status", children: [
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "h-1.5 w-1.5 animate-pulse rounded-full bg-primary", "aria-hidden": true }),
|
|
444
|
+
"Writing\u2026"
|
|
445
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-xs text-destructive", role: "status", children: "Cut off before it finished \u2014 nothing can be applied." })
|
|
446
|
+
] }),
|
|
447
|
+
streaming ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "mt-1 text-xs text-muted-foreground", children: [
|
|
448
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("summary", { className: "cursor-pointer select-none hover:text-foreground", children: "Show what arrived" }),
|
|
449
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { className: "mt-1 max-h-64 overflow-auto whitespace-pre-wrap break-all rounded bg-muted px-2 py-1 text-[11px]", children: content })
|
|
450
|
+
] })
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
|
|
320
456
|
// directives/registry.ts
|
|
321
|
-
var
|
|
457
|
+
var import_content_ir4 = require("@ai-matrx/content-ir");
|
|
322
458
|
var REGISTRY_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.content-ir-react.directive-renderers");
|
|
323
459
|
var registry = globalThis[REGISTRY_SLOT] ??= {
|
|
324
460
|
bySlug: /* @__PURE__ */ new Map(),
|
|
@@ -330,8 +466,8 @@ function getDirectiveRenderer(directive) {
|
|
|
330
466
|
|
|
331
467
|
// directives/SideEffectDirectiveCard.tsx
|
|
332
468
|
var import_react5 = require("react");
|
|
333
|
-
var
|
|
334
|
-
var
|
|
469
|
+
var import_content_ir5 = require("@ai-matrx/content-ir");
|
|
470
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
335
471
|
var ROWS_BEFORE_FOLD = 3;
|
|
336
472
|
function ItemRow({
|
|
337
473
|
directive,
|
|
@@ -340,31 +476,35 @@ function ItemRow({
|
|
|
340
476
|
total
|
|
341
477
|
}) {
|
|
342
478
|
const host = useDirectiveHost();
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
479
|
+
const recordId = TARGETING_CLASSES.has(directive.directiveClass) ? itemRecordId(item) : null;
|
|
480
|
+
if (recordId) {
|
|
481
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TargetRow, { directive, item, recordId });
|
|
482
|
+
}
|
|
483
|
+
const titleColumn = (0, import_content_ir5.nounTitleColumn)(directive.noun, host.nouns);
|
|
484
|
+
const title = (0, import_content_ir5.itemTitle)(item, titleColumn, index, total);
|
|
485
|
+
const subtitle = (0, import_content_ir5.itemSubtitle)(item);
|
|
486
|
+
const facts = (0, import_content_ir5.itemFacts)(item);
|
|
347
487
|
const kind = host.itemKind?.(directive.slug) ?? null;
|
|
348
|
-
const display = (0,
|
|
488
|
+
const display = (0, import_content_ir5.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
|
|
349
489
|
const openItem = host.openItem;
|
|
350
|
-
const body = /* @__PURE__ */ (0,
|
|
351
|
-
/* @__PURE__ */ (0,
|
|
352
|
-
/* @__PURE__ */ (0,
|
|
490
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
491
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "min-w-0 shrink-0 truncate font-medium text-foreground", children: title }),
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.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_runtime7.jsxs)("span", { className: "truncate text-[11px] text-muted-foreground", children: [
|
|
353
493
|
fact.value,
|
|
354
494
|
" ",
|
|
355
495
|
fact.label
|
|
356
496
|
] }, fact.key)) }),
|
|
357
|
-
subtitle && facts.length === 0 ? /* @__PURE__ */ (0,
|
|
358
|
-
openItem ? /* @__PURE__ */ (0,
|
|
497
|
+
subtitle && facts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hidden truncate text-[11px] text-muted-foreground sm:inline", children: subtitle }) : null,
|
|
498
|
+
openItem ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MaximizeIcon, { className: "ml-auto h-3 w-3 shrink-0 text-muted-foreground" }) : null
|
|
359
499
|
] });
|
|
360
|
-
return /* @__PURE__ */ (0,
|
|
361
|
-
openItem ? /* @__PURE__ */ (0,
|
|
500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
|
|
501
|
+
openItem ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
362
502
|
"button",
|
|
363
503
|
{
|
|
364
504
|
type: "button",
|
|
365
505
|
onClick: () => openItem({
|
|
366
506
|
// Stamped so the panel's kind pipeline types it from its own first key.
|
|
367
|
-
item: (0,
|
|
507
|
+
item: (0, import_content_ir5.asKindInstance)(item, kind) ?? item,
|
|
368
508
|
itemKind: kind,
|
|
369
509
|
title,
|
|
370
510
|
subtitle: `${display.title} \xB7 item ${index + 1} of ${total}`,
|
|
@@ -376,46 +516,81 @@ function ItemRow({
|
|
|
376
516
|
title: "Open to read it",
|
|
377
517
|
children: body
|
|
378
518
|
}
|
|
379
|
-
) : /* @__PURE__ */ (0,
|
|
519
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex min-w-0 flex-1 items-center gap-2 px-1 py-0.5", children: body }),
|
|
380
520
|
host.renderCopy?.({ label: title, value: item, kind, size: "xs" })
|
|
381
521
|
] });
|
|
382
522
|
}
|
|
523
|
+
function TargetRow({
|
|
524
|
+
directive,
|
|
525
|
+
item,
|
|
526
|
+
recordId
|
|
527
|
+
}) {
|
|
528
|
+
const host = useDirectiveHost();
|
|
529
|
+
const fallback = recordFallbackName((0, import_content_ir5.nounLabel)(directive.noun, host.nouns), recordId);
|
|
530
|
+
const changes = directive.directiveClass === "update" ? itemChanges(item) : [];
|
|
531
|
+
const name = host.renderRecord ? host.renderRecord({ noun: directive.noun, id: recordId, fallback, context: "row" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate font-medium text-foreground", children: fallback });
|
|
532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "py-1 text-xs", "data-directive-target": recordId, children: [
|
|
533
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
534
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex min-w-0 flex-1 items-center gap-1 px-1", children: name }),
|
|
535
|
+
host.renderCopy?.({ label: fallback, value: item, size: "xs" })
|
|
536
|
+
] }),
|
|
537
|
+
directive.directiveClass === "update" ? changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "px-1 text-[11px] text-muted-foreground", children: "Sets no fields \u2014 nothing would change." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "mt-0.5 space-y-0.5 px-1", children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
538
|
+
"li",
|
|
539
|
+
{
|
|
540
|
+
className: "flex min-w-0 items-baseline gap-1.5 text-[11px]",
|
|
541
|
+
title: `${change.label} \u2192 ${change.full}`,
|
|
542
|
+
children: [
|
|
543
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "shrink-0 text-muted-foreground", children: change.label }),
|
|
544
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": true, className: "shrink-0 text-muted-foreground", children: "\u2192" }),
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
546
|
+
"span",
|
|
547
|
+
{
|
|
548
|
+
className: `min-w-0 truncate ${change.clears ? "italic text-muted-foreground" : "text-foreground"}`,
|
|
549
|
+
children: change.value
|
|
550
|
+
}
|
|
551
|
+
)
|
|
552
|
+
]
|
|
553
|
+
},
|
|
554
|
+
change.key
|
|
555
|
+
)) }) : null
|
|
556
|
+
] });
|
|
557
|
+
}
|
|
383
558
|
function SideEffectDirectiveCard({ directive }) {
|
|
384
559
|
const host = useDirectiveHost();
|
|
385
560
|
const [expanded, setExpanded] = (0, import_react5.useState)(false);
|
|
386
561
|
const items = directive.items;
|
|
387
562
|
const total = items.length;
|
|
388
|
-
const display = (0,
|
|
563
|
+
const display = (0, import_content_ir5.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
|
|
389
564
|
const Icon = classIcon(directive.directiveClass, directive.noun);
|
|
390
565
|
const shown = expanded ? items : items.slice(0, ROWS_BEFORE_FOLD);
|
|
391
566
|
const hidden = total - shown.length;
|
|
392
|
-
return /* @__PURE__ */ (0,
|
|
393
|
-
/* @__PURE__ */ (0,
|
|
394
|
-
/* @__PURE__ */ (0,
|
|
395
|
-
/* @__PURE__ */ (0,
|
|
396
|
-
display.family ? /* @__PURE__ */ (0,
|
|
397
|
-
/* @__PURE__ */ (0,
|
|
567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "my-3 rounded-md border border-border bg-card px-2.5 py-1.5", "data-directive": directive.slug, children: [
|
|
568
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
569
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
570
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm font-medium text-foreground", children: display.title }),
|
|
571
|
+
display.family ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-xs text-muted-foreground", children: display.family }) : null,
|
|
572
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-xs tabular-nums text-muted-foreground", children: [
|
|
398
573
|
total,
|
|
399
574
|
" ",
|
|
400
575
|
total === 1 ? "item" : "items"
|
|
401
576
|
] }),
|
|
402
|
-
/* @__PURE__ */ (0,
|
|
577
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
403
578
|
host.renderCopy?.({ label: display.title, value: directive.shell, size: "icon" }),
|
|
404
|
-
/* @__PURE__ */ (0,
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ApplyDirectiveButton, { directive, itemCount: total })
|
|
405
580
|
] })
|
|
406
581
|
] }),
|
|
407
582
|
total === 0 ? (
|
|
408
583
|
// Stated, never silent: an empty batch is a real (and suspicious) state.
|
|
409
|
-
/* @__PURE__ */ (0,
|
|
410
|
-
) : /* @__PURE__ */ (0,
|
|
411
|
-
hidden > 0 || expanded ? /* @__PURE__ */ (0,
|
|
584
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-1 text-xs text-muted-foreground", children: "No items \u2014 nothing would be written." })
|
|
585
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-0.5 divide-y divide-border/60", children: shown.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ItemRow, { directive, item, index: i, total }, i)) }),
|
|
586
|
+
hidden > 0 || expanded ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
412
587
|
"button",
|
|
413
588
|
{
|
|
414
589
|
type: "button",
|
|
415
590
|
onClick: () => setExpanded((v) => !v),
|
|
416
591
|
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
592
|
children: [
|
|
418
|
-
expanded ? /* @__PURE__ */ (0,
|
|
593
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronDownIcon, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronRightIcon, { className: "h-3 w-3" }),
|
|
419
594
|
expanded ? "Show less" : `Show ${hidden} more`
|
|
420
595
|
]
|
|
421
596
|
}
|
|
@@ -424,17 +599,28 @@ function SideEffectDirectiveCard({ directive }) {
|
|
|
424
599
|
}
|
|
425
600
|
|
|
426
601
|
// directives/DirectiveRender.tsx
|
|
427
|
-
var
|
|
428
|
-
function
|
|
602
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
603
|
+
function isWholeJson(content) {
|
|
604
|
+
try {
|
|
605
|
+
JSON.parse(content);
|
|
606
|
+
return true;
|
|
607
|
+
} catch {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
function DirectiveRender({ content, className, streaming }) {
|
|
429
612
|
const host = useDirectiveHost();
|
|
430
|
-
const directive = (0,
|
|
613
|
+
const directive = (0, import_content_ir6.tryDecodeDirectiveContent)(content, (message) => {
|
|
431
614
|
const line = `[kind-directives] ${message}`;
|
|
432
615
|
if (host.reportError) host.reportError(line);
|
|
433
616
|
else console.error(line);
|
|
434
617
|
});
|
|
435
618
|
if (!directive) {
|
|
619
|
+
if (typeof content === "string" && (0, import_content_ir6.looksLikeDirectiveHead)(content) && !isWholeJson(content)) {
|
|
620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DirectiveProvisionalCard, { content, streaming: streaming !== false, className });
|
|
621
|
+
}
|
|
436
622
|
const raw = typeof content === "string" ? content : JSON.stringify(content, null, 2);
|
|
437
|
-
return /* @__PURE__ */ (0,
|
|
623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
438
624
|
"pre",
|
|
439
625
|
{
|
|
440
626
|
className: `my-3 overflow-x-auto rounded-md border border-border bg-muted px-3 py-2 text-xs text-muted-foreground${className ? ` ${className}` : ""}`,
|
|
@@ -443,13 +629,13 @@ function DirectiveRender({ content, className }) {
|
|
|
443
629
|
);
|
|
444
630
|
}
|
|
445
631
|
const Renderer = getDirectiveRenderer(directive);
|
|
446
|
-
if (Renderer) return /* @__PURE__ */ (0,
|
|
447
|
-
if (directive.parsed.executes) return /* @__PURE__ */ (0,
|
|
448
|
-
return /* @__PURE__ */ (0,
|
|
632
|
+
if (Renderer) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Renderer, { directive });
|
|
633
|
+
if (directive.parsed.executes) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SideEffectDirectiveCard, { directive });
|
|
634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DirectiveFallbackCard, { directive });
|
|
449
635
|
}
|
|
450
636
|
|
|
451
637
|
// route/kind-route.ts
|
|
452
|
-
var
|
|
638
|
+
var import_content_ir7 = require("@ai-matrx/content-ir");
|
|
453
639
|
var IR_ROUTE_KEY = "__ir_route";
|
|
454
640
|
var GENERIC_STRUCTURED_COMPONENT_KEY = "generic_structured";
|
|
455
641
|
var SOURCELESS_DB_ROW_SLOT = /* @__PURE__ */ Symbol.for(
|
|
@@ -468,20 +654,20 @@ function readIrRouteMarker(metadata) {
|
|
|
468
654
|
}
|
|
469
655
|
|
|
470
656
|
// react/KindInstanceRender.tsx
|
|
471
|
-
var
|
|
657
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
472
658
|
function isRecordValue(value) {
|
|
473
659
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
474
660
|
}
|
|
475
661
|
function kindIsRoutable(kind, host) {
|
|
476
|
-
if ((0,
|
|
662
|
+
if ((0, import_content_ir8.isReservedDirectiveSlug)(kind)) return true;
|
|
477
663
|
if (host.kinds.getDefinition(kind)?.legacyBlockType) return true;
|
|
478
664
|
const resolution = host.components.resolve(kind, host.platform, "output");
|
|
479
665
|
if (!resolution?.isActive) return false;
|
|
480
666
|
return resolution.componentKey !== GENERIC_STRUCTURED_COMPONENT_KEY;
|
|
481
667
|
}
|
|
482
668
|
function KindInstanceRender(props) {
|
|
483
|
-
if ((0,
|
|
484
|
-
return /* @__PURE__ */ (0,
|
|
669
|
+
if ((0, import_content_ir8.isReservedDirectiveSlug)(props.kind)) {
|
|
670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
485
671
|
DirectiveRender,
|
|
486
672
|
{
|
|
487
673
|
content: props.value,
|
|
@@ -489,7 +675,7 @@ function KindInstanceRender(props) {
|
|
|
489
675
|
}
|
|
490
676
|
);
|
|
491
677
|
}
|
|
492
|
-
return /* @__PURE__ */ (0,
|
|
678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(KindInstanceRenderInner, { ...props });
|
|
493
679
|
}
|
|
494
680
|
function KindInstanceRenderInner({
|
|
495
681
|
kind,
|
|
@@ -535,18 +721,18 @@ function KindInstanceRenderInner({
|
|
|
535
721
|
content: JSON.stringify(value, null, 2),
|
|
536
722
|
language: "json",
|
|
537
723
|
metadata: {
|
|
538
|
-
[
|
|
724
|
+
[import_content_ir8.IR_ENVELOPE_KEY]: (0, import_content_ir8.envelopeFromCompleteValue)(value, kind)
|
|
539
725
|
}
|
|
540
726
|
} : null;
|
|
541
727
|
const frameClass = variant === "bare" ? void 0 : "rounded-md border border-border bg-card p-3";
|
|
542
728
|
if (routingStatus === "unroutable" && unroutableFallback !== void 0) {
|
|
543
|
-
return /* @__PURE__ */ (0,
|
|
729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: unroutableFallback });
|
|
544
730
|
}
|
|
545
731
|
const onTheFloor = block === null || routingStatus === "unroutable";
|
|
546
732
|
const notice = "This shape has no custom component yet, so it renders through the universal viewer \u2014 exactly what production shows today.";
|
|
547
|
-
return /* @__PURE__ */ (0,
|
|
548
|
-
showRoutingNote && routingStatus === "unroutable" ? host.renderNotice?.(notice) ?? /* @__PURE__ */ (0,
|
|
549
|
-
/* @__PURE__ */ (0,
|
|
733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: className ? `space-y-3 ${className}` : "space-y-3", children: [
|
|
734
|
+
showRoutingNote && routingStatus === "unroutable" ? host.renderNotice?.(notice) ?? /* @__PURE__ */ (0, import_jsx_runtime9.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,
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: frameClass, children: onTheFloor ? host.renderValue({ value, kind }) : host.renderBlock(block) })
|
|
550
736
|
] });
|
|
551
737
|
}
|
|
552
738
|
|
|
@@ -554,7 +740,7 @@ function KindInstanceRenderInner({
|
|
|
554
740
|
var import_react7 = __toESM(require("react"), 1);
|
|
555
741
|
|
|
556
742
|
// route/partial-kind-route.ts
|
|
557
|
-
var
|
|
743
|
+
var import_content_ir9 = require("@ai-matrx/content-ir");
|
|
558
744
|
var PARTIAL_UNSAFE_SLOT = /* @__PURE__ */ Symbol.for(
|
|
559
745
|
"ai-matrx.content-ir-react.partial-unsafe-kinds"
|
|
560
746
|
);
|
|
@@ -564,7 +750,7 @@ function markKindPartialUnsafe(kind) {
|
|
|
564
750
|
}
|
|
565
751
|
|
|
566
752
|
// react/ProvisionalKindBoundary.tsx
|
|
567
|
-
var
|
|
753
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
568
754
|
var ProvisionalKindBoundaryInner = class extends import_react7.default.Component {
|
|
569
755
|
state = { failed: false };
|
|
570
756
|
static getDerivedStateFromError() {
|
|
@@ -589,25 +775,25 @@ var ProvisionalKindBoundaryInner = class extends import_react7.default.Component
|
|
|
589
775
|
};
|
|
590
776
|
function ProvisionalKindBoundary(props) {
|
|
591
777
|
const host = useContentIrHost();
|
|
592
|
-
return /* @__PURE__ */ (0,
|
|
778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ProvisionalKindBoundaryInner, { ...props, reportError: host.reportError });
|
|
593
779
|
}
|
|
594
780
|
function ProvisionalKindFrame({ children }) {
|
|
595
781
|
const host = useContentIrHost();
|
|
596
782
|
const label = "Still arriving";
|
|
597
|
-
return /* @__PURE__ */ (0,
|
|
783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative", "aria-busy": "true", children: [
|
|
598
784
|
children,
|
|
599
|
-
/* @__PURE__ */ (0,
|
|
785
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.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_runtime10.jsx)("span", { className: "text-[10px] text-muted-foreground", children: label }) })
|
|
600
786
|
] });
|
|
601
787
|
}
|
|
602
788
|
|
|
603
789
|
// react/GenericStructuredView.tsx
|
|
604
790
|
var import_react8 = require("react");
|
|
605
|
-
var
|
|
606
|
-
var
|
|
791
|
+
var import_content_ir10 = require("@ai-matrx/content-ir");
|
|
792
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
607
793
|
function readStructuredValue(content, metadata) {
|
|
608
|
-
const envelope = (0,
|
|
794
|
+
const envelope = (0, import_content_ir10.readEnvelope)(metadata);
|
|
609
795
|
if (envelope) {
|
|
610
|
-
return { value: (0,
|
|
796
|
+
return { value: (0, import_content_ir10.reconstructRegionValue)(envelope), recovered: true };
|
|
611
797
|
}
|
|
612
798
|
try {
|
|
613
799
|
return { value: JSON.parse(content), recovered: true };
|
|
@@ -622,25 +808,25 @@ function GenericStructuredView({
|
|
|
622
808
|
className
|
|
623
809
|
}) {
|
|
624
810
|
const host = useContentIrHost();
|
|
625
|
-
const envelope = (0,
|
|
811
|
+
const envelope = (0, import_content_ir10.readEnvelope)(metadata);
|
|
626
812
|
const status = envelope?.root.status ?? "complete";
|
|
627
813
|
const { value, recovered } = readStructuredValue(content, metadata);
|
|
628
|
-
const kind = envelope?.root.kind ?? (typeof value === "object" && value !== null && !Array.isArray(value) ? (0,
|
|
814
|
+
const kind = envelope?.root.kind ?? (typeof value === "object" && value !== null && !Array.isArray(value) ? (0, import_content_ir10.readObjectKind)(value) : null) ?? "";
|
|
629
815
|
const marker = readIrRouteMarker(metadata);
|
|
630
816
|
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";
|
|
631
|
-
return /* @__PURE__ */ (0,
|
|
632
|
-
status === "streaming" ? streamingIndicator ?? /* @__PURE__ */ (0,
|
|
817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: className ? `my-2 min-w-0 ${className}` : "my-2 min-w-0", children: [
|
|
818
|
+
status === "streaming" ? streamingIndicator ?? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-2 text-xs text-muted-foreground", children: "Still arriving\u2026" }) : null,
|
|
633
819
|
recovered ? host.renderValue({ value, ...kind ? { kind } : {}, note }) : (
|
|
634
820
|
// Zero-data-loss backstop: the region never parsed, so show the source
|
|
635
821
|
// verbatim rather than swallowing it.
|
|
636
|
-
/* @__PURE__ */ (0,
|
|
822
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("pre", { className: "max-h-96 overflow-auto font-mono text-xs leading-relaxed text-muted-foreground", children: content })
|
|
637
823
|
)
|
|
638
824
|
] });
|
|
639
825
|
}
|
|
640
826
|
|
|
641
827
|
// react/RuntimeWrapperViews.tsx
|
|
642
|
-
var
|
|
643
|
-
var
|
|
828
|
+
var import_content_ir11 = require("@ai-matrx/content-ir");
|
|
829
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
644
830
|
function isRecord2(value) {
|
|
645
831
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
646
832
|
}
|
|
@@ -656,16 +842,16 @@ function DelegatedOutput({
|
|
|
656
842
|
}) {
|
|
657
843
|
const host = useContentIrHost();
|
|
658
844
|
if (output === null || output === void 0) {
|
|
659
|
-
return /* @__PURE__ */ (0,
|
|
845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyLabel });
|
|
660
846
|
}
|
|
661
847
|
if (!isRecord2(output)) {
|
|
662
|
-
return /* @__PURE__ */ (0,
|
|
848
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: host.renderValue({ value: output }) });
|
|
663
849
|
}
|
|
664
|
-
const kind = (0,
|
|
850
|
+
const kind = (0, import_content_ir11.readObjectKind)(output) ?? declaredKind;
|
|
665
851
|
if (!kind) {
|
|
666
|
-
return /* @__PURE__ */ (0,
|
|
852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: fallback?.(output) ?? host.renderValue({ value: output }) });
|
|
667
853
|
}
|
|
668
|
-
return /* @__PURE__ */ (0,
|
|
854
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
669
855
|
KindInstanceRender,
|
|
670
856
|
{
|
|
671
857
|
kind,
|
|
@@ -679,10 +865,10 @@ function DelegatedOutput({
|
|
|
679
865
|
function NodeOutcomeView({ serverData, fallback }) {
|
|
680
866
|
const wrapper = readWrapperFrom(
|
|
681
867
|
serverData,
|
|
682
|
-
|
|
868
|
+
import_content_ir11.readNodeOutcomeValue
|
|
683
869
|
);
|
|
684
870
|
if (!wrapper) return null;
|
|
685
|
-
return /* @__PURE__ */ (0,
|
|
871
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
686
872
|
DelegatedOutput,
|
|
687
873
|
{
|
|
688
874
|
output: wrapper.output,
|
|
@@ -694,17 +880,17 @@ function NodeOutcomeView({ serverData, fallback }) {
|
|
|
694
880
|
function RunResultView({ serverData, fallback }) {
|
|
695
881
|
const wrapper = readWrapperFrom(
|
|
696
882
|
serverData,
|
|
697
|
-
|
|
883
|
+
import_content_ir11.readRunResultValue
|
|
698
884
|
);
|
|
699
885
|
if (!wrapper) return null;
|
|
700
|
-
return /* @__PURE__ */ (0,
|
|
886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-2", children: wrapper.outputs.length > 0 ? wrapper.outputs.map((outcome) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
701
887
|
NodeOutcomeView,
|
|
702
888
|
{
|
|
703
889
|
serverData: { wrapper: outcome },
|
|
704
890
|
...fallback === void 0 ? {} : { fallback }
|
|
705
891
|
},
|
|
706
892
|
`${outcome.node_id}:${outcome.attempt}`
|
|
707
|
-
)) : /* @__PURE__ */ (0,
|
|
893
|
+
)) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
708
894
|
DelegatedOutput,
|
|
709
895
|
{
|
|
710
896
|
output: wrapper.output,
|