@hachej/boring-ui-kit 0.2.3 → 0.2.5

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.
@@ -8,8 +8,8 @@
8
8
  "react-dom@^19.0.0"
9
9
  ],
10
10
  "registryDependencies": [
11
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-chat.json",
12
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json"
11
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-chat.json",
12
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -9,8 +9,8 @@
9
9
  "lucide-react@^1.51.0"
10
10
  ],
11
11
  "registryDependencies": [
12
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json",
13
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json"
12
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json",
13
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json"
14
14
  ],
15
15
  "files": [
16
16
  {
package/r/registry.json CHANGED
@@ -107,8 +107,8 @@
107
107
  "lucide-react@^1.51.0"
108
108
  ],
109
109
  "registryDependencies": [
110
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json",
111
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json"
110
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json",
111
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json"
112
112
  ],
113
113
  "files": [
114
114
  {
@@ -129,8 +129,8 @@
129
129
  "title": "Markdown editor",
130
130
  "description": "A host-owned styled wrapper over the concrete borrowed Markdown controller.",
131
131
  "dependencies": [
132
- "@hachej/boring-ui-kit@^0.2.3",
133
- "@hachej/boring-files@^0.2.3",
132
+ "@hachej/boring-ui-kit@^0.2.5",
133
+ "@hachej/boring-files@^0.2.5",
134
134
  "react@^19.0.0",
135
135
  "react-dom@^19.0.0",
136
136
  "marked@^17.0.6",
@@ -343,8 +343,8 @@
343
343
  "title": "HTML source and passive preview",
344
344
  "description": "Exact HTML source editing with a reconstructed passive preview and borrowed controller. Browser security qualification remains separate.",
345
345
  "dependencies": [
346
- "@hachej/boring-ui-kit@^0.2.3",
347
- "@hachej/boring-files@^0.2.3",
346
+ "@hachej/boring-ui-kit@^0.2.5",
347
+ "@hachej/boring-files@^0.2.5",
348
348
  "react@^19.0.0",
349
349
  "react-dom@^19.0.0"
350
350
  ],
@@ -435,8 +435,8 @@
435
435
  "title": "Pi chat",
436
436
  "description": "A complete Tailwind chat over the borrowed native chat controller: composer, messages, one collapsible activity block per turn (tool calls and reasoning), message queue, history, a human-in-the-loop question card, an Approve / Deny card for host tools wrapped with requireApproval optional artifact cards that open generated content in the host's panel, and feedback cards for the opt-in feedback tool (lists, and Show offers that the host page resolves). Chat only: no layout. Owned, editable source; no AI SDK. The optional pi-ambient and pi-workspace blocks build on it.",
437
437
  "dependencies": [
438
- "@hachej/boring-ui-kit@^0.2.3",
439
- "@hachej/boring-files@^0.2.3",
438
+ "@hachej/boring-ui-kit@^0.2.5",
439
+ "@hachej/boring-files@^0.2.5",
440
440
  "react@^19.0.0",
441
441
  "react-dom@^19.0.0",
442
442
  "marked@^17.0.6",
@@ -449,9 +449,9 @@
449
449
  "use-stick-to-bottom@^1.1.6"
450
450
  ],
451
451
  "registryDependencies": [
452
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json",
453
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json",
454
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/button.json"
452
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json",
453
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json",
454
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/button.json"
455
455
  ],
456
456
  "files": [
457
457
  {
@@ -574,6 +574,11 @@
574
574
  "type": "registry:hook",
575
575
  "target": "components/pi-chat/use-remote-chat.ts"
576
576
  },
577
+ {
578
+ "path": "registry/pi-chat/use-chat-draft.ts",
579
+ "type": "registry:hook",
580
+ "target": "components/pi-chat/use-chat-draft.ts"
581
+ },
577
582
  {
578
583
  "path": "registry/pi-chat/labels.ts",
579
584
  "type": "registry:lib",
@@ -671,7 +676,7 @@
671
676
  "title": "Pi ambient agent",
672
677
  "description": "AmbientChat, a compact floating agent bar that grows into a chat window over an existing page, and AgentNotifications, toasts for finished, failed and waiting tasks (with the one guarded browser Notification helper). A block over the pi-chat item; its in-window artifact panel uses the pi-workspace layout.",
673
678
  "dependencies": [
674
- "@hachej/boring-ui-kit@^0.2.3",
679
+ "@hachej/boring-ui-kit@^0.2.5",
675
680
  "react@^19.0.0",
676
681
  "react-dom@^19.0.0",
677
682
  "@earendil-works/pi-durable@~1.1.0",
@@ -679,10 +684,10 @@
679
684
  "lucide-react@^1.51.0"
680
685
  ],
681
686
  "registryDependencies": [
682
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-chat.json",
683
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-workspace.json",
684
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json",
685
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/button.json"
687
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-chat.json",
688
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-workspace.json",
689
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json",
690
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/button.json"
686
691
  ],
687
692
  "files": [
688
693
  {
@@ -712,8 +717,8 @@
712
717
  "react-dom@^19.0.0"
713
718
  ],
714
719
  "registryDependencies": [
715
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-chat.json",
716
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json"
720
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-chat.json",
721
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json"
717
722
  ],
718
723
  "files": [
719
724
  {
@@ -734,19 +739,19 @@
734
739
  "title": "Pi agent app",
735
740
  "description": "AgentWorkspace: a whole agent page in one component. Left: the sessions pane (search, New, rename, archive, delete; collapsible, a drawer on a narrow screen). Center: PiChat. Right: the artifact viewers (artifact panel with versions, file viewer, auto-open of new artifacts) in the ArtifactWorkspace panel, a full-screen sheet on a phone. Props are data and callbacks; hooks for the conversations handler (useConversations), the chat transport (useRemoteChat) and saved resources (useSaved).",
736
741
  "dependencies": [
737
- "@hachej/boring-ui-kit@^0.2.3",
738
- "@hachej/boring-files@^0.2.3",
742
+ "@hachej/boring-ui-kit@^0.2.5",
743
+ "@hachej/boring-files@^0.2.5",
739
744
  "react@^19.0.0",
740
745
  "react-dom@^19.0.0",
741
746
  "lucide-react@^1.51.0",
742
747
  "radix-ui@^1.8.0"
743
748
  ],
744
749
  "registryDependencies": [
745
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-chat.json",
746
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-workspace.json",
747
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/viewers.json",
748
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json",
749
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/button.json"
750
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-chat.json",
751
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-workspace.json",
752
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/viewers.json",
753
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json",
754
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/button.json"
750
755
  ],
751
756
  "files": [
752
757
  {
@@ -808,6 +813,119 @@
808
813
  "path": "registry/pi-app/app-labels-fr.ts",
809
814
  "type": "registry:lib",
810
815
  "target": "components/pi-app/app-labels-fr.ts"
816
+ },
817
+ {
818
+ "path": "registry/pi-app/use-revision-attachments.ts",
819
+ "type": "registry:hook",
820
+ "target": "components/pi-app/use-revision-attachments.ts"
821
+ }
822
+ ]
823
+ },
824
+ {
825
+ "name": "app-shell",
826
+ "type": "registry:block",
827
+ "title": "App shell: layouts, list/detail and agent layer",
828
+ "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 the shadcn drawer, sidebar, avatar and dropdown-menu of the host's own style (Base UI variants).",
829
+ "dependencies": [
830
+ "@hachej/boring-feedback@^0.2.5",
831
+ "@hachej/boring-ui-kit@^0.2.5",
832
+ "@base-ui/react@^1.8.0",
833
+ "react@^19.0.0",
834
+ "react-dom@^19.0.0",
835
+ "lucide-react@^1.51.0"
836
+ ],
837
+ "registryDependencies": [
838
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-chat.json",
839
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/feedback.json",
840
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json",
841
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/button.json",
842
+ "drawer",
843
+ "sidebar",
844
+ "avatar",
845
+ "dropdown-menu"
846
+ ],
847
+ "css": {
848
+ "@layer base": {
849
+ ".app-shell :where(button, [role=button])": {
850
+ "appearance": "none",
851
+ "background-color": "transparent",
852
+ "border": "0 solid",
853
+ "font": "inherit",
854
+ "color": "inherit",
855
+ "cursor": "pointer",
856
+ "padding": "0"
857
+ },
858
+ ".app-shell :where(h2)": {
859
+ "margin": "0",
860
+ "font": "inherit"
861
+ }
862
+ }
863
+ },
864
+ "files": [
865
+ {
866
+ "path": "registry/app-shell/agent-layer.tsx",
867
+ "type": "registry:component",
868
+ "target": "components/app-shell/agent-layer.tsx"
869
+ },
870
+ {
871
+ "path": "registry/app-shell/agent-context.ts",
872
+ "type": "registry:lib",
873
+ "target": "components/app-shell/agent-context.ts"
874
+ },
875
+ {
876
+ "path": "registry/app-shell/back.ts",
877
+ "type": "registry:lib",
878
+ "target": "components/app-shell/back.ts"
879
+ },
880
+ {
881
+ "path": "registry/app-shell/use-visual-viewport.ts",
882
+ "type": "registry:hook",
883
+ "target": "components/app-shell/use-visual-viewport.ts"
884
+ },
885
+ {
886
+ "path": "registry/app-shell/text.ts",
887
+ "type": "registry:lib",
888
+ "target": "components/app-shell/text.ts"
889
+ },
890
+ {
891
+ "path": "registry/app-shell/app-shell.tsx",
892
+ "type": "registry:component",
893
+ "target": "components/app-shell/app-shell.tsx"
894
+ },
895
+ {
896
+ "path": "registry/app-shell/list-detail.tsx",
897
+ "type": "registry:component",
898
+ "target": "components/app-shell/list-detail.tsx"
899
+ },
900
+ {
901
+ "path": "registry/app-shell/header.tsx",
902
+ "type": "registry:component",
903
+ "target": "components/app-shell/header.tsx"
904
+ },
905
+ {
906
+ "path": "registry/app-shell/nav.tsx",
907
+ "type": "registry:component",
908
+ "target": "components/app-shell/nav.tsx"
909
+ },
910
+ {
911
+ "path": "registry/app-shell/account.tsx",
912
+ "type": "registry:component",
913
+ "target": "components/app-shell/account.tsx"
914
+ },
915
+ {
916
+ "path": "registry/app-shell/sheet.tsx",
917
+ "type": "registry:component",
918
+ "target": "components/app-shell/sheet.tsx"
919
+ },
920
+ {
921
+ "path": "registry/app-shell/compact.ts",
922
+ "type": "registry:hook",
923
+ "target": "components/app-shell/compact.ts"
924
+ },
925
+ {
926
+ "path": "registry/app-shell/index.ts",
927
+ "type": "registry:lib",
928
+ "target": "components/app-shell/index.ts"
811
929
  }
812
930
  ]
813
931
  },
@@ -817,8 +935,8 @@
817
935
  "title": "Viewers",
818
936
  "description": "The standard viewer top bar (title, status, viewer controls, Refresh, Share, Copy, Download, Open in new tab, Close, overflow menu) with Tailwind panes over it: the Markdown editor with a formatting toolbar and prose styling, the passive HTML preview and source editor, an image viewer with zoom and pan, and a PDF viewer. Owned, editable source over the borrowed controllers; no AI SDK.",
819
937
  "dependencies": [
820
- "@hachej/boring-ui-kit@^0.2.3",
821
- "@hachej/boring-files@^0.2.3",
938
+ "@hachej/boring-ui-kit@^0.2.5",
939
+ "@hachej/boring-files@^0.2.5",
822
940
  "react@^19.0.0",
823
941
  "react-dom@^19.0.0",
824
942
  "marked@^17.0.6",
@@ -837,9 +955,9 @@
837
955
  "lucide-react@^1.51.0"
838
956
  ],
839
957
  "registryDependencies": [
840
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json",
841
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json",
842
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/button.json"
958
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json",
959
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json",
960
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/button.json"
843
961
  ],
844
962
  "files": [
845
963
  {
@@ -1462,8 +1580,8 @@
1462
1580
  "lucide-react@^1.51.0"
1463
1581
  ],
1464
1582
  "registryDependencies": [
1465
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json",
1466
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json"
1583
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json",
1584
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json"
1467
1585
  ],
1468
1586
  "files": [
1469
1587
  {
@@ -1479,9 +1597,9 @@
1479
1597
  "title": "Feedback",
1480
1598
  "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.",
1481
1599
  "dependencies": [
1482
- "@hachej/boring-feedback@^0.2.3",
1483
- "@hachej/boring-ui-kit@^0.2.3",
1484
- "@hachej/boring-files@^0.2.3",
1600
+ "@hachej/boring-feedback@^0.2.5",
1601
+ "@hachej/boring-ui-kit@^0.2.5",
1602
+ "@hachej/boring-files@^0.2.5",
1485
1603
  "react@^19.0.0",
1486
1604
  "react-dom@^19.0.0",
1487
1605
  "lucide-react@^1.51.0"
@@ -2204,13 +2322,56 @@
2204
2322
  "color": "var(--boring-feedback-text)",
2205
2323
  "font": "inherit"
2206
2324
  },
2325
+ "[data-boring=\"feedback\"] .boring-feedback-pin-field": {
2326
+ "display": "grid"
2327
+ },
2328
+ "[data-boring=\"feedback\"] .boring-feedback-pin-field > *": {
2329
+ "grid-column": "1"
2330
+ },
2331
+ "[data-boring=\"feedback\"] .boring-feedback-pin-field > textarea, [data-boring=\"feedback\"] .boring-feedback-pin-field > .boring-feedback-pin-mic": {
2332
+ "grid-row": "1"
2333
+ },
2334
+ "[data-boring=\"feedback\"] .boring-feedback-pin-field > .boring-feedback-voice-problem": {
2335
+ "grid-row": "2"
2336
+ },
2337
+ "[data-boring=\"feedback\"] .boring-feedback-pin-field textarea": {
2338
+ "display": "block",
2339
+ "box-sizing": "border-box",
2340
+ "width": "100%",
2341
+ "padding-right": "3.25rem"
2342
+ },
2343
+ "[data-boring=\"feedback\"] .boring-feedback-pin-mic": {
2344
+ "justify-self": "end",
2345
+ "align-self": "end",
2346
+ "display": "inline-flex",
2347
+ "align-items": "center",
2348
+ "justify-content": "center",
2349
+ "width": "2.75rem",
2350
+ "height": "2.75rem",
2351
+ "padding": "0",
2352
+ "border": "0",
2353
+ "border-radius": "var(--boring-feedback-radius-md)",
2354
+ "background": "transparent",
2355
+ "color": "var(--boring-feedback-muted)",
2356
+ "cursor": "pointer"
2357
+ },
2358
+ "[data-boring=\"feedback\"] .boring-feedback-pin-mic:hover": {
2359
+ "color": "var(--boring-feedback-text, inherit)"
2360
+ },
2361
+ "[data-boring=\"feedback\"] .boring-feedback-pin-mic[aria-pressed=\"true\"]": {
2362
+ "color": "var(--boring-feedback-accent)"
2363
+ },
2364
+ "[data-boring=\"feedback\"] .boring-feedback-pin-mic:disabled": {
2365
+ "opacity": "0.6",
2366
+ "cursor": "default"
2367
+ },
2207
2368
  "[data-boring=\"feedback\"] .boring-feedback-bubble-actions": {
2208
2369
  "display": "flex",
2209
2370
  "flex-wrap": "wrap",
2210
2371
  "gap": "0.375rem"
2211
2372
  },
2212
2373
  "[data-boring=\"feedback\"] .boring-feedback-bubble-actions .boring-feedback-button": {
2213
- "min-height": "2rem",
2374
+ "min-height": "2.75rem",
2214
2375
  "padding": "0 0.625rem",
2215
2376
  "font-size": "var(--text-sm, 0.875rem)"
2216
2377
  },
@@ -2221,8 +2382,8 @@
2221
2382
  }
2222
2383
  },
2223
2384
  "registryDependencies": [
2224
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/pi-chat.json",
2225
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json"
2385
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/pi-chat.json",
2386
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json"
2226
2387
  ]
2227
2388
  },
2228
2389
  {
@@ -2231,7 +2392,7 @@
2231
2392
  "title": "Feedback preview",
2232
2393
  "description": "PreviewBanner: a live, reversible preview of a change in the page (Approve / Discard) over `@hachej/boring-feedback/preview`, whose subagent calls models through a host gateway. Separate from `feedback` so annotation-only apps do not install the model SDK; install `feedback` first (its styles cover the banner).",
2233
2394
  "dependencies": [
2234
- "@hachej/boring-feedback@^0.2.3",
2395
+ "@hachej/boring-feedback@^0.2.5",
2235
2396
  "@earendil-works/pi-ai@~1.1.0",
2236
2397
  "react@^19.0.0"
2237
2398
  ],
@@ -2249,8 +2410,8 @@
2249
2410
  "title": "Consumer task-list viewer",
2250
2411
  "description": "A consumer-defined task-list schema and controller over the shared text buffer, with a restylable borrowed React renderer.",
2251
2412
  "dependencies": [
2252
- "@hachej/boring-ui-kit@^0.2.3",
2253
- "@hachej/boring-files@^0.2.3",
2413
+ "@hachej/boring-ui-kit@^0.2.5",
2414
+ "@hachej/boring-files@^0.2.5",
2254
2415
  "react@^19.0.0",
2255
2416
  "react-dom@^19.0.0",
2256
2417
  "zod@^4.6.5"
@@ -2316,14 +2477,14 @@
2316
2477
  "title": "File tree",
2317
2478
  "description": "Browse, search, upload and inspect retained versions through one revisionProvider binding.",
2318
2479
  "dependencies": [
2319
- "@hachej/boring-ui-kit@^0.2.3",
2320
- "@hachej/boring-files@^0.2.3",
2480
+ "@hachej/boring-ui-kit@^0.2.5",
2481
+ "@hachej/boring-files@^0.2.5",
2321
2482
  "react@^19.0.0",
2322
2483
  "radix-ui@^1.8.0",
2323
2484
  "lucide-react@^1.51.0"
2324
2485
  ],
2325
2486
  "registryDependencies": [
2326
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json"
2487
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json"
2327
2488
  ],
2328
2489
  "files": [
2329
2490
  {
@@ -4,8 +4,8 @@
4
4
  "title": "Consumer task-list viewer",
5
5
  "description": "A consumer-defined task-list schema and controller over the shared text buffer, with a restylable borrowed React renderer.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.2.3",
8
- "@hachej/boring-files@^0.2.3",
7
+ "@hachej/boring-ui-kit@^0.2.5",
8
+ "@hachej/boring-files@^0.2.5",
9
9
  "react@^19.0.0",
10
10
  "react-dom@^19.0.0",
11
11
  "zod@^4.6.5"
package/r/utils.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "files": [
11
11
  {
12
12
  "path": "registry/utils/utils.ts",
13
- "content": "import { clsx } from 'clsx';\nimport type { ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string { return twMerge(clsx(inputs)); }\n\n/** Thrown when no automatic copy worked; `text` is what the person must copy by hand (a viewer shows it selected). */\nexport class ManualCopyError extends Error {\n constructor(readonly text: string) { super('Copy the text by hand'); this.name = 'ManualCopyError'; }\n}\n\n/**\n * Copies `text` using the host's callback when given, else the async Clipboard API (secure contexts only), else a hidden\n * textarea and `document.execCommand('copy')` (works over plain HTTP). Throws `ManualCopyError` when none worked.\n * This is the one place this item touches the clipboard; `npm run check` keeps it that way.\n */\nexport async function copyText(text: string, onCopy?: (text: string) => Promise<void>): Promise<void> {\n if (onCopy) return onCopy(text);\n try { const clipboard = globalThis.navigator?.clipboard; if (clipboard) { await clipboard.writeText(text); return; } }\n catch { /* denied or unfocused: use the selection route */ }\n const doc = globalThis.document;\n if (doc?.body && typeof doc.execCommand === 'function') {\n const area = doc.createElement('textarea');\n area.value = text;\n area.setAttribute('readonly', '');\n area.style.cssText = 'position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none';\n const focus = doc.activeElement instanceof HTMLElement ? doc.activeElement : undefined;\n doc.body.append(area);\n try { area.select(); area.setSelectionRange(0, text.length); if (doc.execCommand('copy')) return; }\n catch { /* fall through */ }\n finally { area.remove(); focus?.focus({ preventScroll: true }); }\n }\n throw new ManualCopyError(text);\n}\n\n/**\n * A block's `labels` or `icons`: `defaults` with each partial override on top, later ones winning. A key an override leaves `undefined`\n * keeps the value below it, so a host can pass `{ title: maybe }` safely.\n */\nexport function withDefaults<T extends object>(defaults: T, ...overrides: readonly (Partial<T> | undefined)[]): T {\n const merged: Record<string, unknown> = { ...defaults as Record<string, unknown> };\n for (const override of overrides) for (const [key, value] of Object.entries(override ?? {})) if (value !== undefined) merged[key] = value;\n return merged as T;\n}\n",
13
+ "content": "import { clsx } from 'clsx';\nimport type { ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string { return twMerge(clsx(inputs)); }\n\n/** Thrown when no automatic copy worked; `text` is what the person must copy by hand (a viewer shows it selected). */\nexport class ManualCopyError extends Error {\n readonly text: string;\n constructor(text: string) { super('Copy the text by hand'); this.name = 'ManualCopyError'; this.text = text; }\n}\n\n/**\n * Copies `text` using the host's callback when given, else the async Clipboard API (secure contexts only), else a hidden\n * textarea and `document.execCommand('copy')` (works over plain HTTP). Throws `ManualCopyError` when none worked.\n * This is the one place this item touches the clipboard; `npm run check` keeps it that way.\n */\nexport async function copyText(text: string, onCopy?: (text: string) => Promise<void>): Promise<void> {\n if (onCopy) return onCopy(text);\n try { const clipboard = globalThis.navigator?.clipboard; if (clipboard) { await clipboard.writeText(text); return; } }\n catch { /* denied or unfocused: use the selection route */ }\n const doc = globalThis.document;\n if (doc?.body && typeof doc.execCommand === 'function') {\n const area = doc.createElement('textarea');\n area.value = text;\n area.setAttribute('readonly', '');\n area.style.cssText = 'position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none';\n const focus = doc.activeElement instanceof HTMLElement ? doc.activeElement : undefined;\n doc.body.append(area);\n try { area.select(); area.setSelectionRange(0, text.length); if (doc.execCommand('copy')) return; }\n catch { /* fall through */ }\n finally { area.remove(); focus?.focus({ preventScroll: true }); }\n }\n throw new ManualCopyError(text);\n}\n\n/**\n * A block's `labels` or `icons`: `defaults` with each partial override on top, later ones winning. A key an override leaves `undefined`\n * keeps the value below it, so a host can pass `{ title: maybe }` safely.\n */\nexport function withDefaults<T extends object>(defaults: T, ...overrides: readonly (Partial<T> | undefined)[]): T {\n const merged: Record<string, unknown> = { ...defaults as Record<string, unknown> };\n for (const override of overrides) for (const [key, value] of Object.entries(override ?? {})) if (value !== undefined) merged[key] = value;\n return merged as T;\n}\n",
14
14
  "type": "registry:lib",
15
15
  "target": "components/utils/utils.ts"
16
16
  }
package/r/viewers.json CHANGED
@@ -4,8 +4,8 @@
4
4
  "title": "Viewers",
5
5
  "description": "The standard viewer top bar (title, status, viewer controls, Refresh, Share, Copy, Download, Open in new tab, Close, overflow menu) with Tailwind panes over it: the Markdown editor with a formatting toolbar and prose styling, the passive HTML preview and source editor, an image viewer with zoom and pan, and a PDF viewer. Owned, editable source over the borrowed controllers; no AI SDK.",
6
6
  "dependencies": [
7
- "@hachej/boring-ui-kit@^0.2.3",
8
- "@hachej/boring-files@^0.2.3",
7
+ "@hachej/boring-ui-kit@^0.2.5",
8
+ "@hachej/boring-files@^0.2.5",
9
9
  "react@^19.0.0",
10
10
  "react-dom@^19.0.0",
11
11
  "marked@^17.0.6",
@@ -24,9 +24,9 @@
24
24
  "lucide-react@^1.51.0"
25
25
  ],
26
26
  "registryDependencies": [
27
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/theme.json",
28
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/utils.json",
29
- "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.3/r/button.json"
27
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/theme.json",
28
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/utils.json",
29
+ "https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.2.5/r/button.json"
30
30
  ],
31
31
  "files": [
32
32
  {