@nivaro/react 0.3.35 → 0.3.37

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 (106) hide show
  1. package/dist/components/slots/CommentsSlot.js +44 -36
  2. package/dist/full.css +1 -1
  3. package/dist/hooks/useSessionRecorder.js +1 -1
  4. package/dist/index.d.ts +13 -4
  5. package/dist/shared/components/AgentBadge.js +26 -0
  6. package/dist/shared/components/AgentQuestionsCard.js +198 -0
  7. package/dist/shared/components/ItemEditForm.js +3329 -3263
  8. package/dist/shared/components/McpConnectionScope.js +480 -0
  9. package/dist/shared/components/MyWorkView.js +223 -208
  10. package/dist/shared/components/RecordReadView.js +620 -572
  11. package/dist/shared/components/chat/ChatPanel.js +683 -671
  12. package/dist/shared/components/imports/DownloadSampleButton.js +69 -0
  13. package/dist/shared/components/imports/ImportConsole.js +106 -104
  14. package/dist/shared/components/imports/RunDetailSheet.js +11 -10
  15. package/dist/shared/components/item-edit/FieldAffordances.js +32 -32
  16. package/dist/shared/components/item-edit/FormTour.js +279 -0
  17. package/dist/shared/components/item-edit/GroupSection.js +377 -360
  18. package/dist/shared/components/item-edit/PersonalDefaultControl.js +80 -63
  19. package/dist/shared/components/item-edit/entry/EntryStrip.js +30 -26
  20. package/dist/shared/components/item-edit/form-density.js +36 -0
  21. package/dist/shared/components/item-edit/useFormUsageBeacon.js +59 -46
  22. package/dist/shared/components/item-edit/usePersonalDefaults.js +312 -296
  23. package/dist/shared/components/layout-editor/AddPanel.js +349 -192
  24. package/dist/shared/components/layout-editor/DesignNode.js +146 -131
  25. package/dist/shared/components/layout-editor/EditorCanvas.js +25 -17
  26. package/dist/shared/components/layout-editor/EditorTopBar.js +268 -206
  27. package/dist/shared/components/layout-editor/LayoutEditor.js +810 -731
  28. package/dist/shared/components/layout-editor/PlaceTools.js +334 -0
  29. package/dist/shared/components/layout-editor/SlashInsert.js +252 -0
  30. package/dist/shared/components/layout-editor/StructureMenu.js +285 -242
  31. package/dist/shared/components/layout-editor/add-target.js +54 -43
  32. package/dist/shared/components/layout-editor/ai-forms/AiComposer.js +238 -155
  33. package/dist/shared/components/layout-editor/ai-forms/AiFormsButton.js +1 -1
  34. package/dist/shared/components/layout-editor/ai-forms/ai-forms-api.js +15 -12
  35. package/dist/shared/components/layout-editor/dnd/LayoutDndProvider.js +379 -185
  36. package/dist/shared/components/layout-editor/dnd/TrashZone.js +96 -0
  37. package/dist/shared/components/layout-editor/dnd/UndoChip.js +76 -0
  38. package/dist/shared/components/layout-editor/dnd/merge-drop.js +33 -0
  39. package/dist/shared/components/layout-editor/dnd/multi-drop.js +87 -0
  40. package/dist/shared/components/layout-editor/dnd/node.js +115 -105
  41. package/dist/shared/components/layout-editor/dnd/rail-drop.js +4 -4
  42. package/dist/shared/components/layout-editor/dnd/sensors.js +23 -0
  43. package/dist/shared/components/layout-editor/dnd/trash-drop.js +58 -0
  44. package/dist/shared/components/layout-editor/dnd/trash-links.js +97 -0
  45. package/dist/shared/components/layout-editor/even-row.js +86 -0
  46. package/dist/shared/components/layout-editor/field-list.js +99 -0
  47. package/dist/shared/components/layout-editor/format-painter.js +102 -0
  48. package/dist/shared/components/layout-editor/grid-guides.js +15 -13
  49. package/dist/shared/components/layout-editor/inspector/BehaviourSettings.js +150 -132
  50. package/dist/shared/components/layout-editor/inspector/BulkInspector.js +57 -53
  51. package/dist/shared/components/layout-editor/inspector/EvenRowAction.js +31 -0
  52. package/dist/shared/components/layout-editor/inspector/GroupInspector.js +154 -141
  53. package/dist/shared/components/layout-editor/inspector/Inspector.js +209 -178
  54. package/dist/shared/components/layout-editor/inspector/LookTab.js +106 -98
  55. package/dist/shared/components/layout-editor/inspector/RulesTab.js +38 -37
  56. package/dist/shared/components/layout-editor/inspector/kit.js +280 -223
  57. package/dist/shared/components/layout-editor/keyboard-move.js +15 -15
  58. package/dist/shared/components/layout-editor/lint/LabelStyle.js +201 -0
  59. package/dist/shared/components/layout-editor/lint/LintPanel.js +132 -84
  60. package/dist/shared/components/layout-editor/lint/lint-api.js +65 -28
  61. package/dist/shared/components/layout-editor/nav/NavTools.js +14 -12
  62. package/dist/shared/components/layout-editor/nav/ZoomControls.js +145 -0
  63. package/dist/shared/components/layout-editor/nav/useEditorNav.js +34 -32
  64. package/dist/shared/components/layout-editor/nav/view-prefs.js +100 -15
  65. package/dist/shared/components/layout-editor/outputs/LayoutFile.js +89 -0
  66. package/dist/shared/components/layout-editor/outputs/OutputsButton.js +272 -195
  67. package/dist/shared/components/layout-editor/outputs/layout-file-plan.js +176 -0
  68. package/dist/shared/components/layout-editor/outputs/output-api.js +71 -37
  69. package/dist/shared/components/layout-editor/overview/describe-conditions.js +16 -11
  70. package/dist/shared/components/layout-editor/overview/purpose.js +5 -5
  71. package/dist/shared/components/layout-editor/panel-frame.js +1 -1
  72. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  73. package/dist/shared/components/layout-editor/personal-default-marks.js +40 -0
  74. package/dist/shared/components/layout-editor/pin.js +37 -19
  75. package/dist/shared/components/layout-editor/place-clip.js +257 -0
  76. package/dist/shared/components/layout-editor/preview/PreviewModes.js +27 -26
  77. package/dist/shared/components/layout-editor/preview/PreviewPanes.js +149 -118
  78. package/dist/shared/components/layout-editor/preview/SampleRecord.js +113 -0
  79. package/dist/shared/components/layout-editor/preview/preview-model.js +79 -60
  80. package/dist/shared/components/layout-editor/preview/sample-record.js +105 -0
  81. package/dist/shared/components/layout-editor/removed-log.js +151 -0
  82. package/dist/shared/components/layout-editor/reuse/LibraryRows.js +109 -78
  83. package/dist/shared/components/layout-editor/reuse/linked-sections.js +373 -0
  84. package/dist/shared/components/layout-editor/revert-element.js +140 -0
  85. package/dist/shared/components/layout-editor/section-structure.js +193 -170
  86. package/dist/shared/components/layout-editor/settings/EntrySection.js +63 -45
  87. package/dist/shared/components/layout-editor/settings/LayoutSection.js +63 -32
  88. package/dist/shared/components/layout-editor/settings/ResolveSettings.js +179 -137
  89. package/dist/shared/components/layout-editor/settings/WhoSection.js +18 -17
  90. package/dist/shared/components/layout-editor/settings/settings-registry.js +24 -0
  91. package/dist/shared/components/layout-editor/shortcuts.js +21 -16
  92. package/dist/shared/components/layout-editor/structure-ops.js +221 -195
  93. package/dist/shared/components/layout-editor/usage/UsagePanel.js +133 -85
  94. package/dist/shared/components/layout-editor/usage/refusal-lens.js +130 -0
  95. package/dist/shared/components/layout-editor/usage/usage-api.js +12 -11
  96. package/dist/shared/components/panels/CommentPanel.js +47 -45
  97. package/dist/shared/components/panels/RevisionsPanel.js +66 -64
  98. package/dist/shared/components/panels/TaskPanel.js +395 -332
  99. package/dist/shared/components/profile/AgentsPanel.js +196 -147
  100. package/dist/shared/components/profile/ConnectionRollback.js +329 -0
  101. package/dist/shared/components/profile/MyDefaultsCard.js +526 -520
  102. package/dist/shared/lib/entry-config.js +22 -22
  103. package/dist/shared/lib/form-usage-beacon.js +91 -55
  104. package/dist/shared/lib/layout-lint.js +530 -284
  105. package/dist/shared/lib/layout-resolve.js +58 -44
  106. package/package.json +1 -1
