@opengeni/react 1.4.2 → 1.4.5-canary.37458084490001
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/README.md +17 -6
- package/dist/artifacts.d.ts +1 -0
- package/dist/artifacts.js +22 -15
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-WGJ43YGI.js → browser-viewer-CV23VIHB.js} +8 -6
- package/dist/chunk-3ZC6QPOM.js +174 -0
- package/dist/chunk-3ZC6QPOM.js.map +1 -0
- package/dist/{chunk-YVFRBXST.js → chunk-4BCVCJSU.js} +2 -2
- package/dist/{chunk-JHTIMBOL.js → chunk-5JSUNNQN.js} +26 -4
- package/dist/{chunk-JHTIMBOL.js.map → chunk-5JSUNNQN.js.map} +1 -1
- package/dist/{chunk-MDIXFKA3.js → chunk-6FOTSVWU.js} +303 -109
- package/dist/chunk-6FOTSVWU.js.map +1 -0
- package/dist/{chunk-IUHHPMAX.js → chunk-7RRBX5EM.js} +14 -85
- package/dist/chunk-7RRBX5EM.js.map +1 -0
- package/dist/{chunk-L2J3PU7A.js → chunk-7ZB7I3KP.js} +24 -98
- package/dist/chunk-7ZB7I3KP.js.map +1 -0
- package/dist/{chunk-LVS3MH5T.js → chunk-ATIRUHBZ.js} +128 -10
- package/dist/chunk-ATIRUHBZ.js.map +1 -0
- package/dist/chunk-BOFEQC6K.js +162 -0
- package/dist/chunk-BOFEQC6K.js.map +1 -0
- package/dist/{chunk-VCSERYXH.js → chunk-CESBPQP5.js} +309 -162
- package/dist/chunk-CESBPQP5.js.map +1 -0
- package/dist/{chunk-IYQCWGU5.js → chunk-GHJU7XG7.js} +35 -62
- package/dist/chunk-GHJU7XG7.js.map +1 -0
- package/dist/{chunk-G6YRCIYJ.js → chunk-HNVWMDNN.js} +55 -60
- package/dist/chunk-HNVWMDNN.js.map +1 -0
- package/dist/{chunk-PHBFJCEU.js → chunk-I5EGRXXG.js} +110 -7
- package/dist/chunk-I5EGRXXG.js.map +1 -0
- package/dist/{chunk-PBCZL4JP.js → chunk-INIZSNXT.js} +2 -2
- package/dist/{chunk-XS67YG5R.js → chunk-IX3K4THH.js} +24 -3
- package/dist/chunk-IX3K4THH.js.map +1 -0
- package/dist/chunk-IZV5FTJC.js +55 -0
- package/dist/chunk-IZV5FTJC.js.map +1 -0
- package/dist/chunk-JDJJMBB3.js +1883 -0
- package/dist/chunk-JDJJMBB3.js.map +1 -0
- package/dist/{chunk-C5BF4L26.js → chunk-KHF2VRXF.js} +7 -7
- package/dist/{chunk-QMMCJGFI.js → chunk-L5OKM2VX.js} +2 -2
- package/dist/chunk-LHF6BVM4.js +83 -0
- package/dist/chunk-LHF6BVM4.js.map +1 -0
- package/dist/chunk-N7S72EXK.js +25 -0
- package/dist/chunk-N7S72EXK.js.map +1 -0
- package/dist/{chunk-CVYCLFMH.js → chunk-PEHTX3V7.js} +19 -1
- package/dist/chunk-PEHTX3V7.js.map +1 -0
- package/dist/chunk-R5R5RQQD.js +51 -0
- package/dist/chunk-R5R5RQQD.js.map +1 -0
- package/dist/chunk-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.js.map +1 -0
- package/dist/{chunk-JH7V627O.js → chunk-SHLZMAJN.js} +2 -11
- package/dist/chunk-SHLZMAJN.js.map +1 -0
- package/dist/{chunk-CREMJMVN.js → chunk-TZQSHCZN.js} +692 -1996
- package/dist/chunk-TZQSHCZN.js.map +1 -0
- package/dist/chunk-ZIB4H5LN.js +101 -0
- package/dist/chunk-ZIB4H5LN.js.map +1 -0
- package/dist/client.d.ts +9 -3
- package/dist/clipboard.js +1 -1
- package/dist/components/browser-viewer.d.ts +6 -0
- package/dist/components/composer.d.ts +3 -69
- package/dist/components/human-input-form.d.ts +3 -32
- package/dist/components/markdown.d.ts +8 -0
- package/dist/components/model-policy-picker.d.ts +4 -37
- package/dist/components/opper-mark.d.ts +7 -0
- package/dist/components/provider-recovery-notice.d.ts +15 -0
- package/dist/components/remark-soft-line-breaks.d.ts +38 -0
- package/dist/components/sandbox-workspace.d.ts +13 -0
- package/dist/components/session-chrome.d.ts +5 -3
- package/dist/components/session-conversation.d.ts +15 -3
- package/dist/composer-messages.d.ts +74 -0
- package/dist/composer-messages.js +9 -0
- package/dist/composer.js +15 -10
- package/dist/{computer-viewer-46UIN7F3.js → computer-viewer-K4CKYRX6.js} +4 -4
- package/dist/connect-setup.d.ts +2 -0
- package/dist/connect.d.ts +1 -1
- package/dist/connect.js +21 -6
- package/dist/connect.js.map +1 -1
- package/dist/{embedded-voice-NIL4RDX3.js → embedded-voice-3ZFWWJ6O.js} +6 -4
- package/dist/{embedded-voice-NIL4RDX3.js.map → embedded-voice-3ZFWWJ6O.js.map} +1 -1
- package/dist/hooks/shared-machines-list.d.ts +4 -0
- package/dist/hooks/use-client-config-flags.d.ts +6 -0
- package/dist/hooks/use-computer-session.d.ts +2 -0
- package/dist/hooks/use-goal.d.ts +2 -1
- package/dist/human-input-model.d.ts +40 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +116 -73
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +5 -5
- package/dist/{latest-question-2POFPYNB.js → latest-question-SWC6QEVN.js} +3 -3
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/provider-recovery.d.ts +49 -0
- package/dist/machines.js +2 -2
- package/dist/model-mark-paths.d.ts +34 -0
- package/dist/model-mark-paths.js +16 -0
- package/dist/model-picker-model.d.ts +111 -0
- package/dist/model-picker-model.js +25 -0
- package/dist/model-picker-model.js.map +1 -0
- package/dist/{model-policy-picker-menu-WRNSRFQC.js → model-policy-picker-menu-NM4RPTY6.js} +6 -4
- package/dist/model-policy-picker-menu-NM4RPTY6.js.map +1 -0
- package/dist/model-policy.d.ts +10 -0
- package/dist/model-policy.js +5 -1
- package/dist/organization-model.d.ts +32 -0
- package/dist/organization-model.js +65 -0
- package/dist/organization-model.js.map +1 -0
- package/dist/{platform-activity-row-PJJVATTZ.js → platform-activity-row-NJ47YBXW.js} +7 -84
- package/dist/platform-activity-row-NJ47YBXW.js.map +1 -0
- package/dist/queue-presentation-model.d.ts +72 -0
- package/dist/queue-presentation-model.js +38 -0
- package/dist/queue-presentation-model.js.map +1 -0
- package/dist/{queue-surface-implementation-67FS7FUI.js → queue-surface-implementation-YPJFQ3O6.js} +24 -252
- package/dist/queue-surface-implementation-YPJFQ3O6.js.map +1 -0
- package/dist/realtime.js +5 -3
- package/dist/{sandbox-files-34CJJNOY.js → sandbox-files-RCVCMXG7.js} +5 -5
- package/dist/sandbox-files-RCVCMXG7.js.map +1 -0
- package/dist/sandbox-label-model.d.ts +23 -0
- package/dist/sandbox-label-model.js +28 -0
- package/dist/sandbox-label-model.js.map +1 -0
- package/dist/session-attention-model.d.ts +8 -0
- package/dist/session-attention-model.js +46 -0
- package/dist/session-attention-model.js.map +1 -0
- package/dist/session-feedback-model.d.ts +20 -0
- package/dist/session-feedback-model.js +56 -0
- package/dist/session-feedback-model.js.map +1 -0
- package/dist/session-list-model.d.ts +96 -0
- package/dist/session-list-model.js +219 -0
- package/dist/session-list-model.js.map +1 -0
- package/dist/session-status-model.d.ts +19 -0
- package/dist/session-ui.js +26 -17
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +8 -6
- package/dist/testing/session-scenarios.d.ts +10 -0
- package/dist/testing/session-scenarios.js +303 -0
- package/dist/testing/session-scenarios.js.map +1 -0
- package/dist/timeline/genie-copy.d.ts +3 -0
- package/dist/timeline/genie-loading.d.ts +11 -0
- package/dist/timeline/index.d.ts +1 -1
- package/dist/timeline/notice-presentation.d.ts +7 -0
- package/dist/timeline/patch-apply-command.d.ts +18 -0
- package/dist/timeline/platform-activity-presentation.d.ts +7 -0
- package/dist/timeline/presented-image.d.ts +6 -1
- package/dist/timeline/question-nav-model.d.ts +23 -0
- package/dist/timeline/registry.d.ts +10 -1
- package/dist/timeline/retained-loaders.d.ts +1 -1
- package/dist/timeline/tool-presentation.d.ts +172 -0
- package/dist/timeline/turn-summary-model.d.ts +90 -0
- package/dist/timeline/turn-summary.d.ts +4 -74
- package/dist/timeline/work-presentation.d.ts +42 -0
- package/dist/timeline-model.d.ts +24 -0
- package/dist/timeline-model.js +152 -0
- package/dist/timeline-model.js.map +1 -0
- package/package.json +47 -3
- package/src/artifacts.ts +1 -0
- package/src/client.ts +9 -3
- package/src/components/browser-viewer.tsx +23 -2
- package/src/components/claude-mark.tsx +2 -1
- package/src/components/composer.tsx +4 -144
- package/src/components/computer-viewer.tsx +139 -30
- package/src/components/grok-mark.tsx +2 -1
- package/src/components/human-input-form.tsx +13 -124
- package/src/components/markdown.tsx +19 -1
- package/src/components/message-timeline.tsx +45 -99
- package/src/components/model-mark.tsx +2 -1
- package/src/components/model-policy-picker-menu.tsx +30 -85
- package/src/components/model-policy-picker.tsx +15 -148
- package/src/components/opper-mark.tsx +18 -0
- package/src/components/provider-recovery-notice.tsx +41 -0
- package/src/components/queue-surface-implementation.tsx +20 -349
- package/src/components/remark-soft-line-breaks.ts +166 -0
- package/src/components/sandbox-workspace.tsx +17 -1
- package/src/components/session-chrome.tsx +114 -99
- package/src/components/session-conversation.tsx +55 -6
- package/src/components/session-list.tsx +1 -1
- package/src/components/session-status.tsx +17 -16
- package/src/composer-messages.ts +150 -0
- package/src/connect-setup.tsx +45 -11
- package/src/connect.ts +1 -1
- package/src/hooks/shared-machines-list.ts +34 -1
- package/src/hooks/use-browser-session.ts +445 -168
- package/src/hooks/use-client-config-flags.ts +8 -0
- package/src/hooks/use-computer-session.ts +334 -98
- package/src/hooks/use-goal.ts +66 -10
- package/src/human-input-model.ts +147 -0
- package/src/index.ts +16 -0
- package/src/lib/clipboard.ts +29 -0
- package/src/lib/format.ts +7 -0
- package/src/lib/provider-recovery.ts +202 -0
- package/src/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +43 -2
- package/src/organization-model.ts +118 -0
- package/src/queue-presentation-model.ts +464 -0
- package/src/sandbox-label-model.ts +41 -0
- package/src/session-attention-model.ts +59 -0
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +327 -0
- package/src/session-status-model.ts +62 -0
- package/src/testing/session-scenarios.ts +326 -0
- package/src/timeline/activity-rail.tsx +5 -17
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +13 -18
- package/src/timeline/index.ts +1 -0
- package/src/timeline/notice-presentation.ts +22 -0
- package/src/timeline/patch-apply-command.tsx +135 -0
- package/src/timeline/platform-activity-presentation.ts +122 -0
- package/src/timeline/platform-activity-row.tsx +6 -96
- package/src/timeline/presented-image.ts +16 -2
- package/src/timeline/question-nav-model.ts +28 -0
- package/src/timeline/registry.ts +11 -1
- package/src/timeline/retained-loaders.ts +9 -4
- package/src/timeline/rolling-activity.tsx +7 -19
- package/src/timeline/tool-presentation.ts +1316 -0
- package/src/timeline/tool-renderers.tsx +226 -1025
- package/src/timeline/turn-summary-model.ts +338 -0
- package/src/timeline/turn-summary.tsx +21 -326
- package/src/timeline/work-presentation.ts +139 -0
- package/src/timeline-model.ts +108 -0
- package/styles/compiled.css +8 -0
- package/styles/connect.css +4 -0
- package/dist/chunk-CREMJMVN.js.map +0 -1
- package/dist/chunk-CVYCLFMH.js.map +0 -1
- package/dist/chunk-G6YRCIYJ.js.map +0 -1
- package/dist/chunk-HXYOSSQO.js +0 -117
- package/dist/chunk-HXYOSSQO.js.map +0 -1
- package/dist/chunk-IUHHPMAX.js.map +0 -1
- package/dist/chunk-IYQCWGU5.js.map +0 -1
- package/dist/chunk-JH7V627O.js.map +0 -1
- package/dist/chunk-L2J3PU7A.js.map +0 -1
- package/dist/chunk-LVS3MH5T.js.map +0 -1
- package/dist/chunk-MDIXFKA3.js.map +0 -1
- package/dist/chunk-PHBFJCEU.js.map +0 -1
- package/dist/chunk-VCSERYXH.js.map +0 -1
- package/dist/chunk-XS67YG5R.js.map +0 -1
- package/dist/platform-activity-row-PJJVATTZ.js.map +0 -1
- package/dist/queue-surface-implementation-67FS7FUI.js.map +0 -1
- /package/dist/{browser-viewer-WGJ43YGI.js.map → browser-viewer-CV23VIHB.js.map} +0 -0
- /package/dist/{chunk-YVFRBXST.js.map → chunk-4BCVCJSU.js.map} +0 -0
- /package/dist/{chunk-PBCZL4JP.js.map → chunk-INIZSNXT.js.map} +0 -0
- /package/dist/{chunk-C5BF4L26.js.map → chunk-KHF2VRXF.js.map} +0 -0
- /package/dist/{chunk-QMMCJGFI.js.map → chunk-L5OKM2VX.js.map} +0 -0
- /package/dist/{computer-viewer-46UIN7F3.js.map → composer-messages.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-WRNSRFQC.js.map → computer-viewer-K4CKYRX6.js.map} +0 -0
- /package/dist/{latest-question-2POFPYNB.js.map → latest-question-SWC6QEVN.js.map} +0 -0
- /package/dist/{sandbox-files-34CJJNOY.js.map → model-mark-paths.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/clipboard.ts"],"sourcesContent":["/**\n * Copy plain text to the clipboard. Prefers the async Clipboard API; falls\n * back to a short-lived textarea for older embeds / denied permissions.\n */\nexport async function copyTextToClipboard(text: string): Promise<boolean> {\n const value = text.replace(/\\u00a0/g, \" \");\n if (value.length === 0) {\n return false;\n }\n try {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value);\n return true;\n }\n } catch {\n // Fall through to execCommand path.\n }\n if (typeof document === \"undefined\") {\n return false;\n }\n try {\n const area = document.createElement(\"textarea\");\n area.value = value;\n area.setAttribute(\"readonly\", \"\");\n area.style.position = \"fixed\";\n area.style.left = \"-9999px\";\n area.style.top = \"0\";\n document.body.appendChild(area);\n area.select();\n const ok = document.execCommand(\"copy\");\n document.body.removeChild(area);\n return ok;\n } catch {\n return false;\n }\n}\n\n/**\n * Copy text that is still being prepared, such as a command around a freshly\n * minted URL. Safari only allows a clipboard write during the click itself, so\n * hand the pending text to a `ClipboardItem` where supported; otherwise wait\n * for it and copy. Resolves false when the text failed or nothing was copied.\n */\nexport async function copyPendingTextToClipboard(text: Promise<string>): Promise<boolean> {\n if (\n typeof ClipboardItem !== \"undefined\" &&\n typeof navigator !== \"undefined\" &&\n typeof navigator.clipboard?.write === \"function\"\n ) {\n const blob = text.then((value) => new Blob([value], { type: \"text/plain\" }));\n // The caller observes a failed `text`; never leave this copy unhandled.\n blob.catch(() => {});\n try {\n await navigator.clipboard.write([new ClipboardItem({ \"text/plain\": blob })]);\n return true;\n } catch {\n // Fall through: some browsers reject promised clipboard items.\n }\n }\n try {\n return await copyTextToClipboard(await text);\n } catch {\n return false;\n }\n}\n\n/** Serialize an HTML table to tab-separated values (spreadsheet-friendly). */\nexport function tableElementToTsv(table: HTMLTableElement | null | undefined): string {\n if (!table) {\n return \"\";\n }\n const rows = Array.from(table.querySelectorAll(\"tr\"));\n return rows\n .map((row) =>\n Array.from(row.querySelectorAll(\"th,td\"))\n .map((cell) => {\n const raw = (cell.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (/[\\t\\n\"]/.test(raw)) {\n return `\"${raw.replace(/\"/g, '\"\"')}\"`;\n }\n return raw;\n })\n .join(\"\\t\"),\n )\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n"],"mappings":";;;AAIA,eAAsB,oBAAoB,MAAgC;AACxE,QAAM,QAAQ,KAAK,QAAQ,WAAW,GAAG;AACzC,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,MAAI;AACF,QAAI,OAAO,cAAc,eAAe,UAAU,WAAW,WAAW;AACtE,YAAM,UAAU,UAAU,UAAU,KAAK;AACzC,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AACA,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,OAAO,SAAS,cAAc,UAAU;AAC9C,SAAK,QAAQ;AACb,SAAK,aAAa,YAAY,EAAE;AAChC,SAAK,MAAM,WAAW;AACtB,SAAK,MAAM,OAAO;AAClB,SAAK,MAAM,MAAM;AACjB,aAAS,KAAK,YAAY,IAAI;AAC9B,SAAK,OAAO;AACZ,UAAM,KAAK,SAAS,YAAY,MAAM;AACtC,aAAS,KAAK,YAAY,IAAI;AAC9B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,2BAA2B,MAAyC;AACxF,MACE,OAAO,kBAAkB,eACzB,OAAO,cAAc,eACrB,OAAO,UAAU,WAAW,UAAU,YACtC;AACA,UAAM,OAAO,KAAK,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,MAAM,aAAa,CAAC,CAAC;AAE3E,SAAK,MAAM,MAAM;AAAA,IAAC,CAAC;AACnB,QAAI;AACF,YAAM,UAAU,UAAU,MAAM,CAAC,IAAI,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC;AAC3E,aAAO;AAAA,IACT,QAAQ;AAAA,IAER;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,oBAAoB,MAAM,IAAI;AAAA,EAC7C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,kBAAkB,OAAoD;AACpF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,OAAO,MAAM,KAAK,MAAM,iBAAiB,IAAI,CAAC;AACpD,SAAO,KACJ;AAAA,IAAI,CAAC,QACJ,MAAM,KAAK,IAAI,iBAAiB,OAAO,CAAC,EACrC,IAAI,CAAC,SAAS;AACb,YAAM,OAAO,KAAK,eAAe,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/D,UAAI,UAAU,KAAK,GAAG,GAAG;AACvB,eAAO,IAAI,IAAI,QAAQ,MAAM,IAAI,CAAC;AAAA,MACpC;AACA,aAAO;AAAA,IACT,CAAC,EACA,KAAK,GAAI;AAAA,EACd,EACC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,IAAI;AACd;","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
mcpToolLeaf
|
|
4
|
+
} from "./chunk-T46QZH3E.js";
|
|
5
|
+
|
|
6
|
+
// src/timeline/presented-image.ts
|
|
7
|
+
import { normalizeMcpOutput, parseSandboxFileArtifactReceipt } from "@opengeni/sdk";
|
|
8
|
+
function isRetainedImageContentType(contentType) {
|
|
9
|
+
return [
|
|
10
|
+
"image/png",
|
|
11
|
+
"image/jpeg",
|
|
12
|
+
"image/gif",
|
|
13
|
+
"image/webp",
|
|
14
|
+
"image/avif",
|
|
15
|
+
"image/svg+xml"
|
|
16
|
+
].includes(contentType);
|
|
17
|
+
}
|
|
18
|
+
function isPatchFilename(filename) {
|
|
19
|
+
return /\.(patch|diff)$/iu.test(filename.trim());
|
|
20
|
+
}
|
|
21
|
+
function activityPresentsImage(items) {
|
|
22
|
+
return items.some((item) => {
|
|
23
|
+
if (item.kind !== "tool-call") return false;
|
|
24
|
+
const name = mcpToolLeaf(item.name);
|
|
25
|
+
if (name === "generate_image" || name === "image_generation_call") return true;
|
|
26
|
+
if (item.status !== "complete" || name !== "sandbox_file_publish") return false;
|
|
27
|
+
const output = normalizeMcpOutput(item.output);
|
|
28
|
+
if (output.isError) return false;
|
|
29
|
+
const receipt = parseSandboxFileArtifactReceipt(output.text);
|
|
30
|
+
return receipt !== null && (isRetainedImageContentType(receipt.artifact.contentType) || // A published patch is the deliverable when there's no pull request:
|
|
31
|
+
// keep its card (with the apply command) visible like an image.
|
|
32
|
+
isPatchFilename(receipt.filename));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function timelineGroupContainsPresentedImage(group) {
|
|
36
|
+
switch (group.kind) {
|
|
37
|
+
case "item":
|
|
38
|
+
return false;
|
|
39
|
+
case "activity":
|
|
40
|
+
return activityPresentsImage(group.items) || (group.work?.details?.some(timelineGroupContainsPresentedImage) ?? false);
|
|
41
|
+
case "turn":
|
|
42
|
+
return group.groups.some(timelineGroupContainsPresentedImage);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
isRetainedImageContentType,
|
|
48
|
+
isPatchFilename,
|
|
49
|
+
timelineGroupContainsPresentedImage
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=chunk-R5R5RQQD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/timeline/presented-image.ts"],"sourcesContent":["import { normalizeMcpOutput, parseSandboxFileArtifactReceipt } from \"@opengeni/sdk\";\nimport { mcpToolLeaf } from \"./tool-display-name\";\nimport type { ActivityItem, TimelineGroup } from \"./types\";\n\n/*\n * Pure presentation facts shared by the projection and the renderers. Kept\n * free of React so the session-only entry can inspect primary output without pulling\n * in rendering code.\n */\n\n/** Shared browser preview allowlist; other published files remain downloads. */\nexport function isRetainedImageContentType(contentType: string): boolean {\n return [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"image/avif\",\n \"image/svg+xml\",\n ].includes(contentType);\n}\n\n/** A published patch, applied locally with `git apply`. */\nexport function isPatchFilename(filename: string): boolean {\n return /\\.(patch|diff)$/iu.test(filename.trim());\n}\n\n/**\n * Deliberately published images and patches are primary output, not\n * incidental screenshots or work files.\n */\nexport function activityPresentsImage(items: readonly ActivityItem[]): boolean {\n return items.some((item) => {\n if (item.kind !== \"tool-call\") return false;\n const name = mcpToolLeaf(item.name);\n if (name === \"generate_image\" || name === \"image_generation_call\") return true;\n if (item.status !== \"complete\" || name !== \"sandbox_file_publish\") return false;\n const output = normalizeMcpOutput(item.output);\n if (output.isError) return false;\n const receipt = parseSandboxFileArtifactReceipt(output.text);\n return (\n receipt !== null &&\n (isRetainedImageContentType(receipt.artifact.contentType) ||\n // A published patch is the deliverable when there's no pull request:\n // keep its card (with the apply command) visible like an image.\n isPatchFilename(receipt.filename))\n );\n });\n}\n\nexport function timelineGroupContainsPresentedImage(group: TimelineGroup): boolean {\n switch (group.kind) {\n case \"item\":\n return false;\n case \"activity\":\n return (\n activityPresentsImage(group.items) ||\n (group.work?.details?.some(timelineGroupContainsPresentedImage) ?? false)\n );\n case \"turn\":\n return group.groups.some(timelineGroupContainsPresentedImage);\n }\n}\n"],"mappings":";;;;;;AAAA,SAAS,oBAAoB,uCAAuC;AAW7D,SAAS,2BAA2B,aAA8B;AACvE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,WAAW;AACxB;AAGO,SAAS,gBAAgB,UAA2B;AACzD,SAAO,oBAAoB,KAAK,SAAS,KAAK,CAAC;AACjD;AAMO,SAAS,sBAAsB,OAAyC;AAC7E,SAAO,MAAM,KAAK,CAAC,SAAS;AAC1B,QAAI,KAAK,SAAS,YAAa,QAAO;AACtC,UAAM,OAAO,YAAY,KAAK,IAAI;AAClC,QAAI,SAAS,oBAAoB,SAAS,wBAAyB,QAAO;AAC1E,QAAI,KAAK,WAAW,cAAc,SAAS,uBAAwB,QAAO;AAC1E,UAAM,SAAS,mBAAmB,KAAK,MAAM;AAC7C,QAAI,OAAO,QAAS,QAAO;AAC3B,UAAM,UAAU,gCAAgC,OAAO,IAAI;AAC3D,WACE,YAAY,SACX,2BAA2B,QAAQ,SAAS,WAAW;AAAA;AAAA,IAGtD,gBAAgB,QAAQ,QAAQ;AAAA,EAEtC,CAAC;AACH;AAEO,SAAS,oCAAoC,OAA+B;AACjF,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aACE,sBAAsB,MAAM,KAAK,MAChC,MAAM,MAAM,SAAS,KAAK,mCAAmC,KAAK;AAAA,IAEvE,KAAK;AACH,aAAO,MAAM,OAAO,KAAK,mCAAmC;AAAA,EAChE;AACF;","names":[]}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/queue-item-content.ts
|
|
4
|
+
var QUEUE_ITEM_CONTENT_UNAVAILABLE = "Content unavailable";
|
|
5
|
+
function queueItemContent(text, annotationCount) {
|
|
6
|
+
if (text.length > 0) return "text";
|
|
7
|
+
return annotationCount > 0 ? "annotations" : "unavailable";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/queue-presentation-model.ts
|
|
11
|
+
var QUEUE_ROW_PREVIEW_CHARACTERS = 360;
|
|
12
|
+
var QUEUE_COLLAPSED_PREVIEW_CHARACTERS = 180;
|
|
13
|
+
var QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS = 32;
|
|
14
|
+
var QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS = 32;
|
|
15
|
+
var QUEUE_VISIBLE_END_IDENTITY_CHARACTERS = 18;
|
|
16
|
+
var QUEUE_PREVIEW_SEPARATOR = " \u2026 ";
|
|
17
|
+
var queuePreviewSegmenterCache;
|
|
18
|
+
function queuePreviewSegments(sample) {
|
|
19
|
+
if (queuePreviewSegmenterCache === void 0) {
|
|
20
|
+
queuePreviewSegmenterCache = typeof Intl !== "undefined" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
21
|
+
}
|
|
22
|
+
if (!queuePreviewSegmenterCache) return Array.from(sample);
|
|
23
|
+
return Array.from(queuePreviewSegmenterCache.segment(sample), (part) => part.segment);
|
|
24
|
+
}
|
|
25
|
+
var queuePromptNonRenderingCodePoint = /[\p{White_Space}\p{Control}\p{Default_Ignorable_Code_Point}]/u;
|
|
26
|
+
function labelQueuePreview(summary) {
|
|
27
|
+
return {
|
|
28
|
+
summary,
|
|
29
|
+
collapsedVisual: summary,
|
|
30
|
+
visibleStart: summary,
|
|
31
|
+
visibleIdentity: null,
|
|
32
|
+
visibleIdentityLabel: null,
|
|
33
|
+
isFallback: false
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function queueTurnPreview(turn, maxCharacters) {
|
|
37
|
+
if (!turn) return queuePromptPreview("", maxCharacters);
|
|
38
|
+
return queueContentPreview(turn.prompt, turn.annotations?.length ?? 0, maxCharacters);
|
|
39
|
+
}
|
|
40
|
+
function queueContentPreview(prompt, annotationCount, maxCharacters) {
|
|
41
|
+
switch (queueItemContent(prompt, annotationCount)) {
|
|
42
|
+
case "text":
|
|
43
|
+
return queuePromptPreview(prompt, maxCharacters);
|
|
44
|
+
case "annotations":
|
|
45
|
+
return labelQueuePreview(
|
|
46
|
+
`${annotationCount} timeline ${annotationCount === 1 ? "annotation" : "annotations"}`
|
|
47
|
+
);
|
|
48
|
+
case "unavailable":
|
|
49
|
+
return labelQueuePreview(QUEUE_ITEM_CONTENT_UNAVAILABLE);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function queuePromptPreview(prompt, maxCharacters) {
|
|
53
|
+
const wholePromptProbe = samplePromptStart(prompt, maxCharacters + 1);
|
|
54
|
+
if (!wholePromptProbe.truncated && wholePromptProbe.characters <= maxCharacters) {
|
|
55
|
+
const summary2 = replaceLoneSurrogates(wholePromptProbe.value);
|
|
56
|
+
return hasVisiblePromptContent(summary2) ? {
|
|
57
|
+
summary: summary2,
|
|
58
|
+
collapsedVisual: summary2,
|
|
59
|
+
visibleStart: summary2,
|
|
60
|
+
visibleIdentity: null,
|
|
61
|
+
visibleIdentityLabel: null,
|
|
62
|
+
isFallback: false
|
|
63
|
+
} : fallbackPromptPreview(prompt.length, wholePromptProbe.value, wholePromptProbe.value);
|
|
64
|
+
}
|
|
65
|
+
const suffixCharacters = Math.min(Math.floor(maxCharacters / 3), 120);
|
|
66
|
+
const prefixCharacters = maxCharacters - codePointLength(QUEUE_PREVIEW_SEPARATOR) - suffixCharacters;
|
|
67
|
+
const prefixSample = samplePromptStart(
|
|
68
|
+
prompt,
|
|
69
|
+
prefixCharacters + QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS
|
|
70
|
+
);
|
|
71
|
+
const suffixSample = samplePromptEnd(
|
|
72
|
+
prompt,
|
|
73
|
+
suffixCharacters + QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS
|
|
74
|
+
);
|
|
75
|
+
const prefixSegments = segmentPromptSample(prefixSample.value);
|
|
76
|
+
const suffixSegments = segmentPromptSample(suffixSample.value);
|
|
77
|
+
if (prefixSample.truncated) prefixSegments.pop();
|
|
78
|
+
if (suffixSample.truncated) {
|
|
79
|
+
let ambiguousSegment = suffixSegments.shift();
|
|
80
|
+
while (ambiguousSegment?.endsWith("\u200D") && suffixSegments.length > 0) {
|
|
81
|
+
ambiguousSegment = suffixSegments.shift();
|
|
82
|
+
}
|
|
83
|
+
while (suffixSegments[0] && startsWithRegionalIndicator(suffixSegments[0])) {
|
|
84
|
+
suffixSegments.shift();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const prefix = takeWholeGraphemesFromStart(prefixSegments, prefixCharacters);
|
|
88
|
+
const suffix = takeWholeGraphemesFromEnd(suffixSegments, suffixCharacters);
|
|
89
|
+
const reference = boundedPromptSampleReference(
|
|
90
|
+
prompt.length,
|
|
91
|
+
prefixSample.value,
|
|
92
|
+
suffixSample.value
|
|
93
|
+
);
|
|
94
|
+
if (!hasVisiblePromptContent(prefix) && !hasVisiblePromptContent(suffix)) {
|
|
95
|
+
return fallbackPromptPreview(prompt.length, prefixSample.value, suffixSample.value);
|
|
96
|
+
}
|
|
97
|
+
const safeSuffix = hasVisiblePromptContent(suffix) ? suffix : promptPreviewFallbackLabel(reference);
|
|
98
|
+
const summary = `${prefix}${QUEUE_PREVIEW_SEPARATOR}${safeSuffix}`;
|
|
99
|
+
if (!hasVisiblePromptContent(prefix)) {
|
|
100
|
+
return {
|
|
101
|
+
summary,
|
|
102
|
+
collapsedVisual: summary,
|
|
103
|
+
visibleStart: safeSuffix,
|
|
104
|
+
visibleIdentity: null,
|
|
105
|
+
visibleIdentityLabel: null,
|
|
106
|
+
isFallback: false
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const endIdentity = takeWholeGraphemesFromEnd(
|
|
110
|
+
suffixSegments,
|
|
111
|
+
QUEUE_VISIBLE_END_IDENTITY_CHARACTERS
|
|
112
|
+
);
|
|
113
|
+
return {
|
|
114
|
+
summary,
|
|
115
|
+
collapsedVisual: summary,
|
|
116
|
+
visibleStart: prefix,
|
|
117
|
+
visibleIdentity: hasVisiblePromptContent(endIdentity) ? endIdentity : `ref ${reference}`,
|
|
118
|
+
visibleIdentityLabel: hasVisiblePromptContent(endIdentity) ? "End" : "Safe boundary",
|
|
119
|
+
isFallback: false
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function fallbackPromptPreview(promptLength, startSample, endSample) {
|
|
123
|
+
const reference = boundedPromptSampleReference(promptLength, startSample, endSample);
|
|
124
|
+
const summary = promptPreviewFallbackLabel(reference);
|
|
125
|
+
return {
|
|
126
|
+
summary,
|
|
127
|
+
collapsedVisual: `Omitted \xB7 ${reference}`,
|
|
128
|
+
// The complete fallback remains the canonical accessible summary. Narrow
|
|
129
|
+
// collapsed/row layouts paint the bounded reference in a compact truthful
|
|
130
|
+
// form so ellipsis cannot hide the only identifying portion.
|
|
131
|
+
visibleStart: `Omitted \xB7 ${reference}`,
|
|
132
|
+
visibleIdentity: null,
|
|
133
|
+
visibleIdentityLabel: null,
|
|
134
|
+
isFallback: true
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function promptPreviewFallbackLabel(reference) {
|
|
138
|
+
return `Content omitted at safe boundary \xB7 ref ${reference}`;
|
|
139
|
+
}
|
|
140
|
+
function boundedPromptSampleReference(promptLength, startSample, endSample) {
|
|
141
|
+
const head = samplePromptStart(startSample, QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS).value;
|
|
142
|
+
const tail = samplePromptEnd(endSample, QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS).value;
|
|
143
|
+
let hash = 2166136261;
|
|
144
|
+
for (const value of [String(promptLength), head, tail]) {
|
|
145
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
146
|
+
hash ^= value.charCodeAt(index);
|
|
147
|
+
hash = Math.imul(hash, 16777619);
|
|
148
|
+
}
|
|
149
|
+
hash ^= 65535;
|
|
150
|
+
hash = Math.imul(hash, 16777619);
|
|
151
|
+
}
|
|
152
|
+
return (hash >>> 0).toString(16).padStart(8, "0").toUpperCase();
|
|
153
|
+
}
|
|
154
|
+
function hasVisiblePromptContent(value) {
|
|
155
|
+
for (const character of value) {
|
|
156
|
+
if (!queuePromptNonRenderingCodePoint.test(character)) return true;
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
function samplePromptStart(prompt, maxCharacters) {
|
|
161
|
+
let end = 0;
|
|
162
|
+
let characters = 0;
|
|
163
|
+
while (end < prompt.length && characters < maxCharacters) {
|
|
164
|
+
const first = prompt.charCodeAt(end);
|
|
165
|
+
end += isHighSurrogate(first) && end + 1 < prompt.length && isLowSurrogate(prompt.charCodeAt(end + 1)) ? 2 : 1;
|
|
166
|
+
characters += 1;
|
|
167
|
+
}
|
|
168
|
+
return { value: prompt.slice(0, end), characters, truncated: end < prompt.length };
|
|
169
|
+
}
|
|
170
|
+
function samplePromptEnd(prompt, maxCharacters) {
|
|
171
|
+
let start = prompt.length;
|
|
172
|
+
let characters = 0;
|
|
173
|
+
while (start > 0 && characters < maxCharacters) {
|
|
174
|
+
start -= 1;
|
|
175
|
+
if (isLowSurrogate(prompt.charCodeAt(start)) && start > 0 && isHighSurrogate(prompt.charCodeAt(start - 1))) {
|
|
176
|
+
start -= 1;
|
|
177
|
+
}
|
|
178
|
+
characters += 1;
|
|
179
|
+
}
|
|
180
|
+
return { value: prompt.slice(start), characters, truncated: start > 0 };
|
|
181
|
+
}
|
|
182
|
+
function segmentPromptSample(sample) {
|
|
183
|
+
return queuePreviewSegments(replaceLoneSurrogates(sample));
|
|
184
|
+
}
|
|
185
|
+
function replaceLoneSurrogates(value) {
|
|
186
|
+
let sanitized = "";
|
|
187
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
188
|
+
const current = value.charCodeAt(index);
|
|
189
|
+
if (isHighSurrogate(current) && index + 1 < value.length && isLowSurrogate(value.charCodeAt(index + 1))) {
|
|
190
|
+
sanitized += value.slice(index, index + 2);
|
|
191
|
+
index += 1;
|
|
192
|
+
} else if (isHighSurrogate(current) || isLowSurrogate(current)) {
|
|
193
|
+
sanitized += "\uFFFD";
|
|
194
|
+
} else {
|
|
195
|
+
sanitized += value[index];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return sanitized;
|
|
199
|
+
}
|
|
200
|
+
function takeWholeGraphemesFromStart(segments, maxCharacters) {
|
|
201
|
+
const selected = [];
|
|
202
|
+
let characters = 0;
|
|
203
|
+
for (const segment of segments) {
|
|
204
|
+
const segmentCharacters = codePointLength(segment);
|
|
205
|
+
if (characters + segmentCharacters > maxCharacters) break;
|
|
206
|
+
selected.push(segment);
|
|
207
|
+
characters += segmentCharacters;
|
|
208
|
+
}
|
|
209
|
+
while (selected.at(-1)?.trim().length === 0) selected.pop();
|
|
210
|
+
return selected.join("");
|
|
211
|
+
}
|
|
212
|
+
function takeWholeGraphemesFromEnd(segments, maxCharacters) {
|
|
213
|
+
const selected = [];
|
|
214
|
+
let characters = 0;
|
|
215
|
+
for (let index = segments.length - 1; index >= 0; index -= 1) {
|
|
216
|
+
const segment = segments[index];
|
|
217
|
+
if (!segment) continue;
|
|
218
|
+
const segmentCharacters = codePointLength(segment);
|
|
219
|
+
if (characters + segmentCharacters > maxCharacters) break;
|
|
220
|
+
selected.unshift(segment);
|
|
221
|
+
characters += segmentCharacters;
|
|
222
|
+
}
|
|
223
|
+
while (selected[0]?.trim().length === 0) selected.shift();
|
|
224
|
+
while (selected.at(-1)?.trim().length === 0) selected.pop();
|
|
225
|
+
return selected.join("");
|
|
226
|
+
}
|
|
227
|
+
function codePointLength(value) {
|
|
228
|
+
let characters = 0;
|
|
229
|
+
for (const _character of value) characters += 1;
|
|
230
|
+
return characters;
|
|
231
|
+
}
|
|
232
|
+
function startsWithRegionalIndicator(value) {
|
|
233
|
+
const codePoint = value.codePointAt(0);
|
|
234
|
+
return codePoint !== void 0 && codePoint >= 127462 && codePoint <= 127487;
|
|
235
|
+
}
|
|
236
|
+
function isHighSurrogate(codeUnit) {
|
|
237
|
+
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
238
|
+
}
|
|
239
|
+
function isLowSurrogate(codeUnit) {
|
|
240
|
+
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
241
|
+
}
|
|
242
|
+
function moveQueueItem(items, from, to) {
|
|
243
|
+
const next = items.slice();
|
|
244
|
+
const [item] = next.splice(from, 1);
|
|
245
|
+
if (item === void 0) return next;
|
|
246
|
+
next.splice(to < 0 ? next.length + to : to, 0, item);
|
|
247
|
+
return next;
|
|
248
|
+
}
|
|
249
|
+
function queueMovePlan(queue, turnId, nextIndex) {
|
|
250
|
+
const oldIndex = queue.findIndex((turn) => turn.id === turnId);
|
|
251
|
+
if (oldIndex < 0) return null;
|
|
252
|
+
const index = Math.max(0, Math.min(nextIndex, queue.length - 1));
|
|
253
|
+
if (oldIndex === index) return null;
|
|
254
|
+
const ordered = moveQueueItem(queue, oldIndex, index);
|
|
255
|
+
return {
|
|
256
|
+
turnIds: ordered.map((turn) => turn.id),
|
|
257
|
+
beforeTurnId: ordered[index + 1]?.id ?? null,
|
|
258
|
+
index
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function projectPendingQueueMove(queue, pendingMove, snapshot) {
|
|
262
|
+
if (!pendingMove || pendingMove.baseVersion === null || snapshot?.version !== pendingMove.baseVersion) {
|
|
263
|
+
return queue;
|
|
264
|
+
}
|
|
265
|
+
const byId = new Map(queue.map((turn) => [turn.id, turn]));
|
|
266
|
+
const projected = pendingMove.turnIds.map((turnId) => byId.get(turnId));
|
|
267
|
+
if (projected.some((turn) => !turn) || projected.length !== queue.length) {
|
|
268
|
+
return queue;
|
|
269
|
+
}
|
|
270
|
+
return projected;
|
|
271
|
+
}
|
|
272
|
+
var QUEUE_REPLACE_DRAFT_COPY = {
|
|
273
|
+
title: "Your composer already has a draft. Replace it with this queued prompt?",
|
|
274
|
+
detail: "The current draft will be permanently discarded; this queued prompt is preserved until you confirm.",
|
|
275
|
+
keep: "Keep current draft",
|
|
276
|
+
replace: "Replace and edit"
|
|
277
|
+
};
|
|
278
|
+
function objectValue(value) {
|
|
279
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
280
|
+
}
|
|
281
|
+
function queuedTurnPresentation(turn) {
|
|
282
|
+
const realtimeDelegation = objectValue(turn.metadata.realtimeDelegation);
|
|
283
|
+
const inputTranscript = realtimeDelegation?.inputTranscript;
|
|
284
|
+
if (typeof inputTranscript === "string" && inputTranscript.trim()) {
|
|
285
|
+
return { kind: "realtime_voice", text: inputTranscript.trim() };
|
|
286
|
+
}
|
|
287
|
+
if (objectValue(turn.metadata.realtimeTailFlush)) {
|
|
288
|
+
return { kind: "realtime_voice_handoff", text: "Remaining voice context" };
|
|
289
|
+
}
|
|
290
|
+
return { kind: "prompt", text: turn.prompt };
|
|
291
|
+
}
|
|
292
|
+
function isSteeringTurn(turn) {
|
|
293
|
+
return turn.metadata.delivery === "steer";
|
|
294
|
+
}
|
|
295
|
+
function isAuthoritativeQueuedTurn(turn, mutationFor) {
|
|
296
|
+
return !isSteeringTurn(turn) && mutationFor(turn.id) !== "steer";
|
|
297
|
+
}
|
|
298
|
+
function countAuthoritativeQueuedTurns(turns, mutationFor) {
|
|
299
|
+
return turns.filter((turn) => isAuthoritativeQueuedTurn(turn, mutationFor)).length;
|
|
300
|
+
}
|
|
301
|
+
function queueNeighborAnchors(turns, index) {
|
|
302
|
+
return {
|
|
303
|
+
beforeUp: index > 0 ? turns[index - 1]?.id ?? null : null,
|
|
304
|
+
beforeDown: index < turns.length - 1 ? turns[index + 2]?.id ?? null : null
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export {
|
|
309
|
+
QUEUE_ITEM_CONTENT_UNAVAILABLE,
|
|
310
|
+
queueItemContent,
|
|
311
|
+
QUEUE_ROW_PREVIEW_CHARACTERS,
|
|
312
|
+
QUEUE_COLLAPSED_PREVIEW_CHARACTERS,
|
|
313
|
+
queueTurnPreview,
|
|
314
|
+
queueContentPreview,
|
|
315
|
+
queuePromptPreview,
|
|
316
|
+
moveQueueItem,
|
|
317
|
+
queueMovePlan,
|
|
318
|
+
projectPendingQueueMove,
|
|
319
|
+
QUEUE_REPLACE_DRAFT_COPY,
|
|
320
|
+
queuedTurnPresentation,
|
|
321
|
+
isSteeringTurn,
|
|
322
|
+
isAuthoritativeQueuedTurn,
|
|
323
|
+
countAuthoritativeQueuedTurns,
|
|
324
|
+
queueNeighborAnchors
|
|
325
|
+
};
|
|
326
|
+
//# sourceMappingURL=chunk-RI42H5IU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/queue-item-content.ts","../src/queue-presentation-model.ts"],"sourcesContent":["/**\n * One presentation rule for a queued item, shared by the full queue and the\n * compact session-chrome dock so the two cannot drift. A turn with an empty\n * prompt and timeline annotations is valid content; an item with neither is a\n * malformed or legacy object that gets an explicit fallback, never a blank row.\n */\nexport type QueueItemContent = \"text\" | \"annotations\" | \"unavailable\";\n\nexport const QUEUE_ITEM_CONTENT_UNAVAILABLE = \"Content unavailable\";\n\nexport function queueItemContent(text: string, annotationCount: number): QueueItemContent {\n if (text.length > 0) return \"text\";\n return annotationCount > 0 ? \"annotations\" : \"unavailable\";\n}\n","/**\n * Queue presentation shared by the web queue surface and native docks: the\n * bounded head/tail previews of queued prompts, and the reorder plan and its\n * optimistic projection. No DOM, no React.\n */\nimport type { SessionQueueSnapshot, SessionTurn } from \"@opengeni/sdk\";\nimport { QUEUE_ITEM_CONTENT_UNAVAILABLE, queueItemContent } from \"./components/queue-item-content\";\n\nexport { QUEUE_ITEM_CONTENT_UNAVAILABLE, queueItemContent };\n\nexport const QUEUE_ROW_PREVIEW_CHARACTERS = 360;\nexport const QUEUE_COLLAPSED_PREVIEW_CHARACTERS = 180;\nconst QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS = 32;\nconst QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS = 32;\nconst QUEUE_VISIBLE_END_IDENTITY_CHARACTERS = 18;\nconst QUEUE_PREVIEW_SEPARATOR = \" … \";\n// Hermes (React Native) has no Intl.Segmenter; there, previews fall back to\n// code points, which keeps every boundary rule except grapheme joining.\nlet queuePreviewSegmenterCache: Intl.Segmenter | null | undefined;\nfunction queuePreviewSegments(sample: string): string[] {\n if (queuePreviewSegmenterCache === undefined) {\n queuePreviewSegmenterCache =\n typeof Intl !== \"undefined\" && typeof Intl.Segmenter === \"function\"\n ? new Intl.Segmenter(undefined, { granularity: \"grapheme\" })\n : null;\n }\n if (!queuePreviewSegmenterCache) return Array.from(sample);\n return Array.from(queuePreviewSegmenterCache.segment(sample), (part) => part.segment);\n}\nconst queuePromptNonRenderingCodePoint =\n /[\\p{White_Space}\\p{Control}\\p{Default_Ignorable_Code_Point}]/u;\n\ntype BoundedPromptSample = {\n value: string;\n characters: number;\n truncated: boolean;\n};\n\nexport type QueuePromptPreview = {\n summary: string;\n collapsedVisual: string;\n visibleStart: string;\n visibleIdentity: string | null;\n visibleIdentityLabel: \"End\" | \"Safe boundary\" | null;\n isFallback: boolean;\n};\n\nfunction labelQueuePreview(summary: string): QueuePromptPreview {\n return {\n summary,\n collapsedVisual: summary,\n visibleStart: summary,\n visibleIdentity: null,\n visibleIdentityLabel: null,\n isFallback: false,\n };\n}\n\nexport function queueTurnPreview(\n turn: SessionTurn | undefined,\n maxCharacters: number,\n): QueuePromptPreview {\n if (!turn) return queuePromptPreview(\"\", maxCharacters);\n return queueContentPreview(turn.prompt, turn.annotations?.length ?? 0, maxCharacters);\n}\n\nexport function queueContentPreview(\n prompt: string,\n annotationCount: number,\n maxCharacters: number,\n): QueuePromptPreview {\n switch (queueItemContent(prompt, annotationCount)) {\n case \"text\":\n return queuePromptPreview(prompt, maxCharacters);\n case \"annotations\":\n return labelQueuePreview(\n `${annotationCount} timeline ${annotationCount === 1 ? \"annotation\" : \"annotations\"}`,\n );\n case \"unavailable\":\n return labelQueuePreview(QUEUE_ITEM_CONTENT_UNAVAILABLE);\n }\n}\n\n/**\n * Build a bounded head/tail summary of an arbitrary queued prompt. Sampling\n * both ends distinguishes prompts with equal long prefixes. Each sampled edge\n * has a small amount of grapheme context so ordinary emoji/combining sequences\n * can be retained whole. A cluster that exceeds that context is omitted rather\n * than fragmented, and malformed UTF-16 is replaced only in the summary. The\n * durable prompt remains exact and no operation scans or copies it in full.\n */\nexport function queuePromptPreview(prompt: string, maxCharacters: number): QueuePromptPreview {\n const wholePromptProbe = samplePromptStart(prompt, maxCharacters + 1);\n if (!wholePromptProbe.truncated && wholePromptProbe.characters <= maxCharacters) {\n const summary = replaceLoneSurrogates(wholePromptProbe.value);\n return hasVisiblePromptContent(summary)\n ? {\n summary,\n collapsedVisual: summary,\n visibleStart: summary,\n visibleIdentity: null,\n visibleIdentityLabel: null,\n isFallback: false,\n }\n : fallbackPromptPreview(prompt.length, wholePromptProbe.value, wholePromptProbe.value);\n }\n\n const suffixCharacters = Math.min(Math.floor(maxCharacters / 3), 120);\n const prefixCharacters =\n maxCharacters - codePointLength(QUEUE_PREVIEW_SEPARATOR) - suffixCharacters;\n const prefixSample = samplePromptStart(\n prompt,\n prefixCharacters + QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS,\n );\n const suffixSample = samplePromptEnd(\n prompt,\n suffixCharacters + QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS,\n );\n const prefixSegments = segmentPromptSample(prefixSample.value);\n const suffixSegments = segmentPromptSample(suffixSample.value);\n\n // A cluster at a truncated sampling edge may continue outside the sample.\n // Prefix sampling starts at the true source start, so only its last segment\n // is ambiguous. Suffix sampling ends at the true source end, so its first is.\n if (prefixSample.truncated) prefixSegments.pop();\n if (suffixSample.truncated) {\n let ambiguousSegment = suffixSegments.shift();\n // A locally segmented leading fragment ending in ZWJ can join the next\n // pictographic segment when omitted left context supplies its base. Keep\n // backing off until that uncertainty no longer propagates to the right.\n while (ambiguousSegment?.endsWith(\"\\u200d\") && suffixSegments.length > 0) {\n ambiguousSegment = suffixSegments.shift();\n }\n // Regional Indicator pairing depends on the parity of the preceding run.\n // If that run reaches the unknown sample boundary, omit all of its visible\n // leading segments rather than potentially recombining halves of flags.\n while (suffixSegments[0] && startsWithRegionalIndicator(suffixSegments[0])) {\n suffixSegments.shift();\n }\n }\n\n const prefix = takeWholeGraphemesFromStart(prefixSegments, prefixCharacters);\n const suffix = takeWholeGraphemesFromEnd(suffixSegments, suffixCharacters);\n const reference = boundedPromptSampleReference(\n prompt.length,\n prefixSample.value,\n suffixSample.value,\n );\n\n if (!hasVisiblePromptContent(prefix) && !hasVisiblePromptContent(suffix)) {\n return fallbackPromptPreview(prompt.length, prefixSample.value, suffixSample.value);\n }\n\n const safeSuffix = hasVisiblePromptContent(suffix)\n ? suffix\n : promptPreviewFallbackLabel(reference);\n const summary = `${prefix}${QUEUE_PREVIEW_SEPARATOR}${safeSuffix}`;\n if (!hasVisiblePromptContent(prefix)) {\n return {\n summary,\n collapsedVisual: summary,\n visibleStart: safeSuffix,\n visibleIdentity: null,\n visibleIdentityLabel: null,\n isFallback: false,\n };\n }\n\n const endIdentity = takeWholeGraphemesFromEnd(\n suffixSegments,\n QUEUE_VISIBLE_END_IDENTITY_CHARACTERS,\n );\n return {\n summary,\n collapsedVisual: summary,\n visibleStart: prefix,\n visibleIdentity: hasVisiblePromptContent(endIdentity) ? endIdentity : `ref ${reference}`,\n visibleIdentityLabel: hasVisiblePromptContent(endIdentity) ? \"End\" : \"Safe boundary\",\n isFallback: false,\n };\n}\n\nfunction fallbackPromptPreview(\n promptLength: number,\n startSample: string,\n endSample: string,\n): QueuePromptPreview {\n const reference = boundedPromptSampleReference(promptLength, startSample, endSample);\n const summary = promptPreviewFallbackLabel(reference);\n return {\n summary,\n collapsedVisual: `Omitted · ${reference}`,\n // The complete fallback remains the canonical accessible summary. Narrow\n // collapsed/row layouts paint the bounded reference in a compact truthful\n // form so ellipsis cannot hide the only identifying portion.\n visibleStart: `Omitted · ${reference}`,\n visibleIdentity: null,\n visibleIdentityLabel: null,\n isFallback: true,\n };\n}\n\nfunction promptPreviewFallbackLabel(reference: string): string {\n return `Content omitted at safe boundary · ref ${reference}`;\n}\n\nfunction boundedPromptSampleReference(\n promptLength: number,\n startSample: string,\n endSample: string,\n): string {\n const head = samplePromptStart(startSample, QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS).value;\n const tail = samplePromptEnd(endSample, QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS).value;\n let hash = 0x811c9dc5;\n for (const value of [String(promptLength), head, tail]) {\n for (let index = 0; index < value.length; index += 1) {\n hash ^= value.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n hash ^= 0xffff;\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, \"0\").toUpperCase();\n}\n\nfunction hasVisiblePromptContent(value: string): boolean {\n // Callers pass only the already-bounded whole/head/tail preview samples.\n // Default-ignorables and controls can survive trim() while painting no row\n // identity at all (for example ZWJ, VS16, bidi controls, and tag characters).\n for (const character of value) {\n if (!queuePromptNonRenderingCodePoint.test(character)) return true;\n }\n return false;\n}\n\nfunction samplePromptStart(prompt: string, maxCharacters: number): BoundedPromptSample {\n let end = 0;\n let characters = 0;\n while (end < prompt.length && characters < maxCharacters) {\n const first = prompt.charCodeAt(end);\n end +=\n isHighSurrogate(first) &&\n end + 1 < prompt.length &&\n isLowSurrogate(prompt.charCodeAt(end + 1))\n ? 2\n : 1;\n characters += 1;\n }\n return { value: prompt.slice(0, end), characters, truncated: end < prompt.length };\n}\n\nfunction samplePromptEnd(prompt: string, maxCharacters: number): BoundedPromptSample {\n let start = prompt.length;\n let characters = 0;\n while (start > 0 && characters < maxCharacters) {\n start -= 1;\n if (\n isLowSurrogate(prompt.charCodeAt(start)) &&\n start > 0 &&\n isHighSurrogate(prompt.charCodeAt(start - 1))\n ) {\n start -= 1;\n }\n characters += 1;\n }\n return { value: prompt.slice(start), characters, truncated: start > 0 };\n}\n\nfunction segmentPromptSample(sample: string): string[] {\n return queuePreviewSegments(replaceLoneSurrogates(sample));\n}\n\nfunction replaceLoneSurrogates(value: string): string {\n let sanitized = \"\";\n for (let index = 0; index < value.length; index += 1) {\n const current = value.charCodeAt(index);\n if (\n isHighSurrogate(current) &&\n index + 1 < value.length &&\n isLowSurrogate(value.charCodeAt(index + 1))\n ) {\n sanitized += value.slice(index, index + 2);\n index += 1;\n } else if (isHighSurrogate(current) || isLowSurrogate(current)) {\n sanitized += \"�\";\n } else {\n sanitized += value[index];\n }\n }\n return sanitized;\n}\n\nfunction takeWholeGraphemesFromStart(segments: string[], maxCharacters: number): string {\n const selected: string[] = [];\n let characters = 0;\n for (const segment of segments) {\n const segmentCharacters = codePointLength(segment);\n if (characters + segmentCharacters > maxCharacters) break;\n selected.push(segment);\n characters += segmentCharacters;\n }\n while (selected.at(-1)?.trim().length === 0) selected.pop();\n return selected.join(\"\");\n}\n\nfunction takeWholeGraphemesFromEnd(segments: string[], maxCharacters: number): string {\n const selected: string[] = [];\n let characters = 0;\n for (let index = segments.length - 1; index >= 0; index -= 1) {\n const segment = segments[index];\n if (!segment) continue;\n const segmentCharacters = codePointLength(segment);\n if (characters + segmentCharacters > maxCharacters) break;\n selected.unshift(segment);\n characters += segmentCharacters;\n }\n while (selected[0]?.trim().length === 0) selected.shift();\n while (selected.at(-1)?.trim().length === 0) selected.pop();\n return selected.join(\"\");\n}\n\nfunction codePointLength(value: string): number {\n let characters = 0;\n for (const _character of value) characters += 1;\n return characters;\n}\n\nfunction startsWithRegionalIndicator(value: string): boolean {\n const codePoint = value.codePointAt(0);\n return codePoint !== undefined && codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff;\n}\n\nfunction isHighSurrogate(codeUnit: number): boolean {\n return codeUnit >= 0xd800 && codeUnit <= 0xdbff;\n}\n\nfunction isLowSurrogate(codeUnit: number): boolean {\n return codeUnit >= 0xdc00 && codeUnit <= 0xdfff;\n}\n\n/** Move one item, as dnd-kit's arrayMove does. */\nexport function moveQueueItem<T>(items: readonly T[], from: number, to: number): T[] {\n const next = items.slice();\n const [item] = next.splice(from, 1);\n if (item === undefined) return next;\n next.splice(to < 0 ? next.length + to : to, 0, item);\n return next;\n}\n\nexport type QueueMovePlan = {\n /** The turn ids in their new order. */\n turnIds: string[];\n /** The server anchor: the turn the moved one now precedes, null for last. */\n beforeTurnId: string | null;\n /** The bounded destination index. */\n index: number;\n};\n\n/** The reorder request for moving a queued turn to an index, or null for a no-op. */\nexport function queueMovePlan(\n queue: readonly SessionTurn[],\n turnId: string,\n nextIndex: number,\n): QueueMovePlan | null {\n const oldIndex = queue.findIndex((turn) => turn.id === turnId);\n if (oldIndex < 0) return null;\n const index = Math.max(0, Math.min(nextIndex, queue.length - 1));\n if (oldIndex === index) return null;\n const ordered = moveQueueItem(queue, oldIndex, index);\n return {\n turnIds: ordered.map((turn) => turn.id),\n beforeTurnId: ordered[index + 1]?.id ?? null,\n index,\n };\n}\n\nexport type PendingQueueMove = { baseVersion: number | null; turnIds: string[] };\n\n/**\n * The queue as shown while a move is in flight: the optimistic order, unless\n * any authoritative change arrived. A projection never omits or invents a row.\n */\nexport function projectPendingQueueMove(\n queue: SessionTurn[],\n pendingMove: PendingQueueMove | null,\n snapshot: Pick<SessionQueueSnapshot, \"version\"> | null,\n): SessionTurn[] {\n if (\n !pendingMove ||\n pendingMove.baseVersion === null ||\n snapshot?.version !== pendingMove.baseVersion\n ) {\n return queue;\n }\n const byId = new Map(queue.map((turn) => [turn.id, turn]));\n const projected = pendingMove.turnIds.map((turnId) => byId.get(turnId));\n if (projected.some((turn) => !turn) || projected.length !== queue.length) {\n return queue;\n }\n return projected as SessionTurn[];\n}\n\n/** Copy for the \"replace your draft with this queued prompt\" confirmation. */\nexport const QUEUE_REPLACE_DRAFT_COPY = {\n title: \"Your composer already has a draft. Replace it with this queued prompt?\",\n detail:\n \"The current draft will be permanently discarded; this queued prompt is preserved until you confirm.\",\n keep: \"Keep current draft\",\n replace: \"Replace and edit\",\n} as const;\n\nexport type QueuedTurnPresentation = {\n kind: \"prompt\" | \"realtime_voice\" | \"realtime_voice_handoff\";\n text: string;\n};\n\nfunction objectValue(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\n/** What a queued row shows: the prompt, or the transcript of a voice request. */\nexport function queuedTurnPresentation(turn: SessionTurn): QueuedTurnPresentation {\n const realtimeDelegation = objectValue(turn.metadata.realtimeDelegation);\n const inputTranscript = realtimeDelegation?.inputTranscript;\n if (typeof inputTranscript === \"string\" && inputTranscript.trim()) {\n return { kind: \"realtime_voice\", text: inputTranscript.trim() };\n }\n if (objectValue(turn.metadata.realtimeTailFlush)) {\n return { kind: \"realtime_voice_handoff\", text: \"Remaining voice context\" };\n }\n return { kind: \"prompt\", text: turn.prompt };\n}\n\nexport function isSteeringTurn(turn: SessionTurn): boolean {\n return turn.metadata.delivery === \"steer\";\n}\n\n/** A queued turn that is really waiting: not already a steer in flight. */\nexport function isAuthoritativeQueuedTurn(\n turn: SessionTurn,\n mutationFor: (turnId: string) => string | null,\n): boolean {\n return !isSteeringTurn(turn) && mutationFor(turn.id) !== \"steer\";\n}\n\nexport function countAuthoritativeQueuedTurns(\n turns: readonly SessionTurn[],\n mutationFor: (turnId: string) => string | null,\n): number {\n return turns.filter((turn) => isAuthoritativeQueuedTurn(turn, mutationFor)).length;\n}\n\n/** The move anchors for one row's Move up / Move down. */\nexport function queueNeighborAnchors(\n turns: readonly SessionTurn[],\n index: number,\n): { beforeUp: string | null; beforeDown: string | null } {\n return {\n beforeUp: index > 0 ? (turns[index - 1]?.id ?? null) : null,\n beforeDown: index < turns.length - 1 ? (turns[index + 2]?.id ?? null) : null,\n };\n}\n"],"mappings":"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","names":["summary"]}
|
|
@@ -293,21 +293,12 @@ function QueueErrorAlert({
|
|
|
293
293
|
) });
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
-
// src/components/queue-item-content.ts
|
|
297
|
-
var QUEUE_ITEM_CONTENT_UNAVAILABLE = "Content unavailable";
|
|
298
|
-
function queueItemContent(text, annotationCount) {
|
|
299
|
-
if (text.length > 0) return "text";
|
|
300
|
-
return annotationCount > 0 ? "annotations" : "unavailable";
|
|
301
|
-
}
|
|
302
|
-
|
|
303
296
|
export {
|
|
304
297
|
TimelineAnnotationCards,
|
|
305
298
|
TimelineAnnotationsChip,
|
|
306
299
|
requestQueueDraftEdit,
|
|
307
300
|
EmptyQueueStateSurface,
|
|
308
301
|
QueueStoppingStatus,
|
|
309
|
-
QueueErrorAlert
|
|
310
|
-
QUEUE_ITEM_CONTENT_UNAVAILABLE,
|
|
311
|
-
queueItemContent
|
|
302
|
+
QueueErrorAlert
|
|
312
303
|
};
|
|
313
|
-
//# sourceMappingURL=chunk-
|
|
304
|
+
//# sourceMappingURL=chunk-SHLZMAJN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/timeline-annotations.tsx","../src/components/queue-draft-policy.ts","../src/components/queue-surface-state.tsx"],"sourcesContent":["import type { TimelineAnnotationSource } from \"@opengeni/sdk\";\nimport { QuoteIcon, XIcon } from \"lucide-react\";\nimport {\n Suspense,\n lazy,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n AnnotationAccentRow,\n AnnotationNotePreview,\n AnnotationQuoteSourceButton,\n type TimelineAnnotationLike,\n} from \"./timeline-annotation-chrome\";\nimport { ANNOTATION_CARD_STACK_SCROLL_AT } from \"./timeline-annotation-layout\";\nimport {\n TimelineAnnotationSourceRootContext,\n useTimelineAnnotationSourceRoot,\n} from \"./timeline-annotation-reveal-context\";\nimport {\n annotationDisplayOrdinal,\n annotationHasNote,\n resolveAnnotationRevealRoot,\n} from \"./timeline-annotation-shared\";\n\nexport type { TimelineAnnotationLike } from \"./timeline-annotation-chrome\";\n\nconst TimelineAnnotationsDialog = lazy(() => import(\"./timeline-annotations-dialog\"));\n\nfunction AnnotationSourceRootBridge({\n triggerRef,\n children,\n}: {\n triggerRef: RefObject<HTMLElement | null>;\n children: ReactNode;\n}) {\n const inheritedRoot = useTimelineAnnotationSourceRoot();\n const conversationRootRef = useRef<HTMLElement | null>(null);\n if (!inheritedRoot) {\n conversationRootRef.current = resolveAnnotationRevealRoot(triggerRef.current);\n }\n useLayoutEffect(() => {\n if (inheritedRoot) return;\n conversationRootRef.current = resolveAnnotationRevealRoot(triggerRef.current);\n });\n if (inheritedRoot) return children;\n return (\n <TimelineAnnotationSourceRootContext.Provider value={conversationRootRef}>\n {children}\n </TimelineAnnotationSourceRootContext.Provider>\n );\n}\n\nexport function TimelineAnnotationCards({\n annotations,\n onRevealSource,\n className,\n}: {\n annotations: readonly TimelineAnnotationLike[];\n onRevealSource?: ((source: TimelineAnnotationSource) => boolean) | undefined;\n className?: string | undefined;\n}) {\n const [unavailableId, setUnavailableId] = useState<string | null>(null);\n if (annotations.length === 0) return null;\n return (\n <div\n data-og-annotation-cards=\"\"\n className={cn(\n \"grid gap-2\",\n annotations.length >= ANNOTATION_CARD_STACK_SCROLL_AT &&\n \"max-h-[min(28rem,55vh)] overflow-x-hidden overflow-y-auto overscroll-contain pr-1\",\n className,\n )}\n >\n {annotations.map((annotation, index) => {\n const ordinal = annotationDisplayOrdinal(annotation, index);\n return (\n <section key={annotation.id} aria-label={`Annotation ${ordinal}`}>\n <AnnotationAccentRow>\n <p className=\"mb-0.5 text-og-xs font-medium tabular-nums text-og-fg-subtle\">\n Annotation {ordinal}\n </p>\n <AnnotationQuoteSourceButton\n annotation={annotation}\n lines={2}\n onRevealSource={onRevealSource}\n onUnavailable={setUnavailableId}\n />\n {unavailableId === annotation.id ? (\n <p role=\"status\" className=\"text-og-xs text-og-status-waiting\">\n Source is outside the loaded timeline window.\n </p>\n ) : null}\n <AnnotationNotePreview\n note={annotation.note}\n annotationId={annotation.id}\n ordinal={ordinal}\n />\n </AnnotationAccentRow>\n </section>\n );\n })}\n </div>\n );\n}\n\nexport function TimelineAnnotationsChip({\n annotations,\n editable = false,\n focusAnnotationId,\n onFocusConsumed,\n onUpdate,\n onRemove,\n onRevealSource,\n className,\n compact = false,\n onCommit,\n}: {\n annotations: readonly TimelineAnnotationLike[];\n editable?: boolean | undefined;\n focusAnnotationId?: string | null | undefined;\n onFocusConsumed?: (() => void) | undefined;\n onUpdate?: ((id: string, note: string) => void) | undefined;\n onRemove?: ((id: string) => void) | undefined;\n /** Return focus to the owning input after all notes are completed with Enter. */\n onCommit?: (() => void) | undefined;\n onRevealSource?: ((source: TimelineAnnotationSource) => boolean) | undefined;\n className?: string | undefined;\n /** Dense trigger for single-line rows such as the compact queue dock. */\n compact?: boolean | undefined;\n}) {\n const focusRequested = Boolean(\n focusAnnotationId && annotations.some((item) => item.id === focusAnnotationId),\n );\n const [open, setOpen] = useState(focusRequested);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const openedFocusId = useRef<string | null>(focusRequested ? (focusAnnotationId ?? null) : null);\n\n useEffect(() => {\n if (!focusRequested || !focusAnnotationId) {\n if (!focusRequested) openedFocusId.current = null;\n return;\n }\n if (openedFocusId.current === focusAnnotationId) return;\n openedFocusId.current = focusAnnotationId;\n setOpen(true);\n }, [focusAnnotationId, focusRequested]);\n\n if (annotations.length === 0) return null;\n const countLabel = `${annotations.length} ${annotations.length === 1 ? \"annotation\" : \"annotations\"}`;\n const incomplete = annotations.some((annotation) => !annotationHasNote(annotation.note));\n const canClear = Boolean(editable && onRemove);\n\n const dismiss = (restoreFocus: boolean) => {\n setOpen(false);\n onFocusConsumed?.();\n if (restoreFocus) triggerRef.current?.focus();\n };\n\n return (\n <span className={cn(\"inline-flex max-w-full items-center\", className)}>\n <span\n className={cn(\n \"inline-flex max-w-full items-center rounded-full border bg-og-surface-1 text-og-fg-muted\",\n incomplete ? \"border-og-accent/45 bg-og-accent-soft/50\" : \"border-og-border\",\n )}\n >\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(\n \"inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-full border-0 bg-transparent font-medium outline-hidden transition hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\",\n compact ? \"min-h-6 py-0.5 text-og-xs\" : \"min-h-8 py-1 text-og-sm\",\n canClear ? \"pr-1 pl-2.5\" : \"px-2.5\",\n )}\n aria-label={`Review ${countLabel}`}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n onClick={() => setOpen((current) => !current)}\n >\n <QuoteIcon className=\"size-3.5 shrink-0 text-og-accent\" aria-hidden=\"true\" />\n <span className=\"min-w-0 truncate\">{countLabel}</span>\n </button>\n {canClear ? (\n <button\n type=\"button\"\n className=\"inline-flex size-7 shrink-0 items-center justify-center rounded-full border-0 bg-transparent text-og-fg-subtle outline-hidden hover:text-og-status-failed focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:size-11\"\n aria-label=\"Remove all annotations\"\n onClick={() => {\n for (const annotation of annotations) onRemove?.(annotation.id);\n }}\n >\n <XIcon className=\"size-3.5\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </span>\n {open ? (\n <AnnotationSourceRootBridge triggerRef={triggerRef}>\n <Suspense fallback={null}>\n <TimelineAnnotationsDialog\n annotations={annotations}\n editable={editable}\n focusAnnotationId={focusAnnotationId}\n onFocusConsumed={onFocusConsumed}\n onUpdate={onUpdate}\n onRemove={onRemove}\n onRevealSource={onRevealSource}\n triggerRef={triggerRef}\n countLabel={countLabel}\n onDismiss={dismiss}\n onCommit={() => {\n dismiss(!onCommit);\n onCommit?.();\n }}\n />\n </Suspense>\n </AnnotationSourceRootBridge>\n ) : null}\n </span>\n );\n}\n\nexport default TimelineAnnotationsChip;\n","import type { ComposerState } from \"../hooks/use-composer\";\n\n/**\n * Decide whether checking out a queued prompt would replace current composer\n * content. `hasDraftContent` reads the synchronous draft refs, so this stays\n * correct even when a controlled input update has not rendered yet.\n */\nexport function requestQueueDraftEdit(\n composer: Pick<ComposerState, \"hasDraftContent\">,\n confirmReplacement: () => void,\n editImmediately: () => void,\n): void {\n if (composer.hasDraftContent()) {\n confirmReplacement();\n } else {\n editImmediately();\n }\n}\n","import { Loader2Icon, RotateCwIcon } from \"lucide-react\";\n\nimport type { UseTurnQueueResult } from \"../hooks/use-turn-queue\";\nimport { useErrorMessage } from \"../lib/error-message\";\n\ntype QueueStateProps = {\n queue: UseTurnQueueResult;\n};\n\nexport function EmptyQueueStateSurface({ queue }: QueueStateProps) {\n const hasError = Boolean(queue.error || queue.mutationError);\n return (\n <div\n className=\"og-root mx-auto mb-2 w-full max-w-3xl shrink-0 px-4 sm:px-6\"\n data-testid=\"queue-surface\"\n >\n <div className=\"overflow-hidden rounded-lg border border-border bg-surface/80 shadow-sm\">\n {queue.stoppingPreviousAttempt ? (\n <QueueStoppingStatus queue={queue} dividerAfter={hasError} />\n ) : null}\n {hasError ? <QueueErrorAlert queue={queue} /> : null}\n </div>\n </div>\n );\n}\n\nexport function QueueStoppingStatus({\n queue,\n dividerAfter = false,\n}: QueueStateProps & { dividerAfter?: boolean }) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`flex min-h-11 items-center gap-2.5 bg-status-waiting/[0.07] px-3 py-2 text-og-control text-fg ${\n dividerAfter ? \"border-b border-status-waiting/20\" : \"\"\n }`}\n data-testid=\"stopping-previous-attempt\"\n >\n <Loader2Icon\n aria-hidden=\"true\"\n className=\"size-3.5 shrink-0 animate-spin text-status-waiting motion-reduce:animate-none\"\n />\n <span className=\"min-w-0\">\n <span className=\"font-medium\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Stopping current attempt…\"\n : \"Stopping previous attempt…\"}\n </span>{\" \"}\n <span className=\"text-fg-muted\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Queued work stays saved until you resume.\"\n : \"Queued work is saved and starts automatically.\"}\n </span>\n </span>\n </div>\n );\n}\n\nexport function QueueErrorAlert({\n queue,\n dividerBefore = false,\n}: QueueStateProps & { dividerBefore?: boolean }) {\n const formatError = useErrorMessage();\n return (\n <div className={`${dividerBefore ? \"border-t border-border\" : \"\"} p-2`}>\n <div\n role=\"alert\"\n className=\"flex min-w-0 max-w-full flex-wrap items-start gap-2 rounded-md bg-status-failed/10 px-2 py-1.5 text-og-control text-status-failed\"\n >\n <span\n role=\"region\"\n aria-label=\"Queue error details\"\n tabIndex={0}\n className=\"max-h-[min(5rem,20dvh)] min-w-0 max-w-full flex-[1_1_5rem] overflow-auto overscroll-contain whitespace-pre-wrap rounded-sm outline-hidden [overflow-wrap:anywhere] [unicode-bidi:plaintext] focus-visible:ring-2 focus-visible:ring-ring/40\"\n data-testid=\"queue-error-message\"\n dir=\"auto\"\n >\n {formatError(queue.mutationError ?? queue.error)}\n </span>\n <button\n type=\"button\"\n onClick={() => {\n queue.clearMutationError();\n void queue.refresh();\n }}\n aria-label=\"Dismiss queue error and retry\"\n title=\"Retry loading the queue\"\n className=\"ms-auto inline-flex size-7 shrink-0 items-center justify-center self-start rounded-md outline-hidden transition-colors hover:bg-surface-3 focus-visible:ring-2 focus-visible:ring-ring/40 motion-reduce:transition-none pointer-coarse:size-[44px]\"\n >\n <RotateCwIcon className=\"size-3.5\" />\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,WAAW,aAAa;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAyCH,cAgCU,YAhCV;AApBJ,IAAM,4BAA4B,KAAK,MAAM,OAAO,2CAA+B,CAAC;AAEpF,SAAS,2BAA2B;AAAA,EAClC;AAAA,EACA;AACF,GAGG;AACD,QAAM,gBAAgB,gCAAgC;AACtD,QAAM,sBAAsB,OAA2B,IAAI;AAC3D,MAAI,CAAC,eAAe;AAClB,wBAAoB,UAAU,4BAA4B,WAAW,OAAO;AAAA,EAC9E;AACA,kBAAgB,MAAM;AACpB,QAAI,cAAe;AACnB,wBAAoB,UAAU,4BAA4B,WAAW,OAAO;AAAA,EAC9E,CAAC;AACD,MAAI,cAAe,QAAO;AAC1B,SACE,oBAAC,oCAAoC,UAApC,EAA6C,OAAO,qBAClD,UACH;AAEJ;AAEO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAwB,IAAI;AACtE,MAAI,YAAY,WAAW,EAAG,QAAO;AACrC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,4BAAyB;AAAA,MACzB,WAAW;AAAA,QACT;AAAA,QACA,YAAY,UAAU,mCACpB;AAAA,QACF;AAAA,MACF;AAAA,MAEC,sBAAY,IAAI,CAAC,YAAY,UAAU;AACtC,cAAM,UAAU,yBAAyB,YAAY,KAAK;AAC1D,eACE,oBAAC,aAA4B,cAAY,cAAc,OAAO,IAC5D,+BAAC,uBACC;AAAA,+BAAC,OAAE,WAAU,gEAA+D;AAAA;AAAA,YAC9D;AAAA,aACd;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,OAAO;AAAA,cACP;AAAA,cACA,eAAe;AAAA;AAAA,UACjB;AAAA,UACC,kBAAkB,WAAW,KAC5B,oBAAC,OAAE,MAAK,UAAS,WAAU,qCAAoC,2DAE/D,IACE;AAAA,UACJ;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,WAAW;AAAA,cACjB,cAAc,WAAW;AAAA,cACzB;AAAA;AAAA,UACF;AAAA,WACF,KArBY,WAAW,EAsBzB;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AACF,GAaG;AACD,QAAM,iBAAiB;AAAA,IACrB,qBAAqB,YAAY,KAAK,CAAC,SAAS,KAAK,OAAO,iBAAiB;AAAA,EAC/E;AACA,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,cAAc;AAC/C,QAAM,aAAa,OAAiC,IAAI;AACxD,QAAM,gBAAgB,OAAsB,iBAAkB,qBAAqB,OAAQ,IAAI;AAE/F,YAAU,MAAM;AACd,QAAI,CAAC,kBAAkB,CAAC,mBAAmB;AACzC,UAAI,CAAC,eAAgB,eAAc,UAAU;AAC7C;AAAA,IACF;AACA,QAAI,cAAc,YAAY,kBAAmB;AACjD,kBAAc,UAAU;AACxB,YAAQ,IAAI;AAAA,EACd,GAAG,CAAC,mBAAmB,cAAc,CAAC;AAEtC,MAAI,YAAY,WAAW,EAAG,QAAO;AACrC,QAAM,aAAa,GAAG,YAAY,MAAM,IAAI,YAAY,WAAW,IAAI,eAAe,aAAa;AACnG,QAAM,aAAa,YAAY,KAAK,CAAC,eAAe,CAAC,kBAAkB,WAAW,IAAI,CAAC;AACvF,QAAM,WAAW,QAAQ,YAAY,QAAQ;AAE7C,QAAM,UAAU,CAAC,iBAA0B;AACzC,YAAQ,KAAK;AACb,sBAAkB;AAClB,QAAI,aAAc,YAAW,SAAS,MAAM;AAAA,EAC9C;AAEA,SACE,qBAAC,UAAK,WAAW,GAAG,uCAAuC,SAAS,GAClE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,aAAa,6CAA6C;AAAA,QAC5D;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,MAAK;AAAA,cACL,WAAW;AAAA,gBACT;AAAA,gBACA,UAAU,8BAA8B;AAAA,gBACxC,WAAW,gBAAgB;AAAA,cAC7B;AAAA,cACA,cAAY,UAAU,UAAU;AAAA,cAChC,iBAAc;AAAA,cACd,iBAAe;AAAA,cACf,SAAS,MAAM,QAAQ,CAAC,YAAY,CAAC,OAAO;AAAA,cAE5C;AAAA,oCAAC,aAAU,WAAU,oCAAmC,eAAY,QAAO;AAAA,gBAC3E,oBAAC,UAAK,WAAU,oBAAoB,sBAAW;AAAA;AAAA;AAAA,UACjD;AAAA,UACC,WACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,cAAW;AAAA,cACX,SAAS,MAAM;AACb,2BAAW,cAAc,YAAa,YAAW,WAAW,EAAE;AAAA,cAChE;AAAA,cAEA,8BAAC,SAAM,WAAU,YAAW,eAAY,QAAO;AAAA;AAAA,UACjD,IACE;AAAA;AAAA;AAAA,IACN;AAAA,IACC,OACC,oBAAC,8BAA2B,YAC1B,8BAAC,YAAS,UAAU,MAClB;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,UAAU,MAAM;AACd,kBAAQ,CAAC,QAAQ;AACjB,qBAAW;AAAA,QACb;AAAA;AAAA,IACF,GACF,GACF,IACE;AAAA,KACN;AAEJ;;;AC1NO,SAAS,sBACd,UACA,oBACA,iBACM;AACN,MAAI,SAAS,gBAAgB,GAAG;AAC9B,uBAAmB;AAAA,EACrB,OAAO;AACL,oBAAgB;AAAA,EAClB;AACF;;;ACjBA,SAAS,aAAa,oBAAoB;AAgBpC,SAEI,OAAAA,MAFJ,QAAAC,aAAA;AAPC,SAAS,uBAAuB,EAAE,MAAM,GAAoB;AACjE,QAAM,WAAW,QAAQ,MAAM,SAAS,MAAM,aAAa;AAC3D,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MAEZ,0BAAAC,MAAC,SAAI,WAAU,2EACZ;AAAA,cAAM,0BACL,gBAAAD,KAAC,uBAAoB,OAAc,cAAc,UAAU,IACzD;AAAA,QACH,WAAW,gBAAAA,KAAC,mBAAgB,OAAc,IAAK;AAAA,SAClD;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,eAAe;AACjB,GAAiD;AAC/C,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,WAAW,iGACT,eAAe,sCAAsC,EACvD;AAAA,MACA,eAAY;AAAA,MAEZ;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA;AAAA,QACZ;AAAA,QACA,gBAAAC,MAAC,UAAK,WAAU,WACd;AAAA,0BAAAD,KAAC,UAAK,WAAU,eACb,gBAAM,kBAAkB,UAAU,WAC/B,mCACA,mCACN;AAAA,UAAQ;AAAA,UACR,gBAAAA,KAAC,UAAK,WAAU,iBACb,gBAAM,kBAAkB,UAAU,WAC/B,8CACA,kDACN;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,gBAAgB;AAClB,GAAkD;AAChD,QAAM,cAAc,gBAAgB;AACpC,SACE,gBAAAA,KAAC,SAAI,WAAW,GAAG,gBAAgB,2BAA2B,EAAE,QAC9D,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MAEV;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAW;AAAA,YACX,UAAU;AAAA,YACV,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,KAAI;AAAA,YAEH,sBAAY,MAAM,iBAAiB,MAAM,KAAK;AAAA;AAAA,QACjD;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM;AACb,oBAAM,mBAAmB;AACzB,mBAAK,MAAM,QAAQ;AAAA,YACrB;AAAA,YACA,cAAW;AAAA,YACX,OAAM;AAAA,YACN,WAAU;AAAA,YAEV,0BAAAA,KAAC,gBAAa,WAAU,YAAW;AAAA;AAAA,QACrC;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":["jsx","jsxs"]}
|