@hachej/boring-ui-kit 0.4.44 → 0.4.45
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/package.json +2 -2
- package/r/agent-target.json +4 -4
- package/r/app-shell.json +10 -10
- package/r/board-viewer.json +6 -6
- package/r/button.json +1 -1
- package/r/dock.json +1 -1
- package/r/documents.json +12 -12
- package/r/feedback-preview.json +1 -1
- package/r/feedback.json +6 -6
- package/r/file-tree.json +4 -4
- package/r/highlights.json +3 -3
- package/r/html-viewer.json +3 -3
- package/r/looks-viewer.json +2 -2
- package/r/maquette-viewer.json +1 -1
- package/r/markdown-editor.json +3 -3
- package/r/mockup-viewer.json +1 -1
- package/r/pi-ambient.json +8 -8
- package/r/pi-app-kinds.json +10 -10
- package/r/pi-app.json +10 -10
- package/r/pi-artifacts.json +2 -2
- package/r/pi-chat-approval.json +2 -2
- package/r/pi-chat-attachments.json +1 -1
- package/r/pi-chat-markdown.json +2 -2
- package/r/pi-chat-mentions.json +1 -1
- package/r/pi-chat-pickers.json +1 -1
- package/r/pi-chat-plugins.json +11 -11
- package/r/pi-chat-question.json +1 -1
- package/r/pi-chat-slash.json +2 -2
- package/r/pi-chat-subagent.json +1 -1
- package/r/pi-chat-voice.json +3 -3
- package/r/pi-chat.json +5 -5
- package/r/pi-workspace.json +3 -3
- package/r/placed-agent.json +4 -4
- package/r/pm-panel.json +16 -16
- package/r/provider-setup.json +1 -1
- package/r/registry.json +185 -185
- package/r/requests-board.json +1 -1
- package/r/shared-chat.json +6 -6
- package/r/task-board.json +2 -2
- package/r/task-list-viewer.json +2 -2
- package/r/task-mentions.json +4 -4
- package/r/version-history.json +2 -2
- package/r/viewer-code.json +2 -2
- package/r/viewer-frame.json +4 -4
- package/r/viewer-html.json +4 -4
- package/r/viewer-image.json +2 -2
- package/r/viewer-markdown.json +5 -5
- package/r/viewer-pdf.json +3 -3
- package/r/viewers.json +6 -6
- package/r/windows.json +1 -1
package/r/placed-agent.json
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"lucide-react@^1.51.0"
|
|
10
10
|
],
|
|
11
11
|
"registryDependencies": [
|
|
12
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
13
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
14
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
15
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
12
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-app.json",
|
|
13
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-ambient.json",
|
|
14
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/app-shell.json",
|
|
15
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/utils.json"
|
|
16
16
|
],
|
|
17
17
|
"files": [
|
|
18
18
|
{
|
package/r/pm-panel.json
CHANGED
|
@@ -4,27 +4,27 @@
|
|
|
4
4
|
"title": "Shared PM composer and in-app panel",
|
|
5
5
|
"description": "« Améliorer l'app »: the embedded AgentWorkspace chat, History, read-only Library and host Tasks panel, with the shared pointing strip, numbered pins and timestamped chips. Docked beside the app on desktop and full screen on phones; PmChat gives Studio the same component.",
|
|
6
6
|
"dependencies": [
|
|
7
|
-
"@hachej/boring-ui-kit@^0.4.
|
|
8
|
-
"@hachej/boring-feedback@^0.4.
|
|
9
|
-
"@hachej/boring-files@^0.4.
|
|
7
|
+
"@hachej/boring-ui-kit@^0.4.45",
|
|
8
|
+
"@hachej/boring-feedback@^0.4.45",
|
|
9
|
+
"@hachej/boring-files@^0.4.45",
|
|
10
10
|
"@earendil-works/pi-durable@~1.4.0",
|
|
11
11
|
"lucide-react@^1.51.0",
|
|
12
12
|
"react@^19.0.0",
|
|
13
13
|
"react-dom@^19.0.0"
|
|
14
14
|
],
|
|
15
15
|
"registryDependencies": [
|
|
16
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
17
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
18
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
19
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
20
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
21
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
22
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
23
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
24
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
25
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
26
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
27
|
-
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.
|
|
16
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-app.json",
|
|
17
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-app-kinds.json",
|
|
18
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-chat.json",
|
|
19
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-chat-markdown.json",
|
|
20
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-chat-plugins.json",
|
|
21
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-chat-voice.json",
|
|
22
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/feedback.json",
|
|
23
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/task-board.json",
|
|
24
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/task-mentions.json",
|
|
25
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/utils.json",
|
|
26
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/pi-artifacts.json",
|
|
27
|
+
"https://cdn.jsdelivr.net/npm/@hachej/boring-ui-kit@0.4.45/r/viewer-frame.json"
|
|
28
28
|
],
|
|
29
29
|
"files": [
|
|
30
30
|
{
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"path": "registry/pm-panel/point-frames.ts",
|
|
62
|
-
"content": "'use client';\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { usePointPage } from './use-point-page';\nimport type { PointPick, PointPin } from './use-point-page';\nimport type { PrivacyPolicy } from '@hachej/boring-feedback/page';\nimport type { PmText } from './pm-text';\n\n// Pointing across two sibling frames of one host page: the PM in one (`?pm=standalone`), the app in the other, both on the app's origin\n// with the person's session. Delivery is `postMessage` restricted to this origin; a receiver also requires a sibling source, which keeps\n// one person's two tabs apart, and the same app name. The parent page, whatever its origin, reads and sends nothing here.\nconst CHANNEL = 'boring-pm-point';\ntype ToApp = { readonly type: 'probe' } | { readonly type: 'state'; readonly picking: boolean; readonly pins: readonly PointPin[] };\ntype ToPm = { readonly type: 'here' } | { readonly type: 'pick'; readonly pick: PointPick } | { readonly type: 'unpick'; readonly id: string } | { readonly type: 'problem'; readonly message: string } | { readonly type: 'done' };\n\nfunction siblings(): readonly Window[] {\n if (window.parent === window) return [];\n const frames = window.parent.frames, found: Window[] = [];\n for (let index = 0; index < frames.length; index++) { const frame = frames[index]; if (frame && frame !== window) found.push(frame); }\n return found;\n}\n/** To the page holding the frames: no content, only that pointing started, stopped or landed. A phone shows one frame at a time and switches on this. */\nfunction tellHost(boring: 'pm-pointing' | 'pm-picked', picking?: boolean): void {\n const parent =
|
|
62
|
+
"content": "'use client';\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { usePointPage } from './use-point-page';\nimport type { PointPick, PointPin } from './use-point-page';\nimport type { PrivacyPolicy } from '@hachej/boring-feedback/page';\nimport type { PmText } from './pm-text';\n\n// Pointing across two sibling frames of one host page: the PM in one (`?pm=standalone`), the app in the other, both on the app's origin\n// with the person's session. Delivery is `postMessage` restricted to this origin; a receiver also requires a sibling source, which keeps\n// one person's two tabs apart, and the same app name. The parent page, whatever its origin, reads and sends nothing here.\nconst CHANNEL = 'boring-pm-point';\ntype ToApp = { readonly type: 'probe' } | { readonly type: 'state'; readonly picking: boolean; readonly pins: readonly PointPin[] };\ntype ToPm = { readonly type: 'here' } | { readonly type: 'pick'; readonly pick: PointPick } | { readonly type: 'unpick'; readonly id: string } | { readonly type: 'problem'; readonly message: string } | { readonly type: 'done' };\n\nfunction siblings(): readonly Window[] {\n if (window.parent === window) return [];\n const frames = window.parent.frames, found: Window[] = [];\n for (let index = 0; index < frames.length; index++) { const frame = frames[index]; if (frame && frame !== window) found.push(frame); }\n return found;\n}\nconst hostOrigin = () => window.location.ancestorOrigins?.[0] ?? (document.referrer ? new URL(document.referrer).origin : undefined);\n/** To the page holding the frames: no content, only that pointing started, stopped or landed. A phone shows one frame at a time and switches on this. */\nfunction tellHost(boring: 'pm-pointing' | 'pm-picked', picking?: boolean): void {\n const parent = hostOrigin();\n if (parent) window.parent.postMessage({ boring, ...(picking === undefined ? {} : { picking }) }, parent);\n}\nconst post = (target: Window, app: string, message: ToApp | ToPm) => target.postMessage({ channel: CHANNEL, app, message }, window.location.origin);\nfunction received<T>(event: MessageEvent, app: string): { readonly message: T; readonly source: Window } | undefined {\n const source = event.source as Window | null;\n if (event.origin !== window.location.origin || !source || source === window || window.parent === window || source.parent !== window.parent) return undefined;\n const data = event.data as { channel?: unknown; app?: unknown; message?: T } | null;\n return data?.channel === CHANNEL && data.app === app && data.message ? { message: data.message, source } : undefined;\n}\n\ninterface PmSide {\n readonly enabled: boolean;\n readonly app: string;\n readonly picking: boolean;\n readonly pins: readonly PointPin[];\n readonly onPick: (pick: PointPick) => void;\n readonly onUnpick: (id: string) => void;\n readonly onProblem: (message: string) => void;\n readonly onDone: () => void;\n}\n\n/** In the PM frame: tells the sibling app frame what to do, takes its picks. The result says an app frame answered. */\nexport function useAppFrame({ enabled, app, picking, pins, onPick, onUnpick, onProblem, onDone }: PmSide): boolean {\n const [frame, setFrame] = useState<Window>();\n const latest = useRef({ picking, pins, onPick, onUnpick, onProblem, onDone });\n useLayoutEffect(() => { latest.current = { picking, pins, onPick, onUnpick, onProblem, onDone }; });\n useEffect(() => {\n if (!enabled) return;\n const listen = (event: MessageEvent) => {\n // A host showing one frame at a time ends pointing once it comes back: « touch what you want » would point at nothing.\n if (event.source === window.parent && event.origin === hostOrigin() && (event.data as { boring?: unknown } | null)?.boring === 'pm-end-pointing') { latest.current.onDone(); return; }\n const got = received<ToPm>(event, app);\n if (!got) return;\n const { message, source } = got, current = latest.current;\n setFrame(source);\n if (message.type === 'here') post(source, app, { type: 'state', picking: current.picking, pins: current.pins });\n else if (message.type === 'pick') { current.onPick(message.pick); tellHost('pm-picked'); }\n else if (message.type === 'unpick') current.onUnpick(message.id);\n else if (message.type === 'problem') current.onProblem(message.message);\n else if (message.type === 'done') current.onDone();\n };\n window.addEventListener('message', listen);\n for (const sibling of siblings()) post(sibling, app, { type: 'probe' });\n return () => window.removeEventListener('message', listen);\n }, [enabled, app]);\n useEffect(() => { if (enabled && frame) post(frame, app, { type: 'state', picking, pins }); }, [enabled, frame, app, picking, pins]);\n useEffect(() => { if (enabled && window.parent !== window) tellHost('pm-pointing', picking); }, [enabled, picking]);\n useEffect(() => {\n if (!enabled || !frame) return;\n const release = () => post(frame, app, { type: 'state', picking: false, pins: [] });\n window.addEventListener('pagehide', release);\n return () => { window.removeEventListener('pagehide', release); release(); };\n }, [enabled, frame, app]);\n return Boolean(frame);\n}\n\nconst noPins: readonly PointPin[] = [];\n\n/** In the app frame: only the page half runs here, for the PM of a sibling frame. `onStart`: it began pointing, this frame's own PM steps aside. */\nexport function useSiblingPointing({ app, page, screen, policy, text, onStart }: { readonly app: string; readonly page: HTMLElement | null; readonly screen: string; readonly policy: PrivacyPolicy; readonly text: PmText; readonly onStart: () => void }): void {\n const [session, setSession] = useState<{ readonly source: Window; readonly picking: boolean; readonly pins: readonly PointPin[] }>();\n const starting = useRef(onStart);\n useLayoutEffect(() => { starting.current = onStart; });\n useEffect(() => {\n const listen = (event: MessageEvent) => {\n const got = received<ToApp>(event, app);\n if (!got) return;\n const { message, source } = got;\n if (message.type === 'probe') { post(source, app, { type: 'here' }); return; }\n if (message.picking) starting.current();\n setSession({ source, picking: message.picking, pins: message.pins });\n };\n window.addEventListener('message', listen);\n for (const sibling of siblings()) post(sibling, app, { type: 'here' });\n return () => window.removeEventListener('message', listen);\n }, [app]);\n const source = session?.source, picking = session?.picking ?? false;\n useEffect(() => {\n if (!source || !picking) return;\n // A removed PM frame may never get to say so: the page must not stay stuck picking.\n const timer = setInterval(() => { if (source.closed) setSession(undefined); }, 2000);\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape' && !event.isComposing) post(source, app, { type: 'done' }); };\n window.addEventListener('keydown', onKey);\n return () => { clearInterval(timer); window.removeEventListener('keydown', onKey); };\n }, [source, picking, app]);\n const send = (message: ToPm) => { if (source) post(source, app, message); };\n usePointPage({ picking, pins: session?.pins ?? noPins, page, screen, policy, text,\n onPick: pick => send({ type: 'pick', pick }), onUnpick: id => send({ type: 'unpick', id }), onProblem: message => send({ type: 'problem', message }) });\n}\n",
|
|
63
63
|
"type": "registry:hook",
|
|
64
64
|
"target": "components/pm-panel/point-frames.ts"
|
|
65
65
|
},
|
package/r/provider-setup.json
CHANGED