@ai-matrx/content-ir-react 0.16.0 → 0.17.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 +24 -0
- package/dist/{directive-host-C4TcPpxX.d.cts → directive-host-BOML4BQ7.d.cts} +27 -1
- package/dist/{directive-host-C4TcPpxX.d.ts → directive-host-BOML4BQ7.d.ts} +27 -1
- package/dist/directives.cjs +106 -11
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.d.cts +29 -4
- package/dist/directives.d.ts +29 -4
- package/dist/directives.js +106 -11
- package/dist/directives.js.map +1 -1
- package/dist/{host-types-a0XEr5b3.d.cts → host-types-Dxzs0C3f.d.cts} +1 -1
- package/dist/{host-types-CEc86R-v.d.ts → host-types-uKO1zZo3.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 +106 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +106 -11
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +104 -11
- 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 +104 -11
- package/dist/react.js.map +1 -1
- package/dist/{route-De9c5YgW.d.ts → route-CfKxIEdj.d.ts} +27 -1
- package/dist/{route-YcoyR3Fj.d.cts → route-DjGv9skd.d.cts} +27 -1
- package/dist/route.d.cts +1 -1
- package/dist/route.d.ts +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.0 — 2026-10-02
|
|
4
|
+
|
|
5
|
+
- **A failed apply speaks plainly.** The card no longer prints the server's text as its
|
|
6
|
+
sentence (G5 review: "unknown / non-writable noun 'task'. Writable: [...]"). It says what
|
|
7
|
+
failed and what to do — "The task wasn't created. Try again in a moment." / "1 of 2 weren't
|
|
8
|
+
created. Retry to try those again." — and keeps the raw text behind a **Details** toggle
|
|
9
|
+
(`data-apply-failure`, `data-apply-failure-details`). New host seam
|
|
10
|
+
`DirectiveHost.explainFailure(failure) → { what, next } | null` names failures the host
|
|
11
|
+
recognises; `defaultFailureWords` / `failureWords` are exported. Guard:
|
|
12
|
+
`__tests__/directive-failure-words.test.tsx` (3 red on 0.16.1).
|
|
13
|
+
|
|
14
|
+
Consumer action: a host whose `confirm` rejected with a person-ready sentence should map it
|
|
15
|
+
in `explainFailure`; otherwise that sentence now sits behind Details under the default words.
|
|
16
|
+
|
|
17
|
+
## 0.16.1 — 2026-10-02
|
|
18
|
+
|
|
19
|
+
- **A record's title column reads "Title" everywhere.** `itemChanges(item, current,
|
|
20
|
+
{ titleColumn })` labels the noun's title column "Title" (a note's is stored in
|
|
21
|
+
`label`, and the confirm said "Label" while the form said "Title"); the card's update
|
|
22
|
+
row passes `nounTitleColumn`. Guard: `__tests__/directive-card-g3.test.tsx` ("a
|
|
23
|
+
record's title column…", 2 red on 0.16.0).
|
|
24
|
+
|
|
25
|
+
Consumer action: a host's own confirm passes `{ titleColumn }` to `itemChanges`.
|
|
26
|
+
|
|
3
27
|
## 0.16.0 — 2026-10-02
|
|
4
28
|
|
|
5
29
|
The G3 review of the action cards (nightly clone). Guard: `__tests__/directive-card-g3.test.tsx`
|
|
@@ -166,6 +166,32 @@ interface DirectiveHost {
|
|
|
166
166
|
itemKind?: DirectiveItemKindLookup;
|
|
167
167
|
/** Where a decode failure or an unhonourable shell is reported. Default: console.error. */
|
|
168
168
|
reportError?: (message: string) => void;
|
|
169
|
+
/**
|
|
170
|
+
* Plain words for a failed apply the host recognises ("This button can't
|
|
171
|
+
* create a task yet." + "Create it from Tasks instead."). The card never shows
|
|
172
|
+
* the server's raw text as its sentence: it shows these words — or its own
|
|
173
|
+
* verb-aware default — and keeps the raw text behind "Details". Return null
|
|
174
|
+
* to use the default.
|
|
175
|
+
*/
|
|
176
|
+
explainFailure?: (failure: DirectiveFailure) => DirectiveFailureWords | null;
|
|
177
|
+
}
|
|
178
|
+
/** One failed apply, as the card knows it. */
|
|
179
|
+
interface DirectiveFailure {
|
|
180
|
+
/** The server's / host's own text — technical; shown only behind Details. */
|
|
181
|
+
raw: string;
|
|
182
|
+
directiveClass: string;
|
|
183
|
+
noun: string;
|
|
184
|
+
/** The noun's display label ("Task"). */
|
|
185
|
+
nounLabel: string;
|
|
186
|
+
/** Items that failed, when some applied and some did not. */
|
|
187
|
+
failed?: number;
|
|
188
|
+
/** Items in the block. */
|
|
189
|
+
total?: number;
|
|
190
|
+
}
|
|
191
|
+
/** What failed and what to do — each one short sentence. */
|
|
192
|
+
interface DirectiveFailureWords {
|
|
193
|
+
what: string;
|
|
194
|
+
next: string;
|
|
169
195
|
}
|
|
170
196
|
/** Where a directive renders — today, the conversation it sits in (if any). */
|
|
171
197
|
interface DirectiveScope {
|
|
@@ -193,4 +219,4 @@ declare function DirectiveHostProvider({ host, children }: DirectiveHostProvider
|
|
|
193
219
|
*/
|
|
194
220
|
declare function useDirectiveHost(): DirectiveHost;
|
|
195
221
|
|
|
196
|
-
export { type
|
|
222
|
+
export { type DirectiveFailure as D, type DirectiveFailureWords as a, type DirectiveRecordRef as b, type DirectiveApplyResult as c, type DirectiveApplyState as d, type DirectiveAskRequest as e, type DirectiveCopyProps as f, type DirectiveHost as g, DirectiveHostProvider as h, type DirectiveHostProviderProps as i, type DirectiveOpenItemOptions as j, type DirectiveRecordProps as k, type DirectiveScope as l, DirectiveScopeProvider as m, type DirectiveShell as n, useDirectiveScope as o, useDirectiveHost as u };
|
|
@@ -166,6 +166,32 @@ interface DirectiveHost {
|
|
|
166
166
|
itemKind?: DirectiveItemKindLookup;
|
|
167
167
|
/** Where a decode failure or an unhonourable shell is reported. Default: console.error. */
|
|
168
168
|
reportError?: (message: string) => void;
|
|
169
|
+
/**
|
|
170
|
+
* Plain words for a failed apply the host recognises ("This button can't
|
|
171
|
+
* create a task yet." + "Create it from Tasks instead."). The card never shows
|
|
172
|
+
* the server's raw text as its sentence: it shows these words — or its own
|
|
173
|
+
* verb-aware default — and keeps the raw text behind "Details". Return null
|
|
174
|
+
* to use the default.
|
|
175
|
+
*/
|
|
176
|
+
explainFailure?: (failure: DirectiveFailure) => DirectiveFailureWords | null;
|
|
177
|
+
}
|
|
178
|
+
/** One failed apply, as the card knows it. */
|
|
179
|
+
interface DirectiveFailure {
|
|
180
|
+
/** The server's / host's own text — technical; shown only behind Details. */
|
|
181
|
+
raw: string;
|
|
182
|
+
directiveClass: string;
|
|
183
|
+
noun: string;
|
|
184
|
+
/** The noun's display label ("Task"). */
|
|
185
|
+
nounLabel: string;
|
|
186
|
+
/** Items that failed, when some applied and some did not. */
|
|
187
|
+
failed?: number;
|
|
188
|
+
/** Items in the block. */
|
|
189
|
+
total?: number;
|
|
190
|
+
}
|
|
191
|
+
/** What failed and what to do — each one short sentence. */
|
|
192
|
+
interface DirectiveFailureWords {
|
|
193
|
+
what: string;
|
|
194
|
+
next: string;
|
|
169
195
|
}
|
|
170
196
|
/** Where a directive renders — today, the conversation it sits in (if any). */
|
|
171
197
|
interface DirectiveScope {
|
|
@@ -193,4 +219,4 @@ declare function DirectiveHostProvider({ host, children }: DirectiveHostProvider
|
|
|
193
219
|
*/
|
|
194
220
|
declare function useDirectiveHost(): DirectiveHost;
|
|
195
221
|
|
|
196
|
-
export { type
|
|
222
|
+
export { type DirectiveFailure as D, type DirectiveFailureWords as a, type DirectiveRecordRef as b, type DirectiveApplyResult as c, type DirectiveApplyState as d, type DirectiveAskRequest as e, type DirectiveCopyProps as f, type DirectiveHost as g, DirectiveHostProvider as h, type DirectiveHostProviderProps as i, type DirectiveOpenItemOptions as j, type DirectiveRecordProps as k, type DirectiveScope as l, DirectiveScopeProvider as m, type DirectiveShell as n, useDirectiveScope as o, useDirectiveHost as u };
|
package/dist/directives.cjs
CHANGED
|
@@ -31,7 +31,9 @@ __export(directives_exports, {
|
|
|
31
31
|
DirectiveScopeProvider: () => DirectiveScopeProvider,
|
|
32
32
|
SideEffectDirectiveCard: () => SideEffectDirectiveCard,
|
|
33
33
|
TARGETING_CLASSES: () => TARGETING_CLASSES,
|
|
34
|
+
defaultFailureWords: () => defaultFailureWords,
|
|
34
35
|
describeChangeValue: () => describeChangeValue,
|
|
36
|
+
failureWords: () => failureWords,
|
|
35
37
|
fieldLabel: () => fieldLabel,
|
|
36
38
|
getDirectiveRenderer: () => getDirectiveRenderer,
|
|
37
39
|
itemChanges: () => itemChanges,
|
|
@@ -151,11 +153,13 @@ function sameValue(a, b) {
|
|
|
151
153
|
if (typeof a === "object" || typeof b === "object") return safeJson(a) === safeJson(b);
|
|
152
154
|
return false;
|
|
153
155
|
}
|
|
154
|
-
function itemChanges(item, current) {
|
|
156
|
+
function itemChanges(item, current, options = {}) {
|
|
155
157
|
const out = [];
|
|
158
|
+
const titleColumn = options.titleColumn ?? null;
|
|
156
159
|
for (const [key, raw] of Object.entries(item)) {
|
|
157
160
|
if (NOT_A_CHANGE.has(key)) continue;
|
|
158
|
-
const
|
|
161
|
+
const label = key === titleColumn ? "Title" : fieldLabel(key);
|
|
162
|
+
const change = { key, label, ...describeValue(raw) };
|
|
159
163
|
if (current && Object.prototype.hasOwnProperty.call(current, key)) {
|
|
160
164
|
change.before = describeValue(current[key]);
|
|
161
165
|
change.same = sameValue(current[key], raw);
|
|
@@ -165,6 +169,30 @@ function itemChanges(item, current) {
|
|
|
165
169
|
return out;
|
|
166
170
|
}
|
|
167
171
|
|
|
172
|
+
// directives/failure-words.ts
|
|
173
|
+
var PAST = {
|
|
174
|
+
create: "created",
|
|
175
|
+
update: "updated",
|
|
176
|
+
delete: "deleted"
|
|
177
|
+
};
|
|
178
|
+
function defaultFailureWords(failure) {
|
|
179
|
+
const verbed = PAST[failure.directiveClass] ?? "applied";
|
|
180
|
+
const noun = failure.nounLabel.trim().toLowerCase() || "item";
|
|
181
|
+
if (failure.failed && failure.total && failure.total > 1) {
|
|
182
|
+
return {
|
|
183
|
+
what: `${failure.failed} of ${failure.total} weren't ${verbed}.`,
|
|
184
|
+
next: "Retry to try those again."
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
what: `The ${noun} wasn't ${verbed}.`,
|
|
189
|
+
next: "Try again in a moment."
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function failureWords(failure, explain) {
|
|
193
|
+
return explain?.(failure) ?? defaultFailureWords(failure);
|
|
194
|
+
}
|
|
195
|
+
|
|
168
196
|
// directives/icons.tsx
|
|
169
197
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
170
198
|
function Svg({ children, ...props }) {
|
|
@@ -422,10 +450,23 @@ function ApplyDirectiveButton({
|
|
|
422
450
|
children: [
|
|
423
451
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "inline-flex min-w-0 items-start gap-1", children: [
|
|
424
452
|
bad ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AlertIcon, { className: "mt-px h-3.5 w-3.5 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckCircleIcon, { className: "mt-px h-3.5 w-3.5 shrink-0" }),
|
|
425
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
453
|
+
bad ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
454
|
+
FailureNotice,
|
|
455
|
+
{
|
|
456
|
+
words: failureWords(
|
|
457
|
+
{
|
|
458
|
+
raw: state.message ?? `${state.failed} failed`,
|
|
459
|
+
directiveClass: directive.directiveClass,
|
|
460
|
+
noun: directive.noun,
|
|
461
|
+
nounLabel: nounText,
|
|
462
|
+
failed: state.failed,
|
|
463
|
+
total: state.applied + state.failed
|
|
464
|
+
},
|
|
465
|
+
host.explainFailure
|
|
466
|
+
),
|
|
467
|
+
raw: state.message
|
|
468
|
+
}
|
|
469
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "min-w-0", children: state.message ?? `Applied ${state.applied}` })
|
|
429
470
|
] }),
|
|
430
471
|
state.copies > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
431
472
|
"span",
|
|
@@ -502,10 +543,64 @@ function ApplyDirectiveButton({
|
|
|
502
543
|
]
|
|
503
544
|
}
|
|
504
545
|
),
|
|
505
|
-
state.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
546
|
+
state.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
547
|
+
"span",
|
|
548
|
+
{
|
|
549
|
+
className: "inline-flex max-w-sm items-start gap-1 text-xs text-destructive",
|
|
550
|
+
"data-apply-state": "error",
|
|
551
|
+
children: [
|
|
552
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AlertIcon, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
|
|
553
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
554
|
+
FailureNotice,
|
|
555
|
+
{
|
|
556
|
+
words: failureWords(
|
|
557
|
+
{
|
|
558
|
+
raw: state.message,
|
|
559
|
+
directiveClass: directive.directiveClass,
|
|
560
|
+
noun: directive.noun,
|
|
561
|
+
nounLabel: nounText
|
|
562
|
+
},
|
|
563
|
+
host.explainFailure
|
|
564
|
+
),
|
|
565
|
+
raw: state.message
|
|
566
|
+
}
|
|
567
|
+
)
|
|
568
|
+
]
|
|
569
|
+
}
|
|
570
|
+
) : null
|
|
571
|
+
] });
|
|
572
|
+
}
|
|
573
|
+
function FailureNotice({
|
|
574
|
+
words,
|
|
575
|
+
raw
|
|
576
|
+
}) {
|
|
577
|
+
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
578
|
+
const detail = raw?.trim() ?? "";
|
|
579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "flex min-w-0 flex-col gap-0.5", "data-apply-failure": true, children: [
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "min-w-0", children: [
|
|
581
|
+
words.what,
|
|
582
|
+
" ",
|
|
583
|
+
words.next,
|
|
584
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
585
|
+
"button",
|
|
586
|
+
{
|
|
587
|
+
type: "button",
|
|
588
|
+
onClick: () => setOpen((v) => !v),
|
|
589
|
+
"aria-expanded": open,
|
|
590
|
+
className: "ml-1 underline underline-offset-2 hover:no-underline",
|
|
591
|
+
"data-apply-failure-details-toggle": true,
|
|
592
|
+
children: open ? "Hide details" : "Details"
|
|
593
|
+
}
|
|
594
|
+
) : null
|
|
595
|
+
] }),
|
|
596
|
+
open && detail ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
597
|
+
"span",
|
|
598
|
+
{
|
|
599
|
+
className: "block max-w-sm select-text break-words font-mono text-[11px] text-muted-foreground",
|
|
600
|
+
"data-apply-failure-details": true,
|
|
601
|
+
children: detail
|
|
602
|
+
}
|
|
603
|
+
) : null
|
|
509
604
|
] });
|
|
510
605
|
}
|
|
511
606
|
|
|
@@ -652,7 +747,7 @@ function TargetRow({
|
|
|
652
747
|
isUpdate ? host.readRecord : void 0,
|
|
653
748
|
isUpdate ? { noun: directive.noun, id: recordId } : null
|
|
654
749
|
);
|
|
655
|
-
const changes = isUpdate ? itemChanges(item, current.values) : [];
|
|
750
|
+
const changes = isUpdate ? itemChanges(item, current.values, { titleColumn: (0, import_content_ir3.nounTitleColumn)(directive.noun, host.nouns) }) : [];
|
|
656
751
|
const name = host.renderRecord ? host.renderRecord({ noun: directive.noun, id: recordId, fallback, context: "row" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate font-medium text-foreground", children: fallback });
|
|
657
752
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "py-1 text-xs", "data-directive-target": recordId, children: [
|
|
658
753
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|