@hachej/boring-ui-kit 0.4.57 → 0.4.58

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 (49) hide show
  1. package/dist/chat-react-conversations.d.ts +7 -1
  2. package/dist/chat-react-conversations.js +58 -18
  3. package/package.json +2 -2
  4. package/r/agent-target.json +4 -4
  5. package/r/app-shell.json +9 -9
  6. package/r/board-viewer.json +6 -6
  7. package/r/button.json +1 -1
  8. package/r/dock.json +1 -1
  9. package/r/documents.json +12 -12
  10. package/r/drawing-viewer.json +1 -1
  11. package/r/feedback.json +6 -6
  12. package/r/file-tree.json +4 -4
  13. package/r/highlights.json +3 -3
  14. package/r/html-viewer.json +3 -3
  15. package/r/looks-viewer.json +2 -2
  16. package/r/maquette-viewer.json +1 -1
  17. package/r/markdown-editor.json +3 -3
  18. package/r/mockup-viewer.json +1 -1
  19. package/r/pi-ambient.json +9 -9
  20. package/r/pi-app-kinds.json +10 -10
  21. package/r/pi-app.json +10 -10
  22. package/r/pi-artifacts.json +2 -2
  23. package/r/pi-chat-approval.json +2 -2
  24. package/r/pi-chat-attachments.json +1 -1
  25. package/r/pi-chat-markdown.json +2 -2
  26. package/r/pi-chat-mentions.json +1 -1
  27. package/r/pi-chat-pickers.json +1 -1
  28. package/r/pi-chat-plugins.json +11 -11
  29. package/r/pi-chat-question.json +1 -1
  30. package/r/pi-chat-slash.json +2 -2
  31. package/r/pi-chat-subagent.json +1 -1
  32. package/r/pi-chat-voice.json +3 -3
  33. package/r/pi-chat.json +10 -10
  34. package/r/pi-workspace.json +3 -3
  35. package/r/placed-agent.json +4 -4
  36. package/r/provider-setup.json +1 -1
  37. package/r/registry.json +162 -162
  38. package/r/shared-chat.json +6 -6
  39. package/r/spaces.json +1 -1
  40. package/r/task-list-viewer.json +2 -2
  41. package/r/version-history.json +2 -2
  42. package/r/viewer-code.json +2 -2
  43. package/r/viewer-frame.json +4 -4
  44. package/r/viewer-html.json +4 -4
  45. package/r/viewer-image.json +2 -2
  46. package/r/viewer-markdown.json +5 -5
  47. package/r/viewer-pdf.json +3 -3
  48. package/r/viewers.json +6 -6
  49. package/r/windows.json +1 -1