@@ -9,7 +9,7 @@ import { noteReplayEvent as _e, createReplayCheckoutState as De } from "../share
9
9
  import { emitReplayTap as Te, setReplayRecorderMode as N, registerReplayCapture as qe, clipEndOffset as Le, withClipKind as Pe } from "../shared/lib/replay-capture.js";
10
10
  import { instrumentConsole as Ne, instrumentRequests as Fe, redactSecrets as Me } from "../shared/lib/replay-context.js";
11
11
  import { instrumentSocket as Oe } from "../shared/lib/replay-socket.js";
12
- const Ue = "nivaro-react@0.3.35", j = 1e4, We = 150, He = 3e3, Ke = 600, $e = (n) => `nvr_replay_resume${n ? `:${n}` : ""}`, G = () => typeof navigator > "u" || navigator.onLine !== !1;
12
+ const Ue = "nivaro-react@0.3.37", j = 1e4, We = 150, He = 3e3, Ke = 600, $e = (n) => `nvr_replay_resume${n ? `:${n}` : ""}`, G = () => typeof navigator > "u" || navigator.onLine !== !1;
13
13
  function Be(n) {
14
14
  return typeof n.url != "string" || typeof fetch != "function" ? null : (f, a) => {
15
15
  const u = typeof n.getToken == "function" ? n.getToken() : void 0, d = { "Content-Type": "application/json" };
package/dist/index.d.ts CHANGED
@@ -2374,16 +2374,17 @@ declare interface DesignMark {
2374
2374
  /** Instant tooltip (data-tip) with the detail. */
2375
2375
  tip?: string;
2376
2376
  highlight?: boolean;
2377
- /** A small icon before the text (a pinned section's pin, #2628). */
2378
- icon?: 'pin';
2377
+ /** A small icon before the text (a pinned section's pin, #2628; a personal-default field's person). */
2378
+ icon?: 'pin' | 'person' | 'link';
2379
2379
  /**
2380
2380
  * Where the tag ranks when a node has more than fit (DesignNode shows two,
2381
2381
  * then "+n"): `preview` (a preview mode's own tag) ranks with the role
2382
2382
  * mark, `loop` (a rule loop) next, plain rule and state tags after, `ai`
2383
2383
  * (an AI finding) last but one, "from <parent>" last. A highlighted tag
2384
- * without a kind ranks as a loop.
2384
+ * without a kind ranks as a loop. `personal` (the field takes personal defaults) ranks with a
2385
+ * loop: it says what the field IS for people, so it never hides behind "+n".
2385
2386
  */
2386
- kind?: 'preview' | 'loop' | 'ai';
2387
+ kind?: 'preview' | 'loop' | 'ai' | 'personal';
2387
2388
  /** Clickable: opens what the tag explains (the node is selected first). */
2388
2389
  onClick?: () => void;
2389
2390
  }
@@ -5349,6 +5350,8 @@ declare interface LayoutDesign {
5349
5350
  ghost?(field: string): string | null;
5350
5351
  /** #2701: the width handle on a selected field set its width (12, 6, 4 or 3 columns). */
5351
5352
  resizeWidth?(t: DesignTarget, span: number): void;
5353
+ /** #3194: nodes inside a linked library section never drag (they change in the library). */
5354
+ locked?(t: DesignTarget): boolean;
5352
5355
  }
5353
5356
 
5354
5357
  /**
@@ -5442,6 +5445,12 @@ declare interface LayoutGroup {
5442
5445
  * (lib/visible-when.ts) and "hide this section while everything in it is empty". */
5443
5446
  visible_when?: string | null;
5444
5447
  hide_when_empty?: boolean | number | null;
5448
+ /** #3195: values a collapsed section shows in its heading (the edit form's summary strip). */
5449
+ summary_fields?: string | string[] | Array<string | {
5450
+ field?: string;
5451
+ label?: string | null;
5452
+ }> | null;
5453
+ summary_hide_empty?: boolean | number | null;
5445
5454
  }
5446
5455
 
5447
5456
  export declare type LayoutItem = FormGroupDescriptor | '__ungrouped__';
@@ -0,0 +1,26 @@
1
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
+ import { Bot as n } from "lucide-react";
3
+ import { cn as s } from "../lib/utils.js";
4
+ function o({
5
+ label: t,
6
+ className: a
7
+ }) {
8
+ return t ? /* @__PURE__ */ r(
9
+ "span",
10
+ {
11
+ "data-nvr-agent-badge": !0,
12
+ "data-tip": "Made by an AI assistant acting as this person, through Nivaro’s MCP server",
13
+ className: s(
14
+ "inline-flex shrink-0 items-center gap-1 rounded bg-slate-100 px-1.5 py-px text-[10.5px] font-medium leading-4 text-slate-600 dark:bg-muted dark:text-slate-300",
15
+ a
16
+ ),
17
+ children: [
18
+ /* @__PURE__ */ e(n, { className: "h-3 w-3", "aria-hidden": !0 }),
19
+ /* @__PURE__ */ e("span", { className: "max-w-[16ch] truncate", children: t })
20
+ ]
21
+ }
22
+ ) : null;
23
+ }
24
+ export {
25
+ o as AgentBadge
26
+ };
@@ -0,0 +1,198 @@
1
+ import { jsxs as s, jsx as n } from "react/jsx-runtime";
2
+ import { useQueryClient as E } from "@tanstack/react-query";
3
+ import { Bot as S } from "lucide-react";
4
+ import { useRef as N, useState as f, useEffect as _ } from "react";
5
+ import { useApiFetchConfig as I, useItemNavigation as j } from "../context.js";
6
+ import { userErrorMessage as Q } from "../lib/safe-error.js";
7
+ import { formatRelative as D, cn as L } from "../lib/utils.js";
8
+ import { Textarea as M } from "./ui/textarea.js";
9
+ function O() {
10
+ try {
11
+ const e = new URLSearchParams(window.location.search).get("focus") ?? "", o = /^question:([0-9a-f-]{36})/i.exec(e);
12
+ return o ? o[1].toLowerCase() : null;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+ function A(e) {
18
+ const o = new Date(e).getTime() - Date.now();
19
+ if (o <= 0) return "Expired";
20
+ const a = Math.round(o / 6e4);
21
+ if (a < 60) return `Expires in ${a} min`;
22
+ const d = Math.round(a / 60);
23
+ return d < 48 ? `Expires in ${d} h` : `Expires in ${Math.round(d / 24)} days`;
24
+ }
25
+ function V({ questions: e }) {
26
+ const o = N(O()).current, [a, d] = f({});
27
+ if (e.length === 0 && Object.keys(a).length === 0) return null;
28
+ const l = e.filter((r) => !a[r.id]).length;
29
+ return /* @__PURE__ */ s(
30
+ "section",
31
+ {
32
+ className: "rounded-lg border border-nvr-cyan/30 bg-white dark:border-nvr-cyan/25 dark:bg-card",
33
+ "data-my-work-questions": !0,
34
+ "aria-labelledby": "my-work-questions-title",
35
+ children: [
36
+ /* @__PURE__ */ s("div", { className: "border-b border-slate-200 px-4 py-2.5 dark:border-border", children: [
37
+ /* @__PURE__ */ s(
38
+ "h2",
39
+ {
40
+ id: "my-work-questions-title",
41
+ className: "flex items-center gap-1.5 text-[13px] font-medium",
42
+ children: [
43
+ /* @__PURE__ */ n(S, { className: "h-3.5 w-3.5 text-[#0e7490] dark:text-[#67e8f9]", "aria-hidden": !0 }),
44
+ "Questions from assistants",
45
+ l > 0 && /* @__PURE__ */ n("span", { className: "rounded-full bg-nvr-cyan/10 px-1.5 text-[10.5px] font-semibold tabular-nums text-[#0e7490] dark:text-[#67e8f9]", children: l })
46
+ ]
47
+ }
48
+ ),
49
+ /* @__PURE__ */ n("p", { className: "text-[11px] text-muted-foreground", children: "An assistant is waiting for your answer before it carries on." })
50
+ ] }),
51
+ /* @__PURE__ */ s("ul", { className: "divide-y divide-slate-100 dark:divide-border/60", children: [
52
+ e.filter((r) => !a[r.id]).map((r) => {
53
+ var c, u;
54
+ return /* @__PURE__ */ n(
55
+ K,
56
+ {
57
+ q: r,
58
+ focused: o === r.id.toLowerCase(),
59
+ forMe: ((c = r.asked_for) == null ? void 0 : c.toLowerCase()) === ((u = r.recipient) == null ? void 0 : u.toLowerCase()),
60
+ onAnswered: (m) => d((i) => ({ ...i, [r.id]: m }))
61
+ },
62
+ r.id
63
+ );
64
+ }),
65
+ Object.entries(a).map(([r, c]) => /* @__PURE__ */ n(
66
+ "li",
67
+ {
68
+ className: "px-4 py-2 text-[12px] text-muted-foreground",
69
+ role: "status",
70
+ "data-my-work-question-done": r,
71
+ children: c
72
+ },
73
+ r
74
+ ))
75
+ ] })
76
+ ]
77
+ }
78
+ );
79
+ }
80
+ function K({
81
+ q: e,
82
+ focused: o,
83
+ forMe: a,
84
+ onAnswered: d
85
+ }) {
86
+ const { apiBase: l, authHeaders: r, credentials: c } = I(), { open: u } = j(), m = E(), [i, C] = f(""), [p, g] = f(null), [k, v] = f(null), b = N(null);
87
+ _(() => {
88
+ var x;
89
+ if (!o || !b.current) return;
90
+ const t = (x = window.matchMedia) == null ? void 0 : x.call(window, "(prefers-reduced-motion: reduce)").matches;
91
+ b.current.scrollIntoView({ block: "center", behavior: t ? "auto" : "smooth" });
92
+ }, [o]);
93
+ const y = async (t, x) => {
94
+ g(x), v(null);
95
+ try {
96
+ const h = await fetch(`${l}/agent-questions/${encodeURIComponent(e.id)}/answer`, {
97
+ method: "POST",
98
+ headers: { ...r, "content-type": "application/json" },
99
+ credentials: c,
100
+ body: JSON.stringify(t)
101
+ }), $ = await h.json().catch(() => ({}));
102
+ if (!h.ok) throw new Error($.error ?? "Could not send the answer");
103
+ d(`Sent to ${e.asked_by}: ${t.choice ?? t.answer}`), m.invalidateQueries({ queryKey: ["my-work"] }), m.invalidateQueries({ queryKey: ["notifications"] });
104
+ } catch (h) {
105
+ v(Q(h, "Could not send the answer"));
106
+ } finally {
107
+ g(null);
108
+ }
109
+ }, w = e.choices.length > 0;
110
+ return /* @__PURE__ */ s(
111
+ "li",
112
+ {
113
+ ref: b,
114
+ className: L(
115
+ "space-y-2 px-4 py-3 transition-colors duration-700",
116
+ o && "bg-nvr-cyan/5 dark:bg-nvr-cyan/10"
117
+ ),
118
+ "data-my-work-question": e.id,
119
+ children: [
120
+ /* @__PURE__ */ s("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-0.5", children: [
121
+ /* @__PURE__ */ n("span", { className: "text-[12px] font-medium text-slate-900 dark:text-foreground", children: e.asked_by }),
122
+ /* @__PURE__ */ s("span", { className: "text-[11px] text-muted-foreground", children: [
123
+ a ? "your assistant" : `for ${e.asked_for_name ?? "a colleague"}`,
124
+ " · asked",
125
+ " ",
126
+ D(e.created_at),
127
+ " · ",
128
+ A(e.expires_at)
129
+ ] }),
130
+ e.collection && e.item && /* @__PURE__ */ n(
131
+ "button",
132
+ {
133
+ type: "button",
134
+ onClick: () => u({ collection: e.collection, itemId: e.item }),
135
+ className: "text-[11px] text-[#0e7490] hover:underline dark:text-[#67e8f9]",
136
+ children: "Open the record"
137
+ }
138
+ )
139
+ ] }),
140
+ /* @__PURE__ */ n("p", { className: "whitespace-pre-wrap break-words text-[13px] text-slate-800 dark:text-slate-100", children: e.question }),
141
+ w && /* @__PURE__ */ s("fieldset", { className: "m-0 min-w-0 border-0 p-0", children: [
142
+ /* @__PURE__ */ n("legend", { className: "sr-only", children: "Choices" }),
143
+ /* @__PURE__ */ n("div", { className: "flex flex-wrap gap-1.5", children: e.choices.map((t) => /* @__PURE__ */ n(
144
+ "button",
145
+ {
146
+ type: "button",
147
+ disabled: p != null,
148
+ onClick: () => void y({ choice: t }, `c:${t}`),
149
+ className: "rounded-md border border-slate-200 bg-white px-2.5 py-1 text-[12px] font-medium text-slate-800 hover:border-nvr-cyan hover:bg-nvr-cyan/10 disabled:opacity-50 dark:border-border dark:bg-background dark:text-foreground",
150
+ "data-my-work-question-choice": t,
151
+ children: p === `c:${t}` ? "Sending…" : t
152
+ },
153
+ t
154
+ )) })
155
+ ] }),
156
+ (e.allow_text || !w) && /* @__PURE__ */ s(
157
+ "form",
158
+ {
159
+ className: "flex flex-col gap-1.5 sm:flex-row sm:items-end",
160
+ onSubmit: (t) => {
161
+ t.preventDefault(), i.trim() && y({ answer: i.trim() }, "text");
162
+ },
163
+ children: [
164
+ /* @__PURE__ */ n(
165
+ M,
166
+ {
167
+ value: i,
168
+ onChange: (t) => C(t.target.value),
169
+ placeholder: w ? "Or write your own answer…" : "Your answer…",
170
+ rows: 2,
171
+ maxLength: 4e3,
172
+ className: "min-h-[52px] flex-1 bg-white text-[12.5px] dark:bg-background",
173
+ "aria-label": `Answer to ${e.asked_by}`,
174
+ onKeyDown: (t) => {
175
+ t.key === "Enter" && (t.metaKey || t.ctrlKey) && i.trim() && (t.preventDefault(), y({ answer: i.trim() }, "text"));
176
+ }
177
+ }
178
+ ),
179
+ /* @__PURE__ */ n(
180
+ "button",
181
+ {
182
+ type: "submit",
183
+ disabled: !i.trim() || p != null,
184
+ className: "h-8 shrink-0 rounded-md bg-nvr-cyan px-3 text-[12px] font-medium text-white hover:bg-nvr-cyan/90 disabled:opacity-50",
185
+ children: p === "text" ? "Sending…" : "Send answer"
186
+ }
187
+ )
188
+ ]
189
+ }
190
+ ),
191
+ k && /* @__PURE__ */ n("p", { className: "text-[11.5px] text-red-600 dark:text-red-400", role: "alert", children: k })
192
+ ]
193
+ }
194
+ );
195
+ }
196
+ export {
197
+ V as AgentQuestionsCard
198
+ };