@ai-matrx/content-ir-react 0.17.1 → 0.18.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 +22 -0
- package/dist/{directive-host-BOML4BQ7.d.cts → directive-host-Bw2_PrgL.d.cts} +14 -0
- package/dist/{directive-host-BOML4BQ7.d.ts → directive-host-Bw2_PrgL.d.ts} +14 -0
- package/dist/directives.cjs +56 -17
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.d.cts +33 -5
- package/dist/directives.d.ts +33 -5
- package/dist/directives.js +56 -17
- package/dist/directives.js.map +1 -1
- package/dist/{host-types-CKu4ap5K.d.cts → host-types-YP_l_Q_t.d.cts} +1 -1
- package/dist/{host-types-CQ2oIzUy.d.ts → host-types-eSjFmXyF.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 +56 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -5
- package/dist/index.d.ts +33 -5
- package/dist/index.js +56 -17
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +55 -17
- 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 +55 -17
- package/dist/react.js.map +1 -1
- package/dist/{route-D0f5H63n.d.ts → route-CtYw2cTN.d.ts} +14 -0
- package/dist/{route-D2Yz3El4.d.cts → route-KoRMp3Qn.d.cts} +14 -0
- package/dist/route.d.cts +1 -1
- package/dist/route.d.ts +1 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -331,17 +331,22 @@ function classIcon(directiveClass, noun) {
|
|
|
331
331
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
332
332
|
var FINISH_POLL_MS = 2e3;
|
|
333
333
|
var FINISH_POLLS_MAX = 30;
|
|
334
|
+
function readsApplyLedger(host, directive) {
|
|
335
|
+
return !!host.applyState && !!host.confirm && directive.parsed.executes && directive.items.length > 0;
|
|
336
|
+
}
|
|
334
337
|
function ApplyDirectiveButton({
|
|
335
338
|
directive,
|
|
336
339
|
label = "Apply",
|
|
337
340
|
itemCount,
|
|
338
|
-
onApplied
|
|
341
|
+
onApplied,
|
|
342
|
+
onPhase,
|
|
343
|
+
nothingToChange = false
|
|
339
344
|
}) {
|
|
340
345
|
const host = useDirectiveHost();
|
|
341
346
|
const scope = useDirectiveScope();
|
|
342
347
|
const conversationId = scope.conversationId || void 0;
|
|
343
348
|
const items = directive.items;
|
|
344
|
-
const readsLedger =
|
|
349
|
+
const readsLedger = readsApplyLedger(host, directive);
|
|
345
350
|
const initial = readsLedger ? { status: "checking" } : { status: "idle" };
|
|
346
351
|
const [state, setState] = (0, import_react4.useState)(initial);
|
|
347
352
|
const [elapsed, setElapsed] = (0, import_react4.useState)(0);
|
|
@@ -382,7 +387,8 @@ function ApplyDirectiveButton({
|
|
|
382
387
|
failed: 0,
|
|
383
388
|
message: answer.message?.trim() ? answer.message.trim() : null,
|
|
384
389
|
records: answer.records ?? [],
|
|
385
|
-
copies: Math.max(1, answer.copies ?? 1)
|
|
390
|
+
copies: Math.max(1, answer.copies ?? 1),
|
|
391
|
+
before: answer.before ?? null
|
|
386
392
|
} : prev
|
|
387
393
|
);
|
|
388
394
|
} else if (answer.state === "in_flight" && polls < FINISH_POLLS_MAX) {
|
|
@@ -407,6 +413,15 @@ function ApplyDirectiveButton({
|
|
|
407
413
|
if (timer) clearTimeout(timer);
|
|
408
414
|
};
|
|
409
415
|
}, [shellKey, read, report]);
|
|
416
|
+
const appliedClean = state.status === "applied" && state.failed === 0 ? state : null;
|
|
417
|
+
const appliedBefore = appliedClean ? appliedClean.before : null;
|
|
418
|
+
const phaseKey = state.status === "checking" || state.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
|
|
419
|
+
(0, import_react4.useEffect)(() => {
|
|
420
|
+
if (!onPhase) return;
|
|
421
|
+
if (phaseKey === "pending") onPhase({ phase: "pending" });
|
|
422
|
+
else if (phaseKey === "open") onPhase({ phase: "open" });
|
|
423
|
+
else onPhase({ phase: "applied", before: appliedBefore });
|
|
424
|
+
}, [phaseKey, onPhase, appliedBefore]);
|
|
410
425
|
(0, import_react4.useEffect)(() => {
|
|
411
426
|
if (state.status !== "applying") return;
|
|
412
427
|
startedAt.current = Date.now();
|
|
@@ -421,7 +436,7 @@ function ApplyDirectiveButton({
|
|
|
421
436
|
if (!confirm) return null;
|
|
422
437
|
async function handleApply(again = false) {
|
|
423
438
|
if (!confirm) return;
|
|
424
|
-
const
|
|
439
|
+
const prior = state;
|
|
425
440
|
const askedFor = identity;
|
|
426
441
|
const stillHere = () => currentIdentity.current === askedFor;
|
|
427
442
|
const priorCopies = state.status === "applied" ? state.copies : 0;
|
|
@@ -448,7 +463,7 @@ function ApplyDirectiveButton({
|
|
|
448
463
|
if (!stillHere()) return;
|
|
449
464
|
setAskingAgain(false);
|
|
450
465
|
if (!ok) {
|
|
451
|
-
setState(again ?
|
|
466
|
+
setState(again ? prior : { status: "idle" });
|
|
452
467
|
return;
|
|
453
468
|
}
|
|
454
469
|
}
|
|
@@ -467,7 +482,10 @@ function ApplyDirectiveButton({
|
|
|
467
482
|
message: result.message?.trim() ? result.message.trim() : null,
|
|
468
483
|
records: result.records ?? [],
|
|
469
484
|
// "Run again" made one more; a first apply (or a replay of one) is one.
|
|
470
|
-
copies: again ? Math.max(1, priorCopies) + 1 : Math.max(1, priorCopies)
|
|
485
|
+
copies: again ? Math.max(1, priorCopies) + 1 : Math.max(1, priorCopies),
|
|
486
|
+
// "Run again" wrote the same values over themselves; what the FIRST
|
|
487
|
+
// apply replaced is still the change this block made.
|
|
488
|
+
before: again && prior.status === "applied" && prior.before ? prior.before : result.before ?? null
|
|
471
489
|
});
|
|
472
490
|
onApplied?.();
|
|
473
491
|
} catch (error) {
|
|
@@ -569,15 +587,18 @@ function ApplyDirectiveButton({
|
|
|
569
587
|
);
|
|
570
588
|
}
|
|
571
589
|
const destructive = directive.directiveClass === "delete";
|
|
590
|
+
const muted = nothingToChange && state.status === "idle";
|
|
572
591
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
|
|
592
|
+
muted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-xs text-muted-foreground", "data-apply-nothing": "", children: "Nothing to change" }) : null,
|
|
573
593
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
574
594
|
"button",
|
|
575
595
|
{
|
|
576
596
|
type: "button",
|
|
577
597
|
onClick: () => void handleApply(),
|
|
578
598
|
disabled: state.status === "applying" || state.status === "asking" || items.length === 0,
|
|
579
|
-
"data-apply-tone": destructive ? "destructive" : "default",
|
|
580
|
-
|
|
599
|
+
"data-apply-tone": muted ? "muted" : destructive ? "destructive" : "default",
|
|
600
|
+
title: muted ? "It sets no fields, so applying it changes nothing." : void 0,
|
|
601
|
+
className: `inline-flex items-center gap-1 rounded-md border px-2 py-1 text-xs font-medium disabled:opacity-50 ${muted ? "border-border/60 bg-background text-muted-foreground hover:bg-accent" : destructive ? "border-destructive/50 bg-background text-destructive hover:bg-destructive/10" : "border-border bg-background hover:bg-accent"}`,
|
|
581
602
|
children: [
|
|
582
603
|
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" }),
|
|
583
604
|
state.status === "applying" ? `Applying${itemCount ? ` ${itemCount} ${itemCount === 1 ? "item" : "items"}` : ""}\u2026${elapsed ? ` ${elapsed}s` : ""}` : label
|
|
@@ -765,12 +786,13 @@ function ItemRow({
|
|
|
765
786
|
directive,
|
|
766
787
|
item,
|
|
767
788
|
index,
|
|
768
|
-
total
|
|
789
|
+
total,
|
|
790
|
+
phase
|
|
769
791
|
}) {
|
|
770
792
|
const host = useDirectiveHost();
|
|
771
793
|
const recordId = TARGETING_CLASSES.has(directive.directiveClass) ? itemRecordId(item) : null;
|
|
772
794
|
if (recordId) {
|
|
773
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TargetRow, { directive, item, recordId });
|
|
795
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TargetRow, { directive, item, recordId, index, phase });
|
|
774
796
|
}
|
|
775
797
|
const titleColumn = (0, import_content_ir5.nounTitleColumn)(directive.noun, host.nouns);
|
|
776
798
|
const title = (0, import_content_ir5.itemTitle)(item, titleColumn, index, total);
|
|
@@ -857,16 +879,20 @@ function DirectiveChangeList({
|
|
|
857
879
|
function TargetRow({
|
|
858
880
|
directive,
|
|
859
881
|
item,
|
|
860
|
-
recordId
|
|
882
|
+
recordId,
|
|
883
|
+
index,
|
|
884
|
+
phase
|
|
861
885
|
}) {
|
|
862
886
|
const host = useDirectiveHost();
|
|
863
887
|
const fallback = recordFallbackName((0, import_content_ir5.nounLabel)(directive.noun, host.nouns), recordId);
|
|
864
888
|
const isUpdate = directive.directiveClass === "update";
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
889
|
+
const readsLive = isUpdate && phase.phase === "open";
|
|
890
|
+
const live = useRecordValues(
|
|
891
|
+
readsLive ? host.readRecord : void 0,
|
|
892
|
+
readsLive ? { noun: directive.noun, id: recordId } : null
|
|
868
893
|
);
|
|
869
|
-
const
|
|
894
|
+
const compareTo = phase.phase === "applied" ? phase.before?.[index] ?? null : readsLive ? live.values : null;
|
|
895
|
+
const changes = isUpdate ? itemChanges(item, compareTo, { titleColumn: (0, import_content_ir5.nounTitleColumn)(directive.noun, host.nouns) }) : [];
|
|
870
896
|
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 });
|
|
871
897
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "py-1 text-xs", "data-directive-target": recordId, children: [
|
|
872
898
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
@@ -883,6 +909,10 @@ function SideEffectDirectiveCard({ directive }) {
|
|
|
883
909
|
const total = items.length;
|
|
884
910
|
const display = (0, import_content_ir5.directiveDisplay)(directive.directiveClass, directive.noun, host.nouns);
|
|
885
911
|
const Icon = classIcon(directive.directiveClass, directive.noun);
|
|
912
|
+
const [phase, setPhase] = (0, import_react6.useState)(
|
|
913
|
+
() => readsApplyLedger(host, directive) ? { phase: "pending" } : { phase: "open" }
|
|
914
|
+
);
|
|
915
|
+
const nothingToChange = directive.directiveClass === "update" && total > 0 && items.every((item) => itemChanges(item).length === 0);
|
|
886
916
|
const shown = expanded ? items : items.slice(0, ROWS_BEFORE_FOLD);
|
|
887
917
|
const hidden = total - shown.length;
|
|
888
918
|
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: [
|
|
@@ -897,13 +927,21 @@ function SideEffectDirectiveCard({ directive }) {
|
|
|
897
927
|
] }),
|
|
898
928
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
899
929
|
host.renderCopy?.({ label: display.title, value: directive.shell, size: "icon" }),
|
|
900
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
931
|
+
ApplyDirectiveButton,
|
|
932
|
+
{
|
|
933
|
+
directive,
|
|
934
|
+
itemCount: total,
|
|
935
|
+
onPhase: setPhase,
|
|
936
|
+
nothingToChange
|
|
937
|
+
}
|
|
938
|
+
)
|
|
901
939
|
] })
|
|
902
940
|
] }),
|
|
903
941
|
total === 0 ? (
|
|
904
942
|
// Stated, never silent: an empty batch is a real (and suspicious) state.
|
|
905
943
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-1 text-xs text-muted-foreground", children: "No items \u2014 nothing would be written." })
|
|
906
|
-
) : /* @__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)) }),
|
|
944
|
+
) : /* @__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, phase }, i)) }),
|
|
907
945
|
hidden > 0 || expanded ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
908
946
|
"button",
|
|
909
947
|
{
|