@@ -11,10 +11,16 @@ export interface ConversationsClient {
11
11
  readonly activeId: string | undefined;
12
12
  /** New or fork is on its way: the conversation on screen is about to be left, so it must take no message (`PiChat` disables its composer). */
13
13
  readonly creating: boolean;
14
- /** The conversation New or fork just opened, for up to three seconds: `PiChat` puts the cursor in its box once, then calls `openedSeen`, so a later remount does not. */
14
+ /** The conversation New or fork just opened, for up to three seconds: `PiChat` puts the cursor in its box once, then calls `openedSeen`, so a later remount does not. Undefined while a dead key or IME composition is open in the hidden field, however long it stays open. */
15
15
  readonly opened: string | undefined;
16
16
  /** Ends `opened` and returns what the person typed since New, for the new box. */
17
17
  readonly openedSeen: () => string;
18
+ /** New chat was refused or got no answer in time, in the conversation on screen. `typed`: the person's text was dropped. `PiChat` and `AmbientChat` say so. */
19
+ readonly newFailed: {
20
+ readonly typed: boolean;
21
+ } | undefined;
22
+ /** The person closed that message. */
23
+ readonly newFailedSeen: () => void;
18
24
  readonly reload: () => Promise<void>;
19
25
  readonly onSelect: (id: string) => void;
20
26
  readonly onNew: () => void;
@@ -11,15 +11,15 @@ const OPENED_MS = 3000;
11
11
  /**
12
12
  * The clicked button keeps the focus until the new box is back, so a Space typed then would press New again, and the box is held, so the start of a message would be lost.
13
13
  * The focus goes to a hidden field until then: it outlives the chat's remount, and dead keys, IME and Backspace work there. Not on a phone, where it would open the keyboard.
14
+ * A composition still open must finish there: its accent is only a preview in the value, and the keyboard commits the letter to whatever has the focus.
14
15
  */
15
- function holdTyping() {
16
+ function holdTyping(onComposing) {
16
17
  const page = globalThis.document, focused = page?.activeElement;
17
18
  if (!page || focused?.matches('input, textarea, select, [contenteditable]'))
18
19
  return undefined;
19
- const from = focused?.matches('button, [role="button"]') ? focused : undefined;
20
20
  focused?.blur();
21
21
  if (globalThis.matchMedia?.('(pointer: coarse)').matches)
22
- return { from, field: undefined };
22
+ return { field: undefined, composing: false };
23
23
  const field = page.createElement('textarea');
24
24
  field.dataset.testid = 'new-chat-typing';
25
25
  field.tabIndex = -1;
@@ -27,29 +27,43 @@ function holdTyping() {
27
27
  field.style.cssText = 'position:fixed;top:0;left:0;width:1px;height:1px;padding:0;border:0;opacity:0;font-size:16px';
28
28
  field.addEventListener('keydown', event => { if (event.key === 'Enter')
29
29
  event.preventDefault(); });
30
+ const held = { field, composing: false };
31
+ const composing = (value) => { held.composing = value; onComposing(value); };
32
+ field.addEventListener('compositionstart', () => composing(true));
33
+ field.addEventListener('compositionend', () => composing(false));
34
+ field.addEventListener('blur', () => composing(false));
30
35
  page.body.append(field);
31
36
  field.focus();
32
- return { from, field };
37
+ return held;
33
38
  }
34
39
  export function useConversationsClient({ endpoint, fetch, activeId, onSelect, onChange, pollMs = 4000, openTimeoutMs = 15000 }) {
35
40
  const [items, setItems] = useState();
36
41
  const [creating, setCreating] = useState(false);
37
42
  const [opened, setOpened] = useState();
43
+ const [failedNew, setFailedNew] = useState();
38
44
  const typing = useRef(undefined);
39
- // What was typed goes nowhere else, so nothing reaches the conversation being left. The focus goes back unless the person moved.
45
+ const [composing, setComposing] = useState(false);
46
+ // What was typed goes nowhere else, so nothing reaches the conversation being left. The focus does not go back to the button: the next Space would press New again, and a create that works would take the rest of the text as a partial message.
40
47
  const dropTyping = useCallback(() => {
41
48
  const held = typing.current;
42
49
  typing.current = undefined;
43
50
  held?.field?.remove();
44
- if (globalThis.document?.activeElement === globalThis.document?.body)
45
- held?.from?.focus();
51
+ setComposing(false);
46
52
  }, []);
47
53
  useEffect(() => dropTyping, [dropTyping]);
48
54
  const openedTimer = useRef(undefined);
49
55
  const markOpened = useCallback((id) => {
50
56
  clearTimeout(openedTimer.current);
57
+ const expire = () => {
58
+ if (typing.current?.composing) {
59
+ openedTimer.current = setTimeout(expire, OPENED_MS);
60
+ return;
61
+ }
62
+ dropTyping();
63
+ setOpened(undefined);
64
+ };
51
65
  if (id !== undefined)
52
- openedTimer.current = setTimeout(() => { dropTyping(); setOpened(undefined); }, OPENED_MS);
66
+ openedTimer.current = setTimeout(expire, OPENED_MS);
53
67
  else
54
68
  dropTyping();
55
69
  setOpened(id);
@@ -57,9 +71,20 @@ export function useConversationsClient({ endpoint, fetch, activeId, onSelect, on
57
71
  // The New or fork on its way; forgetting it gives the composer back, and its late answer then moves nobody.
58
72
  const opening = useRef(undefined);
59
73
  const forget = useCallback(() => { opening.current = undefined; setCreating(false); }, []);
60
- const latest = useRef({ fetch, onSelect, onChange, activeId, openTimeoutMs });
61
- useLayoutEffect(() => { latest.current = { fetch, onSelect, onChange, activeId, openTimeoutMs }; });
62
74
  const base = endpoint === undefined ? undefined : String(endpoint);
75
+ const latest = useRef({ fetch, onSelect, onChange, activeId, openTimeoutMs, base });
76
+ // Every conversation this person has had open here: a late create's cleanup must never remove one of them.
77
+ const visited = useRef(new Set());
78
+ // Unmounted, it no longer knows what was opened since: its late cleanup removes nothing.
79
+ const mounted = useRef(true);
80
+ useEffect(() => { mounted.current = true; return () => { mounted.current = false; }; }, []);
81
+ useLayoutEffect(() => { latest.current = { fetch, onSelect, onChange, activeId, openTimeoutMs, base }; if (activeId !== undefined)
82
+ visited.current.add(activeId); });
83
+ // The text is not given back: it stays out of the draft being left, and the message says it is gone.
84
+ const failNew = useCallback(() => {
85
+ setFailedNew({ at: latest.current.activeId, typed: Boolean(typing.current?.field?.value) });
86
+ dropTyping();
87
+ }, [dropTyping]);
63
88
  const call = useCallback(async (params, body, signal) => {
64
89
  if (base === undefined)
65
90
  throw new Error('No conversations endpoint');
@@ -86,7 +111,7 @@ export function useConversationsClient({ endpoint, fetch, activeId, onSelect, on
86
111
  const reload = useCallback(() => list(), [list]);
87
112
  // Another endpoint (another owner's list) starts empty; switching conversations only reloads.
88
113
  // eslint-disable-next-line react-hooks/set-state-in-effect -- a new endpoint clears the old owner's list once, after commit
89
- useEffect(() => { setItems(undefined); markOpened(undefined); forget(); }, [base, forget, markOpened]);
114
+ useEffect(() => { setItems(undefined); setFailedNew(undefined); markOpened(undefined); forget(); }, [base, forget, markOpened]);
90
115
  useEffect(() => {
91
116
  if (base === undefined)
92
117
  return;
@@ -105,34 +130,48 @@ export function useConversationsClient({ endpoint, fetch, activeId, onSelect, on
105
130
  const open = async (name, body) => {
106
131
  if (opening.current)
107
132
  return;
133
+ const gaveUp = name === 'create' ? failNew : dropTyping;
108
134
  const run = {};
109
135
  opening.current = run;
110
136
  setCreating(true);
111
137
  const timer = setTimeout(() => { if (opening.current === run) {
112
138
  forget();
113
- dropTyping();
139
+ gaveUp();
114
140
  } }, latest.current.openTimeoutMs);
115
141
  let selected = false;
116
142
  try {
117
143
  const { conversationId } = await op(name, body);
118
- await changed();
144
+ // The conversation exists now: a host refresh that fails does not undo that.
145
+ await changed().catch(() => { });
119
146
  if (conversationId !== undefined && opening.current === run) {
120
147
  selected = true;
121
148
  markOpened(String(conversationId));
122
149
  latest.current.onSelect(String(conversationId));
123
150
  }
151
+ // Nobody waits for it any more, so it would stay in the list as an empty row. Only that row goes: not one the person has had open here, not one with a message (another tab), not on another owner's list.
152
+ else if (name === 'create' && conversationId !== undefined) {
153
+ const unused = () => mounted.current && latest.current.base === base && !visited.current.has(String(conversationId));
154
+ const row = unused() ? (await call({})).conversations?.find(served => String(served.id) === String(conversationId)) : undefined;
155
+ if (row?.lastMessage === null && unused()) {
156
+ await op('delete', { conversationId });
157
+ await changed();
158
+ }
159
+ }
124
160
  }
125
161
  finally {
126
162
  clearTimeout(timer);
127
163
  if (opening.current === run) {
128
164
  forget();
129
165
  if (!selected)
130
- dropTyping();
166
+ gaveUp();
131
167
  }
132
168
  }
133
169
  };
134
170
  return {
135
- items, activeId, creating, opened, reload,
171
+ items, activeId, creating, reload,
172
+ opened: composing ? undefined : opened,
173
+ newFailed: failedNew && failedNew.at === activeId ? { typed: failedNew.typed } : undefined,
174
+ newFailedSeen: () => setFailedNew(undefined),
136
175
  openedSeen: () => {
137
176
  const typed = typing.current?.field?.value ?? '';
138
177
  typing.current?.field?.remove();
@@ -140,11 +179,12 @@ export function useConversationsClient({ endpoint, fetch, activeId, onSelect, on
140
179
  markOpened(undefined);
141
180
  return typed;
142
181
  },
143
- onSelect: (id) => { forget(); markOpened(undefined); latest.current.onSelect(id); },
182
+ onSelect: (id) => { forget(); setFailedNew(undefined); markOpened(undefined); latest.current.onSelect(id); },
144
183
  onNew: () => {
145
184
  if (!opening.current) {
185
+ setFailedNew(undefined);
146
186
  markOpened(undefined);
147
- typing.current = holdTyping();
187
+ typing.current = holdTyping(setComposing);
148
188
  }
149
189
  else
150
190
  typing.current?.field?.focus();
@@ -161,7 +201,7 @@ export function useConversationsClient({ endpoint, fetch, activeId, onSelect, on
161
201
  await open('fork', { conversationId: from, at });
162
202
  },
163
203
  };
164
- }, [items, activeId, creating, opened, call, reload, forget, markOpened, dropTyping]);
204
+ }, [items, activeId, creating, opened, composing, failedNew, base, call, reload, forget, markOpened, dropTyping, failNew]);
165
205
  }
166
206
  /** Compatibility spelling retained for one release. */
167
207
  export const useConversations = useConversationsClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-ui-kit",
3
- "version": "0.4.57",
3
+ "version": "0.4.58",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "type": "module",
@@ -154,7 +154,7 @@
154
154
  }
155
155
  },
156
156
  "peerDependencies": {
157
- "@hachej/boring-files": "^0.4.57",
157
+ "@hachej/boring-files": "^0.4.58",
158
158
  "@earendil-works/pi-durable": "~1.4.0",
159
159
  "react": "^19.0.0",
160
160
  "react-dom": "^19.0.0",
@@ -4,15 +4,15 @@
4
4
  "title": "Point and dictate on app data",
5
5
  "description": "Tap explicitly marked JSON app context, dictate once and show the same app agent’s native reply without opening chat. Host-controlled presentation; no feedback report or second controller.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-feedback@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-feedback@^0.4.58",
9
9
  "@earendil-works/pi-durable@~1.4.0",
10
10
  "react@^19.0.0",
11
11
  "react-dom@^19.0.0"
12
12
  ],
13
13
  "registryDependencies": [
14
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/app-shell.json",
15
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-chat.json"
14
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/app-shell.json",
15
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-chat.json"
16
16
  ],
17
17
  "files": [
18
18
  {
package/r/app-shell.json CHANGED
@@ -4,21 +4,21 @@
4
4
  "title": "App shell: layouts, list/detail and agent layer",
5
5
  "description": "AppShell with three layouts. B \"workspace\" puts a ListDetail on a screen (phone: the list, then the detail as a stack step with Back; wide: a 20rem list and the detail side by side, sidebar as an icon rail). C \"chat\" wraps the app's own AgentWorkspace (untouched, passed as the nav item's render; install the pi-app item yourself) in the same sidebar, account menu and header; it takes no shell agent. A \"screen\": one screen at a time, every screen kept mounted. On a phone bottom tabs (at most four; more give three plus a « Plus » sheet) and an avatar button that opens the account sheet; on a wide screen the shadcn sidebar (icon rail, NavUser). One header per screen through useScreenHeader (title, subtitle, back, up to two actions, the rest behind « … »). The account menu holds « Améliorer l'app » (the improve agent), the app's own entries and sign out. AppSheet is the one bottom sheet (one open at a time, Back closes it). It mounts the AgentLayer: one agent's PiChat above the app (phone: a drawer with peek, half and full snap points; wide: a right panel), the improve agent in the same layer, optional push-to-talk and point mode. Also useAgentContext and readAgentContext (the screen on show travels as `context` with each submit) and useBackLayer, the one Back manager. Built on explicitly pinned Base UI drawer and dropdown-menu recipes, plus the sidebar and avatar of the host's own shadcn style.",
6
6
  "dependencies": [
7
- "@hachej/boring-feedback@^0.4.57",
8
- "@hachej/boring-ui-kit@^0.4.57",
7
+ "@hachej/boring-feedback@^0.4.58",
8
+ "@hachej/boring-ui-kit@^0.4.58",
9
9
  "@base-ui/react@^1.9.0",
10
10
  "react@^19.0.0",
11
11
  "react-dom@^19.0.0",
12
12
  "lucide-react@^1.51.0"
13
13
  ],
14
14
  "registryDependencies": [
15
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-chat.json",
16
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-chat-plugins.json",
17
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-chat-voice.json",
18
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/dock.json",
19
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/feedback.json",
20
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json",
21
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/button.json"
15
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-chat.json",
16
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-chat-plugins.json",
17
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-chat-voice.json",
18
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/dock.json",
19
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/feedback.json",
20
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json",
21
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/button.json"
22
22
  ],
23
23
  "files": [
24
24
  {
@@ -4,17 +4,17 @@
4
4
  "title": "Board viewer",
5
5
  "description": "A board@1 artifact kind for *.board.json. Lazy native tldraw projection of maquette screens, sandboxed HTML mock-ups, goto arrows and notes. Conditional board-file autosave; phone viewing without accidental frame edits. Hosts supply their resource client, asset URLs and license key.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-files@^0.4.58",
9
9
  "react@^19.0.0",
10
10
  "lucide-react@1.51.0",
11
11
  "tldraw@5.5.2"
12
12
  ],
13
13
  "registryDependencies": [
14
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/maquette-viewer.json",
15
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/mockup-viewer.json",
16
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-artifacts.json",
17
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json"
14
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/maquette-viewer.json",
15
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/mockup-viewer.json",
16
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-artifacts.json",
17
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json"
18
18
  ],
19
19
  "files": [
20
20
  {
package/r/button.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "lucide-react@^1.51.0"
10
10
  ],
11
11
  "registryDependencies": [
12
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json"
12
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json"
13
13
  ],
14
14
  "files": [
15
15
  {
package/r/dock.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "react@^19.0.0"
8
8
  ],
9
9
  "registryDependencies": [
10
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json"
10
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json"
11
11
  ],
12
12
  "files": [
13
13
  {
package/r/documents.json CHANGED
@@ -4,22 +4,22 @@
4
4
  "title": "Documents: the Library, a file and its revisions",
5
5
  "description": "The workspace's Library as the list, the chosen file in its viewer and its retained revisions beside it (an older one opens read-only). DocumentSheet opens one document over the app for a host's « Voir la fiche », with an optional « Toutes les fiches ». Every read goes through one revisionProvider binding.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-files@^0.4.58",
9
9
  "react@^19.0.0",
10
10
  "lucide-react@^1.51.0"
11
11
  ],
12
12
  "registryDependencies": [
13
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json",
14
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/button.json",
15
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-artifacts.json",
16
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-app.json",
17
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-app-kinds.json",
18
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/app-shell.json",
19
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/file-tree.json",
20
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/viewer-frame.json",
21
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/viewer-image.json",
22
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/viewer-pdf.json"
13
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json",
14
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/button.json",
15
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-artifacts.json",
16
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-app.json",
17
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-app-kinds.json",
18
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/app-shell.json",
19
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/file-tree.json",
20
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/viewer-frame.json",
21
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/viewer-image.json",
22
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/viewer-pdf.json"
23
23
  ],
24
24
  "files": [
25
25
  {
@@ -4,7 +4,7 @@
4
4
  "title": "Drawing viewer",
5
5
  "description": "DrawingViewer, drawingKind and describeDrawing: an Excalidraw (.excalidraw) or draw.io (.drawio) file, read-only, drawn by the tool's own renderer on a white page fitted to the shapes: Excalidraw's exportToSvg (its fonts served by the app, never its CDN) and the official diagrams.net viewer, vendored in the kit (@hachej/boring-ui-kit/drawio-viewer), in a sandboxed frame without network. Shown as an image, so nothing in the file runs; an unreadable file shows an inline error. onRead hands the shapes and arrows the renderer read (kind, place, size, label, colours, from and to). Each renderer loads the first time a drawing of its format opens; the kind is not in the pi-app-kinds default list, so apps without drawings install nothing.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
8
  "react@^19.0.0",
9
9
  "lucide-react@^1.51.0",
10
10
  "@excalidraw/excalidraw@0.18.1"
package/r/feedback.json CHANGED
@@ -4,17 +4,17 @@
4
4
  "title": "Feedback",
5
5
  "description": "Feedback from the chat composer: one Feedback button starts feedback mode on the application page (hover, click to pin a numbered note, hold ⌥ to use the app, optional voice), and one chip carries the notes to the next message. FeedbackBar, NoteBubble, FeedbackChip with its review, useComposerFeedback for the pi-chat composer, and PickerOverlay styles. Optional, not mounted by default: PointButton, AnnotateSheet, FeedbackList and FeedbackReport. Picking, masking, anchoring and placement stay in @hachej/boring-feedback/page and /ui, so restyling cannot weaken them.",
6
6
  "dependencies": [
7
- "@hachej/boring-feedback@^0.4.57",
8
- "@hachej/boring-ui-kit@^0.4.57",
9
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-feedback@^0.4.58",
8
+ "@hachej/boring-ui-kit@^0.4.58",
9
+ "@hachej/boring-files@^0.4.58",
10
10
  "react@^19.0.0",
11
11
  "react-dom@^19.0.0",
12
12
  "lucide-react@^1.51.0"
13
13
  ],
14
14
  "registryDependencies": [
15
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-chat.json",
16
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/pi-chat-voice.json",
17
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json"
15
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-chat.json",
16
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/pi-chat-voice.json",
17
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json"
18
18
  ],
19
19
  "files": [
20
20
  {
package/r/file-tree.json CHANGED
@@ -4,14 +4,14 @@
4
4
  "title": "File tree",
5
5
  "description": "Browse, search, upload, rename, move, delete and inspect retained versions through one revisionProvider binding. Uses the consumer's shadcn Button, dropdown-menu and dialog with shared version-history rows; Base UI style only.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-files@^0.4.58",
9
9
  "react@^19.0.0",
10
10
  "lucide-react@^1.51.0"
11
11
  ],
12
12
  "registryDependencies": [
13
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json",
14
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/version-history.json"
13
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json",
14
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/version-history.json"
15
15
  ],
16
16
  "files": [
17
17
  {
package/r/highlights.json CHANGED
@@ -4,13 +4,13 @@
4
4
  "title": "Anchored highlights",
5
5
  "description": "Exact Markdown highlights and comments in a conditional workspace sidecar.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-files@^0.4.58",
9
9
  "react@^19.0.0",
10
10
  "react-dom@^19.0.0"
11
11
  ],
12
12
  "registryDependencies": [
13
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/markdown-editor.json"
13
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/markdown-editor.json"
14
14
  ],
15
15
  "files": [
16
16
  {
@@ -4,13 +4,13 @@
4
4
  "title": "HTML source and passive preview",
5
5
  "description": "Exact HTML source editing with a reconstructed passive preview and borrowed controller. Browser security qualification remains separate.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-files@^0.4.58",
9
9
  "react@^19.0.0",
10
10
  "react-dom@^19.0.0"
11
11
  ],
12
12
  "registryDependencies": [
13
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/button.json"
13
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/button.json"
14
14
  ],
15
15
  "files": [
16
16
  {
@@ -8,8 +8,8 @@
8
8
  "lucide-react@^1.51.0"
9
9
  ],
10
10
  "registryDependencies": [
11
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/mockup-viewer.json",
12
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/utils.json"
11
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/mockup-viewer.json",
12
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/utils.json"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -8,7 +8,7 @@
8
8
  "lucide-react@^1.51.0"
9
9
  ],
10
10
  "registryDependencies": [
11
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/diagram-viewer.json"
11
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/diagram-viewer.json"
12
12
  ],
13
13
  "files": [
14
14
  {
@@ -4,8 +4,8 @@
4
4
  "title": "Markdown editor",
5
5
  "description": "A host-owned styled wrapper over the concrete borrowed Markdown controller.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.4.57",
8
- "@hachej/boring-files@^0.4.57",
7
+ "@hachej/boring-ui-kit@^0.4.58",
8
+ "@hachej/boring-files@^0.4.58",
9
9
  "react@^19.0.0",
10
10
  "react-dom@^19.0.0",
11
11
  "marked@^17.0.6",
@@ -24,7 +24,7 @@
24
24
  "lucide-react@^1.51.0"
25
25
  ],
26
26
  "registryDependencies": [
27
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/button.json"
27
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/button.json"
28
28
  ],
29
29
  "files": [
30
30
  {
@@ -10,7 +10,7 @@
10
10
  "zod@^4.6.5"
11
11
  ],
12
12
  "registryDependencies": [
13
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.57/r/viewer-frame.json"
13
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.58/r/viewer-frame.json"
14
14
  ],
15
15
  "files": [
16
16
  {