@opengeni/react 7.4.0-canary.36855269964001 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +3 -48
  2. package/dist/artifacts-document.js +2 -3
  3. package/dist/artifacts-presentation.js +2 -3
  4. package/dist/artifacts-spreadsheet.js +2 -2
  5. package/dist/artifacts.d.ts +0 -1
  6. package/dist/artifacts.js +1402 -505
  7. package/dist/artifacts.js.map +1 -1
  8. package/dist/{browser-viewer-R6KK5VKR.js → browser-viewer-2E6R2Y4W.js} +4 -4
  9. package/dist/{chunk-WUISZ3WU.js → chunk-3E2AITTZ.js} +28 -32
  10. package/dist/{chunk-WUISZ3WU.js.map → chunk-3E2AITTZ.js.map} +1 -1
  11. package/dist/{chunk-PWUILT2U.js → chunk-5AZSK6MV.js} +2 -2
  12. package/dist/{chunk-Y2PRMYLC.js → chunk-DUEBTL3N.js} +3 -4
  13. package/dist/{chunk-Y2PRMYLC.js.map → chunk-DUEBTL3N.js.map} +1 -1
  14. package/dist/{chunk-7UAMYXJY.js → chunk-KNDIXZN6.js} +18 -25
  15. package/dist/{chunk-7UAMYXJY.js.map → chunk-KNDIXZN6.js.map} +1 -1
  16. package/dist/{chunk-P4G6K2E2.js → chunk-L4OSXQ6H.js} +884 -1119
  17. package/dist/chunk-L4OSXQ6H.js.map +1 -0
  18. package/dist/{chunk-LLIH7Q4B.js → chunk-S5JQ4R22.js} +19 -47
  19. package/dist/chunk-S5JQ4R22.js.map +1 -0
  20. package/dist/{chunk-A4UJB2MM.js → chunk-SEEVCT36.js} +2 -2
  21. package/dist/{chunk-UXJCQ5GH.js → chunk-UDD6DLLT.js} +1 -6
  22. package/dist/chunk-UDD6DLLT.js.map +1 -0
  23. package/dist/chunk-UGMKPUEM.js +299 -0
  24. package/dist/chunk-UGMKPUEM.js.map +1 -0
  25. package/dist/{chunk-ZCZHKJKZ.js → chunk-USXVQACU.js} +3 -3
  26. package/dist/{chunk-VABBF52G.js → chunk-V2ABIVYJ.js} +6 -70
  27. package/dist/chunk-V2ABIVYJ.js.map +1 -0
  28. package/dist/{chunk-TVO6GXR6.js → chunk-X4HIN6TV.js} +162 -71
  29. package/dist/chunk-X4HIN6TV.js.map +1 -0
  30. package/dist/{chunk-IIDEIBMC.js → chunk-XEJEOAOV.js} +38 -49
  31. package/dist/chunk-XEJEOAOV.js.map +1 -0
  32. package/dist/{chunk-ZKLCPBWN.js → chunk-Y3QTZN2F.js} +5 -5
  33. package/dist/{chunk-73BUNGLF.js → chunk-YZ3YYMOM.js} +1 -1
  34. package/dist/components/artifacts/editable-artifact-ui.d.ts +1 -2
  35. package/dist/components/artifacts/index.d.ts +0 -7
  36. package/dist/components/browser-select-control.d.ts +1 -3
  37. package/dist/components/message-timeline.d.ts +1 -18
  38. package/dist/components/open-geni-links.d.ts +0 -16
  39. package/dist/components/session-conversation.d.ts +1 -20
  40. package/dist/composer.js +3 -3
  41. package/dist/{computer-viewer-DJHPSP2J.js → computer-viewer-WMJE6OA3.js} +3 -3
  42. package/dist/connect.js +6 -7
  43. package/dist/connect.js.map +1 -1
  44. package/dist/hooks/latest-question.d.ts +1 -1
  45. package/dist/index.d.ts +2 -5
  46. package/dist/index.js +28 -39
  47. package/dist/index.js.map +1 -1
  48. package/dist/interaction.js +4 -4
  49. package/dist/{latest-question-KGCDK3XX.js → latest-question-QB4EUCW5.js} +3 -3
  50. package/dist/lib/format.d.ts +0 -3
  51. package/dist/machines.js +2 -2
  52. package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-PFUEZ2U4.js} +5 -37
  53. package/dist/markdown-table-layout-PFUEZ2U4.js.map +1 -0
  54. package/dist/{sandbox-files-4PMXDSDV.js → sandbox-files-PXPIZAFG.js} +2 -2
  55. package/dist/session-ui.d.ts +2 -5
  56. package/dist/session-ui.js +13 -23
  57. package/dist/session-ui.js.map +1 -1
  58. package/dist/session.js +3 -3
  59. package/dist/sites.js +289 -4
  60. package/dist/sites.js.map +1 -1
  61. package/dist/timeline/types.d.ts +1 -7
  62. package/dist/{timeline-annotation-selection-DMLMM2TX.js → timeline-annotation-selection-ODLVF4OI.js} +1 -6
  63. package/dist/timeline-annotation-selection-ODLVF4OI.js.map +1 -0
  64. package/package.json +3 -7
  65. package/src/artifacts.ts +0 -37
  66. package/src/components/artifacts/editable-artifact-ui.tsx +1 -3
  67. package/src/components/artifacts/editable-artifact-workbench.tsx +2 -5
  68. package/src/components/artifacts/editable-document.tsx +36 -34
  69. package/src/components/artifacts/editable-presentation.tsx +16 -21
  70. package/src/components/artifacts/index.ts +0 -41
  71. package/src/components/browser-select-control.tsx +1 -4
  72. package/src/components/browser-viewer.tsx +22 -81
  73. package/src/components/computer-viewer.tsx +23 -51
  74. package/src/components/markdown-table-layout.ts +5 -49
  75. package/src/components/markdown.tsx +2 -5
  76. package/src/components/message-timeline.tsx +434 -515
  77. package/src/components/open-geni-links.tsx +0 -24
  78. package/src/components/session-conversation.tsx +20 -131
  79. package/src/components/timeline-annotation-selection.tsx +0 -7
  80. package/src/hooks/use-available-models.ts +1 -1
  81. package/src/index.ts +0 -9
  82. package/src/lib/format.ts +0 -13
  83. package/src/session-ui.ts +0 -9
  84. package/src/timeline/projection.ts +4 -78
  85. package/src/timeline/types.ts +0 -7
  86. package/styles/compiled.css +0 -325
  87. package/dist/chat-interactive-block-VAGABN7J.js +0 -11
  88. package/dist/chunk-5CVXZA3Y.js +0 -292
  89. package/dist/chunk-5CVXZA3Y.js.map +0 -1
  90. package/dist/chunk-B3V6TG77.js +0 -41
  91. package/dist/chunk-B3V6TG77.js.map +0 -1
  92. package/dist/chunk-IIDEIBMC.js.map +0 -1
  93. package/dist/chunk-LLIH7Q4B.js.map +0 -1
  94. package/dist/chunk-P4G6K2E2.js.map +0 -1
  95. package/dist/chunk-RAIQYITC.js +0 -1772
  96. package/dist/chunk-RAIQYITC.js.map +0 -1
  97. package/dist/chunk-SCOTPE2I.js +0 -589
  98. package/dist/chunk-SCOTPE2I.js.map +0 -1
  99. package/dist/chunk-TVO6GXR6.js.map +0 -1
  100. package/dist/chunk-UXJCQ5GH.js.map +0 -1
  101. package/dist/chunk-VABBF52G.js.map +0 -1
  102. package/dist/chunk-WEHMPOXK.js +0 -39
  103. package/dist/chunk-WEHMPOXK.js.map +0 -1
  104. package/dist/chunk-XCHWDJ22.js +0 -107
  105. package/dist/chunk-XCHWDJ22.js.map +0 -1
  106. package/dist/components/artifacts/artifact-chrome.d.ts +0 -120
  107. package/dist/components/artifacts/artifact-sandbox.d.ts +0 -27
  108. package/dist/components/artifacts/chat-interactive-block.d.ts +0 -29
  109. package/dist/components/artifacts/deferred-chat-media.d.ts +0 -15
  110. package/dist/components/artifacts/editable-artifact-view.d.ts +0 -46
  111. package/dist/components/artifacts/latest-task-runner.d.ts +0 -15
  112. package/dist/components/artifacts/session-artifact-viewer.d.ts +0 -39
  113. package/dist/components/artifacts/site-view.d.ts +0 -23
  114. package/dist/components/timeline-pill-geometry.d.ts +0 -6
  115. package/dist/components/timeline-pill-placement.d.ts +0 -18
  116. package/dist/components/usage-limit-notice.d.ts +0 -49
  117. package/dist/components/usage-member-list.d.ts +0 -91
  118. package/dist/components/usage-meter.d.ts +0 -73
  119. package/dist/hooks/use-usage.d.ts +0 -40
  120. package/dist/markdown-table-layout-QXSLK4BY.js.map +0 -1
  121. package/dist/sandbox-files-4PMXDSDV.js.map +0 -1
  122. package/dist/timeline/allowance-exhausted-row.d.ts +0 -24
  123. package/dist/timeline-annotation-selection-DMLMM2TX.js.map +0 -1
  124. package/dist/timeline-pill-geometry-2G6EK47V.js +0 -73
  125. package/dist/timeline-pill-geometry-2G6EK47V.js.map +0 -1
  126. package/dist/usage/allowance-copy.d.ts +0 -25
  127. package/dist/usage/summary.d.ts +0 -35
  128. package/dist/usage.d.ts +0 -13
  129. package/dist/usage.js +0 -1073
  130. package/dist/usage.js.map +0 -1
  131. package/src/components/artifacts/artifact-chrome.tsx +0 -413
  132. package/src/components/artifacts/artifact-sandbox.tsx +0 -185
  133. package/src/components/artifacts/chat-interactive-block.tsx +0 -260
  134. package/src/components/artifacts/deferred-chat-media.tsx +0 -67
  135. package/src/components/artifacts/editable-artifact-view.tsx +0 -187
  136. package/src/components/artifacts/latest-task-runner.ts +0 -49
  137. package/src/components/artifacts/session-artifact-viewer.tsx +0 -376
  138. package/src/components/artifacts/site-view.tsx +0 -116
  139. package/src/components/timeline-pill-geometry.ts +0 -112
  140. package/src/components/timeline-pill-placement.ts +0 -81
  141. package/src/components/usage-limit-notice.tsx +0 -179
  142. package/src/components/usage-member-list.tsx +0 -792
  143. package/src/components/usage-meter.tsx +0 -382
  144. package/src/hooks/use-usage.ts +0 -100
  145. package/src/timeline/allowance-exhausted-row.tsx +0 -86
  146. package/src/usage/allowance-copy.ts +0 -64
  147. package/src/usage/summary.ts +0 -93
  148. package/src/usage.ts +0 -50
  149. /package/dist/{browser-viewer-R6KK5VKR.js.map → browser-viewer-2E6R2Y4W.js.map} +0 -0
  150. /package/dist/{chunk-PWUILT2U.js.map → chunk-5AZSK6MV.js.map} +0 -0
  151. /package/dist/{chunk-A4UJB2MM.js.map → chunk-SEEVCT36.js.map} +0 -0
  152. /package/dist/{chunk-ZCZHKJKZ.js.map → chunk-USXVQACU.js.map} +0 -0
  153. /package/dist/{chunk-ZKLCPBWN.js.map → chunk-Y3QTZN2F.js.map} +0 -0
  154. /package/dist/{chunk-73BUNGLF.js.map → chunk-YZ3YYMOM.js.map} +0 -0
  155. /package/dist/{chat-interactive-block-VAGABN7J.js.map → computer-viewer-WMJE6OA3.js.map} +0 -0
  156. /package/dist/{latest-question-KGCDK3XX.js.map → latest-question-QB4EUCW5.js.map} +0 -0
  157. /package/dist/{computer-viewer-DJHPSP2J.js.map → sandbox-files-PXPIZAFG.js.map} +0 -0
package/dist/sites.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/sites-ui.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport type {\n OpenGeniClient,\n WorkspaceArtifact,\n WorkspaceArtifactContentResponse,\n WorkspaceArtifactDetailResponse,\n WorkspaceArtifactListResponse,\n} from \"@opengeni/sdk\";\nimport {\n PublishedHtmlArtifactFrame,\n type PublishedHtmlArtifactToolBridge,\n} from \"./components/artifacts/published-html-artifact-frame\";\n\n/** Implement with an authenticated host proxy. Never put an organization key\n * in browser props; replace the client object when the host actor changes. */\nexport type SiteClient = Pick<\n OpenGeniClient,\n | \"listWorkspaceArtifacts\"\n | \"getWorkspaceArtifact\"\n | \"getWorkspaceArtifactHtml\"\n | \"rollbackWorkspaceArtifact\"\n | \"setWorkspaceArtifactStatus\"\n>;\ntype SiteDisplayContent = Pick<\n WorkspaceArtifactContentResponse,\n \"artifactId\" | \"versionId\" | \"html\" | \"requestedTools\"\n>;\ntype SiteScope = { client: SiteClient; workspaceId: string; className?: string };\n/** Shared native/embedded read boundary: pin content to the observed version,\n * and never accept a response belonging to another workspace or Site. */\nexport async function loadSiteSnapshot(\n client: Pick<SiteClient, \"getWorkspaceArtifact\" | \"getWorkspaceArtifactHtml\"> &\n Partial<Pick<OpenGeniClient, \"getWorkspaceArtifactContent\">>,\n workspaceId: string,\n siteId: string,\n options: { signal?: AbortSignal; includeArchivedContent?: boolean; versionId?: string } = {},\n): Promise<{\n detail: WorkspaceArtifactDetailResponse;\n content: SiteDisplayContent | null;\n}> {\n const requestOptions = options.signal ? { signal: options.signal } : {};\n const detail = await client.getWorkspaceArtifact(workspaceId, siteId, requestOptions);\n options.signal?.throwIfAborted();\n if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)\n throw new Error(\"Site scope mismatch\");\n const selectedVersion = options.versionId\n ? detail.versions.find((version) => version.id === options.versionId)\n : detail.artifact.currentVersion;\n const versionId = options.versionId ?? selectedVersion?.id;\n let content: SiteDisplayContent | null =\n selectedVersion &&\n versionId &&\n (detail.artifact.status === \"active\" || options.includeArchivedContent)\n ? {\n artifactId: siteId,\n versionId,\n requestedTools: selectedVersion!.requestedTools,\n html: await client.getWorkspaceArtifactHtml(workspaceId, siteId, {\n ...requestOptions,\n versionId,\n }),\n }\n : null;\n if (\n versionId &&\n !selectedVersion &&\n (detail.artifact.status === \"active\" || options.includeArchivedContent)\n ) {\n if (!client.getWorkspaceArtifactContent) throw new Error(\"Site version unavailable\");\n content = await client.getWorkspaceArtifactContent(workspaceId, siteId, {\n ...requestOptions,\n versionId,\n });\n }\n options.signal?.throwIfAborted();\n if (content && (content.artifactId !== siteId || content.versionId !== versionId))\n throw new Error(\"Site content mismatch\");\n return { detail: structuredClone(detail), content: content ? structuredClone(content) : null };\n}\nexport type SiteListProps = SiteScope & {\n status?: \"active\" | \"archived\";\n onOpen: (site: WorkspaceArtifact) => void;\n};\nexport type SiteDetailProps = SiteScope & {\n siteId: string;\n /** Presentation hint only: the backend still enforces artifacts:publish. */\n canPublish?: boolean;\n toolBridge?: PublishedHtmlArtifactToolBridge;\n};\n\nfunction useScopeKey(values: readonly unknown[]) {\n const [scope, setScope] = useState(values);\n const [generation, setGeneration] = useState(0);\n if (values.some((value, index) => value !== scope[index])) {\n setScope(values);\n setGeneration(generation + 1);\n }\n return generation;\n}\n\nexport function SiteList(props: SiteListProps) {\n const key = useScopeKey([props.client, props.workspaceId, props.status]);\n return <ScopedSiteList key={key} {...props} />;\n}\nfunction ScopedSiteList({\n client,\n workspaceId,\n status = \"active\",\n onOpen,\n className,\n}: SiteListProps) {\n const [page, setPage] = useState<WorkspaceArtifactListResponse | null>(null);\n const [cursor, setCursor] = useState<string | undefined>();\n const [error, setError] = useState(false);\n const [reload, setReload] = useState(0);\n useEffect(() => {\n const abort = new AbortController();\n setPage(null);\n setError(false);\n void Promise.resolve()\n .then(() =>\n client.listWorkspaceArtifacts(workspaceId, {\n status,\n ...(cursor ? { cursor } : {}),\n limit: 50,\n signal: abort.signal,\n }),\n )\n .then((result) => {\n if (!abort.signal.aborted) setPage(structuredClone(result));\n })\n .catch(() => {\n if (!abort.signal.aborted) setError(true);\n });\n return () => abort.abort();\n }, [client, workspaceId, status, cursor, reload]);\n return (\n <section className={className} aria-label=\"Sites\" aria-busy={!page && !error}>\n {error ? (\n <p role=\"alert\">Sites are unavailable or access has changed. Refresh to check access.</p>\n ) : !page ? (\n <p role=\"status\">Loading Sites…</p>\n ) : page.artifacts.length === 0 ? (\n <p role=\"status\">No {status} Sites.</p>\n ) : (\n <ul>\n {page.artifacts.map((site) => (\n <li key={site.id}>\n <button type=\"button\" onClick={() => onOpen(structuredClone(site))}>\n {site.title}\n </button>\n <p>{site.description}</p>\n <span>\n {site.status} · revision {site.currentVersion?.revision ?? \"unpublished\"}\n </span>\n </li>\n ))}\n </ul>\n )}\n {page?.nextCursor && (\n <button type=\"button\" onClick={() => setCursor(page.nextCursor!)}>\n Next page\n </button>\n )}\n {cursor && (\n <button type=\"button\" onClick={() => setCursor(undefined)}>\n First page\n </button>\n )}\n <button type=\"button\" onClick={() => setReload((value) => value + 1)}>\n Refresh Sites\n </button>\n </section>\n );\n}\n\nexport function SiteDetail(props: SiteDetailProps) {\n const key = useScopeKey([props.client, props.workspaceId, props.siteId]);\n return <ScopedSiteDetail key={key} {...props} />;\n}\nfunction ScopedSiteDetail({\n client,\n workspaceId,\n siteId,\n canPublish = false,\n toolBridge,\n className,\n}: SiteDetailProps) {\n const [loaded, setLoaded] = useState<{\n detail: WorkspaceArtifactDetailResponse;\n content: SiteDisplayContent | null;\n } | null>(null);\n const [error, setError] = useState(false);\n const [reload, setReload] = useState(0);\n const [busy, setBusy] = useState(false);\n const [rollbackId, setRollbackId] = useState(\"\");\n const [confirmation, setConfirmation] = useState<\"status\" | \"rollback\" | null>(null);\n const mutation = useRef<AbortController | null>(null);\n useEffect(() => () => mutation.current?.abort(), []);\n useEffect(() => {\n const abort = new AbortController();\n setLoaded(null);\n setError(false);\n setConfirmation(null);\n setRollbackId(\"\");\n void Promise.resolve()\n .then(async () => {\n const snapshot = await loadSiteSnapshot(client, workspaceId, siteId, {\n signal: abort.signal,\n });\n if (!abort.signal.aborted) setLoaded(snapshot);\n })\n .catch(() => {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n });\n return () => abort.abort();\n }, [client, workspaceId, siteId, reload]);\n // Recheck live read authority without rebuilding the iframe on every tick.\n // No overlapping polls, and failures remove the document and tool bridge.\n useEffect(() => {\n if (!loaded || busy) return;\n const abort = new AbortController();\n let checking = false;\n const timer = setInterval(() => {\n if (checking) return;\n checking = true;\n void Promise.resolve()\n .then(() => client.getWorkspaceArtifact(workspaceId, siteId, { signal: abort.signal }))\n .then((detail) => {\n if (abort.signal.aborted) return;\n if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)\n throw new Error(\"Site scope mismatch\");\n if (\n detail.artifact.currentVersion?.id !== loaded.detail.artifact.currentVersion?.id ||\n detail.artifact.status !== loaded.detail.artifact.status\n ) {\n setLoaded(null);\n setReload((value) => value + 1);\n }\n })\n .catch(() => {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n })\n .finally(() => {\n checking = false;\n });\n }, 15_000);\n return () => {\n abort.abort();\n clearInterval(timer);\n };\n }, [client, workspaceId, siteId, loaded, busy]);\n const commit = async () => {\n const current = loaded?.detail.artifact.currentVersion;\n if (!canPublish || !loaded || !current || !confirmation || mutation.current) return;\n const abort = new AbortController();\n mutation.current = abort;\n setBusy(true);\n try {\n const common = { expectedCurrentVersionId: current.id, idempotencyKey: crypto.randomUUID() };\n if (confirmation === \"rollback\") {\n if (!loaded.detail.versions.some((version) => version.id === rollbackId))\n throw new Error(\"Unknown version\");\n await client.rollbackWorkspaceArtifact(\n workspaceId,\n siteId,\n { ...common, versionId: rollbackId, reason: \"Restore explicitly selected Site version\" },\n { signal: abort.signal },\n );\n } else {\n await client.setWorkspaceArtifactStatus(\n workspaceId,\n siteId,\n {\n ...common,\n status: loaded.detail.artifact.status === \"active\" ? \"archived\" : \"active\",\n reason: \"Explicit Site status change\",\n },\n { signal: abort.signal },\n );\n }\n if (!abort.signal.aborted) {\n setLoaded(null);\n setReload((value) => value + 1);\n }\n } catch {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n } finally {\n if (!abort.signal.aborted) {\n mutation.current = null;\n setBusy(false);\n setConfirmation(null);\n }\n }\n };\n const site = loaded?.detail.artifact;\n return (\n <section\n className={className}\n aria-label=\"Site details\"\n aria-busy={busy || (!loaded && !error)}\n >\n {error && (\n <p role=\"alert\">\n Site state could not be confirmed or access has changed. Refresh before continuing.\n </p>\n )}\n {!loaded && !error && <p role=\"status\">Loading Site…</p>}\n {site && (\n <>\n <h2>{site.title}</h2>\n <p>{site.description}</p>\n <p>\n {site.status} · revision {site.currentVersion?.revision ?? \"unpublished\"}\n </p>\n {loaded.content && (\n <PublishedHtmlArtifactFrame\n html={loaded.content.html}\n title={site.title}\n {...(toolBridge ? { toolBridge } : {})}\n />\n )}\n <h3>Versions</h3>\n <ul>\n {loaded.detail.versions.map((version) => (\n <li key={version.id}>\n Revision {version.revision} · {version.createdAt}\n {version.id === site.currentVersion?.id ? \" · current\" : \"\"}\n </li>\n ))}\n </ul>\n {loaded.detail.versionsTruncated && (\n <p>Older versions are not included in this response.</p>\n )}\n {canPublish && site.currentVersion && (\n <fieldset disabled={busy}>\n <legend>Manage Site</legend>\n <button type=\"button\" onClick={() => setConfirmation(\"status\")}>\n {site.status === \"active\" ? \"Archive Site\" : \"Restore Site\"}\n </button>\n <label>\n Version to restore\n <select\n value={rollbackId}\n onChange={(event) => {\n setRollbackId(event.target.value);\n setConfirmation(null);\n }}\n >\n <option value=\"\">Choose a version</option>\n {loaded.detail.versions\n .filter((version) => version.id !== site.currentVersion?.id)\n .map((version) => (\n <option key={version.id} value={version.id}>\n Revision {version.revision}\n </option>\n ))}\n </select>\n </label>\n <button\n type=\"button\"\n disabled={!rollbackId}\n onClick={() => setConfirmation(\"rollback\")}\n >\n Review rollback\n </button>\n {confirmation && (\n <div role=\"group\" aria-label=\"Confirm Site change\">\n <p>\n {confirmation === \"rollback\"\n ? \"Make the selected version current?\"\n : site.status === \"active\"\n ? \"Archive this Site for workspace users?\"\n : \"Restore this Site for workspace users?\"}\n </p>\n <button type=\"button\" onClick={() => void commit()}>\n Confirm change\n </button>\n <button type=\"button\" onClick={() => setConfirmation(null)}>\n Keep current state\n </button>\n </div>\n )}\n </fieldset>\n )}\n </>\n )}\n <button type=\"button\" disabled={busy} onClick={() => setReload((value) => value + 1)}>\n Refresh Site\n </button>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import type { AllowanceExhaustedRefusal, HumanInputQuestion, HumanInputResponse, MediaGenerationResult, ResourceRef, SessionStatus, TimelineAnnotation, TimelineAnnotationSource, ToolAuthNeededPayload, ToolRef, ToolDisplayMetadata } from "@opengeni/sdk";
1
+ import type { HumanInputQuestion, HumanInputResponse, MediaGenerationResult, ResourceRef, SessionStatus, TimelineAnnotation, TimelineAnnotationSource, ToolAuthNeededPayload, ToolRef, ToolDisplayMetadata } from "@opengeni/sdk";
2
2
  export type TimelineAnnotationSourceDescriptor = Omit<TimelineAnnotationSource, "startOffset" | "endOffset" | "contextBefore" | "contextAfter"> & {
3
3
  text: string;
4
4
  };
@@ -309,12 +309,6 @@ export type NoticeItem = {
309
309
  label: string;
310
310
  url: string;
311
311
  };
312
- /**
313
- * A usage ceiling refused further work. `text` keeps the canonical sentence
314
- * for plain-text consumers; `MessageTimeline` renders this structured row
315
- * (customizable with `renderAllowanceExhausted` / `allowanceExhaustedLabels`).
316
- */
317
- allowance?: AllowanceExhaustedRefusal;
318
312
  occurredAt: string;
319
313
  };
320
314
  /**
@@ -133,7 +133,6 @@ function TimelineAnnotationSelection({
133
133
  }) {
134
134
  const [candidate, setCandidate] = useState(null);
135
135
  const buttonRef = useRef(null);
136
- const initialSelectionObservedRef = useRef(false);
137
136
  const pointerOriginRef = useRef("unset");
138
137
  const portalStyle = usePortalTokenStyle(rootRef.current);
139
138
  useEffect(() => {
@@ -145,10 +144,6 @@ function TimelineAnnotationSelection({
145
144
  const update = (keyboard) => {
146
145
  setCandidate(buildCandidate(root, sources, keyboard));
147
146
  };
148
- if (!initialSelectionObservedRef.current) {
149
- initialSelectionObservedRef.current = true;
150
- update(false);
151
- }
152
147
  const onRootPointerUp = (event) => {
153
148
  if (event.target instanceof Node && buttonRef.current?.contains(event.target)) return;
154
149
  if (pointerOriginRef.current === "outside") return;
@@ -238,4 +233,4 @@ export {
238
233
  TimelineAnnotationSelection,
239
234
  timeline_annotation_selection_default as default
240
235
  };
241
- //# sourceMappingURL=timeline-annotation-selection-DMLMM2TX.js.map
236
+ //# sourceMappingURL=timeline-annotation-selection-ODLVF4OI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/timeline-annotation-selection.tsx"],"sourcesContent":["import type { DraftTimelineAnnotation } from \"@opengeni/sdk\";\nimport { QuoteIcon } from \"lucide-react\";\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { usePortalTokenStyle } from \"../lib/use-portal-token-style\";\nimport type { TimelineAnnotationSourceDescriptor } from \"../timeline\";\nimport {\n clipRangeToSource,\n matchingQuoteInSource,\n occurrenceOffsets,\n quoteOccurrenceIndex,\n truncateAnnotationQuote,\n visibleClientRect,\n} from \"./timeline-annotation-shared\";\n\ntype SelectionCandidate = {\n annotation: DraftTimelineAnnotation;\n left: number;\n top: number;\n keyboard: boolean;\n};\n\nconst CONTROL_SELECTOR = \"button,input,textarea,select,summary,[contenteditable='true']\";\nconst SOURCE_CONTEXT_BYTES = 160;\nconst MAX_QUOTE_BYTES = 16 * 1024;\nconst POPOVER_WIDTH = 280;\nconst POPOVER_HEIGHT = 64;\n\nfunction utf8Prefix(value: string, maxBytes: number): string {\n let output = \"\";\n let bytes = 0;\n for (const character of value) {\n const next = new TextEncoder().encode(character).byteLength;\n if (bytes + next > maxBytes) break;\n output += character;\n bytes += next;\n }\n return output;\n}\n\nfunction utf8Suffix(value: string, maxBytes: number): string {\n let output = \"\";\n let bytes = 0;\n for (const character of [...value].reverse()) {\n const next = new TextEncoder().encode(character).byteLength;\n if (bytes + next > maxBytes) break;\n output = character + output;\n bytes += next;\n }\n return output;\n}\n\nfunction selectionElement(node: Node | null): Element | null {\n return node instanceof Element ? node : (node?.parentElement ?? null);\n}\n\nfunction containingSource(node: Node | null): HTMLElement | null {\n const element = selectionElement(node);\n const source = element?.closest(\"[data-og-annotation-source-key]\");\n return source instanceof HTMLElement ? source : null;\n}\n\nfunction resolveSourceBoundary(range: Range, root: HTMLElement): HTMLElement | null {\n const start = containingSource(range.startContainer);\n const end = containingSource(range.endContainer);\n if (start && end && start !== end) return null;\n const boundary = start ?? end;\n if (!boundary || !root.contains(boundary)) return null;\n return boundary;\n}\n\nfunction isWhollyInsideControl(range: Range, boundary: HTMLElement): boolean {\n const start = selectionElement(range.startContainer)?.closest(CONTROL_SELECTOR);\n const end = selectionElement(range.endContainer)?.closest(CONTROL_SELECTOR);\n return (\n start instanceof Element && start === end && boundary.contains(start) && start !== boundary\n );\n}\n\nfunction annotationId(): string {\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n return `annotation-${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction popoverPosition(rect: DOMRect): { left: number; top: number } {\n const half = POPOVER_WIDTH / 2;\n const left = clamp(rect.left + rect.width / 2, 12 + half, window.innerWidth - 12 - half);\n const preferBelow = rect.bottom + 8 + POPOVER_HEIGHT <= window.innerHeight - 12;\n const top = preferBelow ? rect.bottom + 8 : Math.max(12, rect.top - POPOVER_HEIGHT - 8);\n return { left, top };\n}\n\nfunction buildCandidate(\n root: HTMLElement,\n sources: ReadonlyMap<string, TimelineAnnotationSourceDescriptor>,\n keyboard: boolean,\n): SelectionCandidate | null {\n const selection = document.getSelection();\n if (!selection || selection.rangeCount !== 1 || selection.isCollapsed) return null;\n const range = selection.getRangeAt(0);\n const startBoundary = resolveSourceBoundary(range, root);\n if (!startBoundary) return null;\n if (isWhollyInsideControl(range, startBoundary)) return null;\n const clipped = clipRangeToSource(range, startBoundary);\n if (!clipped) return null;\n const sourceKey = startBoundary.dataset.ogAnnotationSourceKey;\n const source = sourceKey ? sources.get(sourceKey) : undefined;\n const rawQuote = clipped.toString();\n const quote = (source ? matchingQuoteInSource(source.text, rawQuote) : null) ?? rawQuote;\n if (\n !source ||\n quote.trim().length === 0 ||\n new TextEncoder().encode(quote).byteLength > MAX_QUOTE_BYTES\n ) {\n return null;\n }\n const sourceOffsets = occurrenceOffsets(source.text, quote);\n if (sourceOffsets.length === 0) return null;\n const occurrence = quoteOccurrenceIndex(startBoundary, clipped, quote);\n const startOffset = sourceOffsets[Math.min(occurrence, sourceOffsets.length - 1)]!;\n const endOffset = startOffset + quote.length;\n const rect = visibleClientRect(range) ?? visibleClientRect(clipped);\n if (!rect) return null;\n const position = popoverPosition(rect);\n return {\n annotation: {\n id: annotationId(),\n quote,\n note: \"\",\n source: {\n kind: source.kind,\n eventId: source.eventId,\n eventType: source.eventType,\n sequence: source.sequence,\n turnId: source.turnId,\n startOffset,\n endOffset,\n contextBefore: utf8Suffix(source.text.slice(0, startOffset), SOURCE_CONTEXT_BYTES),\n contextAfter: utf8Prefix(source.text.slice(endOffset), SOURCE_CONTEXT_BYTES),\n ...(source.label ? { label: source.label } : {}),\n },\n },\n left: position.left,\n top: position.top,\n keyboard,\n };\n}\n\nexport function TimelineAnnotationSelection({\n rootRef,\n sources,\n onAnnotate,\n}: {\n rootRef: RefObject<HTMLElement | null>;\n sources: ReadonlyMap<string, TimelineAnnotationSourceDescriptor>;\n onAnnotate?: ((annotation: DraftTimelineAnnotation) => void) | undefined;\n}) {\n const [candidate, setCandidate] = useState<SelectionCandidate | null>(null);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n const pointerOriginRef = useRef<\"unset\" | \"inside\" | \"outside\">(\"unset\");\n const portalStyle = usePortalTokenStyle(rootRef.current);\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root || !onAnnotate) {\n setCandidate(null);\n return;\n }\n const update = (keyboard: boolean) => {\n setCandidate(buildCandidate(root, sources, keyboard));\n };\n const onRootPointerUp = (event: PointerEvent) => {\n if (event.target instanceof Node && buttonRef.current?.contains(event.target)) return;\n // Tests may fire only pointerup on the source. A real click that started\n // outside the timeline must not resurrect leftover selection.\n if (pointerOriginRef.current === \"outside\") return;\n window.setTimeout(() => update(false), 0);\n };\n const onDocumentPointerUp = (event: PointerEvent) => {\n if (event.target instanceof Node && buttonRef.current?.contains(event.target)) return;\n const startedInRoot = pointerOriginRef.current === \"inside\";\n pointerOriginRef.current = \"unset\";\n if (!startedInRoot) return;\n window.setTimeout(() => update(false), 0);\n };\n const onKeyUp = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setCandidate(null);\n return;\n }\n window.setTimeout(() => update(true), 0);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (event.target instanceof Node && buttonRef.current?.contains(event.target)) {\n event.preventDefault();\n return;\n }\n pointerOriginRef.current =\n event.target instanceof Node && root.contains(event.target) ? \"inside\" : \"outside\";\n setCandidate(null);\n };\n const onDocumentKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setCandidate(null);\n };\n const onSelectionChange = () => {\n if (buttonRef.current && document.activeElement === buttonRef.current) return;\n const selection = document.getSelection();\n if (!selection || selection.isCollapsed) setCandidate(null);\n };\n root.addEventListener(\"pointerup\", onRootPointerUp);\n root.addEventListener(\"keyup\", onKeyUp);\n document.addEventListener(\"pointerup\", onDocumentPointerUp);\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onDocumentKeyDown);\n document.addEventListener(\"selectionchange\", onSelectionChange);\n return () => {\n root.removeEventListener(\"pointerup\", onRootPointerUp);\n root.removeEventListener(\"keyup\", onKeyUp);\n document.removeEventListener(\"pointerup\", onDocumentPointerUp);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onDocumentKeyDown);\n document.removeEventListener(\"selectionchange\", onSelectionChange);\n };\n }, [onAnnotate, rootRef, sources]);\n\n useEffect(() => {\n if (candidate?.keyboard) buttonRef.current?.focus();\n }, [candidate]);\n\n if (!candidate || !onAnnotate || typeof document === \"undefined\") return null;\n const preview = truncateAnnotationQuote(candidate.annotation.quote, 72);\n return createPortal(\n <button\n ref={buttonRef}\n type=\"button\"\n data-og-annotation-popover=\"\"\n style={{ left: candidate.left, top: candidate.top, ...portalStyle }}\n className=\"og-root fixed z-[80] flex max-w-[min(18rem,calc(100vw-1.5rem))] -translate-x-1/2 items-start gap-2 rounded-2xl border border-og-border bg-og-surface-1 px-3 py-2 text-og-sm font-medium text-og-fg shadow-xl outline-hidden transition hover:border-og-accent/40 hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\"\n aria-label={`Add a note about “${preview}”`}\n title={candidate.annotation.quote}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => {\n onAnnotate(candidate.annotation);\n document.getSelection()?.removeAllRanges();\n setCandidate(null);\n }}\n >\n <QuoteIcon className=\"mt-0.5 size-3.5 shrink-0 text-og-accent\" aria-hidden=\"true\" />\n <span className=\"min-w-0 text-left\">\n <span className=\"block leading-5\">Add note</span>\n <span className=\"mt-0.5 block truncate text-og-xs font-normal text-og-fg-muted\">\n {preview}\n </span>\n </span>\n </button>,\n document.body,\n );\n}\n\nexport default TimelineAnnotationSelection;\n"],"mappings":";;;;;;;;;;;;;AACA,SAAS,iBAAiB;AAC1B,SAAS,WAAW,QAAQ,gBAAgC;AAC5D,SAAS,oBAAoB;AA0PvB,cACA,YADA;AAvON,IAAM,mBAAmB;AACzB,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB,KAAK;AAC7B,IAAM,gBAAgB;AACtB,IAAM,iBAAiB;AAEvB,SAAS,WAAW,OAAe,UAA0B;AAC3D,MAAI,SAAS;AACb,MAAI,QAAQ;AACZ,aAAW,aAAa,OAAO;AAC7B,UAAM,OAAO,IAAI,YAAY,EAAE,OAAO,SAAS,EAAE;AACjD,QAAI,QAAQ,OAAO,SAAU;AAC7B,cAAU;AACV,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAe,UAA0B;AAC3D,MAAI,SAAS;AACb,MAAI,QAAQ;AACZ,aAAW,aAAa,CAAC,GAAG,KAAK,EAAE,QAAQ,GAAG;AAC5C,UAAM,OAAO,IAAI,YAAY,EAAE,OAAO,SAAS,EAAE;AACjD,QAAI,QAAQ,OAAO,SAAU;AAC7B,aAAS,YAAY;AACrB,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAmC;AAC3D,SAAO,gBAAgB,UAAU,OAAQ,MAAM,iBAAiB;AAClE;AAEA,SAAS,iBAAiB,MAAuC;AAC/D,QAAM,UAAU,iBAAiB,IAAI;AACrC,QAAM,SAAS,SAAS,QAAQ,iCAAiC;AACjE,SAAO,kBAAkB,cAAc,SAAS;AAClD;AAEA,SAAS,sBAAsB,OAAc,MAAuC;AAClF,QAAM,QAAQ,iBAAiB,MAAM,cAAc;AACnD,QAAM,MAAM,iBAAiB,MAAM,YAAY;AAC/C,MAAI,SAAS,OAAO,UAAU,IAAK,QAAO;AAC1C,QAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,YAAY,CAAC,KAAK,SAAS,QAAQ,EAAG,QAAO;AAClD,SAAO;AACT;AAEA,SAAS,sBAAsB,OAAc,UAAgC;AAC3E,QAAM,QAAQ,iBAAiB,MAAM,cAAc,GAAG,QAAQ,gBAAgB;AAC9E,QAAM,MAAM,iBAAiB,MAAM,YAAY,GAAG,QAAQ,gBAAgB;AAC1E,SACE,iBAAiB,WAAW,UAAU,OAAO,SAAS,SAAS,KAAK,KAAK,UAAU;AAEvF;AAEA,SAAS,eAAuB;AAC9B,MAAI,OAAO,WAAW,QAAQ,eAAe,YAAY;AACvD,WAAO,WAAW,OAAO,WAAW;AAAA,EACtC;AACA,SAAO,cAAc,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AACxE;AAEA,SAAS,MAAM,OAAe,KAAa,KAAqB;AAC9D,SAAO,KAAK,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,GAAG;AAC3C;AAEA,SAAS,gBAAgB,MAA8C;AACrE,QAAM,OAAO,gBAAgB;AAC7B,QAAM,OAAO,MAAM,KAAK,OAAO,KAAK,QAAQ,GAAG,KAAK,MAAM,OAAO,aAAa,KAAK,IAAI;AACvF,QAAM,cAAc,KAAK,SAAS,IAAI,kBAAkB,OAAO,cAAc;AAC7E,QAAM,MAAM,cAAc,KAAK,SAAS,IAAI,KAAK,IAAI,IAAI,KAAK,MAAM,iBAAiB,CAAC;AACtF,SAAO,EAAE,MAAM,IAAI;AACrB;AAEA,SAAS,eACP,MACA,SACA,UAC2B;AAC3B,QAAM,YAAY,SAAS,aAAa;AACxC,MAAI,CAAC,aAAa,UAAU,eAAe,KAAK,UAAU,YAAa,QAAO;AAC9E,QAAM,QAAQ,UAAU,WAAW,CAAC;AACpC,QAAM,gBAAgB,sBAAsB,OAAO,IAAI;AACvD,MAAI,CAAC,cAAe,QAAO;AAC3B,MAAI,sBAAsB,OAAO,aAAa,EAAG,QAAO;AACxD,QAAM,UAAU,kBAAkB,OAAO,aAAa;AACtD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,YAAY,cAAc,QAAQ;AACxC,QAAM,SAAS,YAAY,QAAQ,IAAI,SAAS,IAAI;AACpD,QAAM,WAAW,QAAQ,SAAS;AAClC,QAAM,SAAS,SAAS,sBAAsB,OAAO,MAAM,QAAQ,IAAI,SAAS;AAChF,MACE,CAAC,UACD,MAAM,KAAK,EAAE,WAAW,KACxB,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE,aAAa,iBAC7C;AACA,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,kBAAkB,OAAO,MAAM,KAAK;AAC1D,MAAI,cAAc,WAAW,EAAG,QAAO;AACvC,QAAM,aAAa,qBAAqB,eAAe,SAAS,KAAK;AACrE,QAAM,cAAc,cAAc,KAAK,IAAI,YAAY,cAAc,SAAS,CAAC,CAAC;AAChF,QAAM,YAAY,cAAc,MAAM;AACtC,QAAM,OAAO,kBAAkB,KAAK,KAAK,kBAAkB,OAAO;AAClE,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,WAAW,gBAAgB,IAAI;AACrC,SAAO;AAAA,IACL,YAAY;AAAA,MACV,IAAI,aAAa;AAAA,MACjB;AAAA,MACA,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM,OAAO;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,WAAW,OAAO;AAAA,QAClB,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO;AAAA,QACf;AAAA,QACA;AAAA,QACA,eAAe,WAAW,OAAO,KAAK,MAAM,GAAG,WAAW,GAAG,oBAAoB;AAAA,QACjF,cAAc,WAAW,OAAO,KAAK,MAAM,SAAS,GAAG,oBAAoB;AAAA,QAC3E,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,IACA,MAAM,SAAS;AAAA,IACf,KAAK,SAAS;AAAA,IACd;AAAA,EACF;AACF;AAEO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAoC,IAAI;AAC1E,QAAM,YAAY,OAAiC,IAAI;AACvD,QAAM,mBAAmB,OAAuC,OAAO;AACvE,QAAM,cAAc,oBAAoB,QAAQ,OAAO;AAEvD,YAAU,MAAM;AACd,UAAM,OAAO,QAAQ;AACrB,QAAI,CAAC,QAAQ,CAAC,YAAY;AACxB,mBAAa,IAAI;AACjB;AAAA,IACF;AACA,UAAM,SAAS,CAAC,aAAsB;AACpC,mBAAa,eAAe,MAAM,SAAS,QAAQ,CAAC;AAAA,IACtD;AACA,UAAM,kBAAkB,CAAC,UAAwB;AAC/C,UAAI,MAAM,kBAAkB,QAAQ,UAAU,SAAS,SAAS,MAAM,MAAM,EAAG;AAG/E,UAAI,iBAAiB,YAAY,UAAW;AAC5C,aAAO,WAAW,MAAM,OAAO,KAAK,GAAG,CAAC;AAAA,IAC1C;AACA,UAAM,sBAAsB,CAAC,UAAwB;AACnD,UAAI,MAAM,kBAAkB,QAAQ,UAAU,SAAS,SAAS,MAAM,MAAM,EAAG;AAC/E,YAAM,gBAAgB,iBAAiB,YAAY;AACnD,uBAAiB,UAAU;AAC3B,UAAI,CAAC,cAAe;AACpB,aAAO,WAAW,MAAM,OAAO,KAAK,GAAG,CAAC;AAAA,IAC1C;AACA,UAAM,UAAU,CAAC,UAAyB;AACxC,UAAI,MAAM,QAAQ,UAAU;AAC1B,qBAAa,IAAI;AACjB;AAAA,MACF;AACA,aAAO,WAAW,MAAM,OAAO,IAAI,GAAG,CAAC;AAAA,IACzC;AACA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,kBAAkB,QAAQ,UAAU,SAAS,SAAS,MAAM,MAAM,GAAG;AAC7E,cAAM,eAAe;AACrB;AAAA,MACF;AACA,uBAAiB,UACf,MAAM,kBAAkB,QAAQ,KAAK,SAAS,MAAM,MAAM,IAAI,WAAW;AAC3E,mBAAa,IAAI;AAAA,IACnB;AACA,UAAM,oBAAoB,CAAC,UAAyB;AAClD,UAAI,MAAM,QAAQ,SAAU,cAAa,IAAI;AAAA,IAC/C;AACA,UAAM,oBAAoB,MAAM;AAC9B,UAAI,UAAU,WAAW,SAAS,kBAAkB,UAAU,QAAS;AACvE,YAAM,YAAY,SAAS,aAAa;AACxC,UAAI,CAAC,aAAa,UAAU,YAAa,cAAa,IAAI;AAAA,IAC5D;AACA,SAAK,iBAAiB,aAAa,eAAe;AAClD,SAAK,iBAAiB,SAAS,OAAO;AACtC,aAAS,iBAAiB,aAAa,mBAAmB;AAC1D,aAAS,iBAAiB,eAAe,aAAa;AACtD,aAAS,iBAAiB,WAAW,iBAAiB;AACtD,aAAS,iBAAiB,mBAAmB,iBAAiB;AAC9D,WAAO,MAAM;AACX,WAAK,oBAAoB,aAAa,eAAe;AACrD,WAAK,oBAAoB,SAAS,OAAO;AACzC,eAAS,oBAAoB,aAAa,mBAAmB;AAC7D,eAAS,oBAAoB,eAAe,aAAa;AACzD,eAAS,oBAAoB,WAAW,iBAAiB;AACzD,eAAS,oBAAoB,mBAAmB,iBAAiB;AAAA,IACnE;AAAA,EACF,GAAG,CAAC,YAAY,SAAS,OAAO,CAAC;AAEjC,YAAU,MAAM;AACd,QAAI,WAAW,SAAU,WAAU,SAAS,MAAM;AAAA,EACpD,GAAG,CAAC,SAAS,CAAC;AAEd,MAAI,CAAC,aAAa,CAAC,cAAc,OAAO,aAAa,YAAa,QAAO;AACzE,QAAM,UAAU,wBAAwB,UAAU,WAAW,OAAO,EAAE;AACtE,SAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,8BAA2B;AAAA,QAC3B,OAAO,EAAE,MAAM,UAAU,MAAM,KAAK,UAAU,KAAK,GAAG,YAAY;AAAA,QAClE,WAAU;AAAA,QACV,cAAY,0BAAqB,OAAO;AAAA,QACxC,OAAO,UAAU,WAAW;AAAA,QAC5B,eAAe,CAAC,UAAU,MAAM,eAAe;AAAA,QAC/C,SAAS,MAAM;AACb,qBAAW,UAAU,UAAU;AAC/B,mBAAS,aAAa,GAAG,gBAAgB;AACzC,uBAAa,IAAI;AAAA,QACnB;AAAA,QAEA;AAAA,8BAAC,aAAU,WAAU,2CAA0C,eAAY,QAAO;AAAA,UAClF,qBAAC,UAAK,WAAU,qBACd;AAAA,gCAAC,UAAK,WAAU,mBAAkB,sBAAQ;AAAA,YAC1C,oBAAC,UAAK,WAAU,iEACb,mBACH;AAAA,aACF;AAAA;AAAA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;AAEA,IAAO,wCAAQ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/react",
3
- "version": "7.4.0-canary.36855269964001",
3
+ "version": "7.4.0",
4
4
  "description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -58,10 +58,6 @@
58
58
  "types": "./dist/accounts.d.ts",
59
59
  "import": "./dist/accounts.js"
60
60
  },
61
- "./usage": {
62
- "types": "./dist/usage.d.ts",
63
- "import": "./dist/usage.js"
64
- },
65
61
  "./machines": {
66
62
  "types": "./dist/machines.d.ts",
67
63
  "import": "./dist/machines.js"
@@ -141,8 +137,8 @@
141
137
  "@dnd-kit/utilities": "3.2.2",
142
138
  "@fontsource-variable/noto-sans-arabic": "5.2.10",
143
139
  "@fontsource-variable/noto-sans-jp": "5.2.10",
144
- "@opengeni/connect": "^0.3.0-canary.36855269964001",
145
- "@opengeni/sdk": "^7.4.0-canary.36855269964001",
140
+ "@opengeni/connect": "^0.3.0",
141
+ "@opengeni/sdk": "^7.4.0",
146
142
  "clsx": "^2.1.1",
147
143
  "dequal": "2.0.3",
148
144
  "lucide-react": "^1.8.0",
package/src/artifacts.ts CHANGED
@@ -1,42 +1,5 @@
1
1
  export { inlineHtmlDocument } from "./components/artifacts/inline-html-document";
2
2
  export { isRetainedImageContentType, useRetainedImageObjectUrl } from "./timeline/retained-image";
3
- export {
4
- ArtifactBadge,
5
- ArtifactLabelsProvider,
6
- DEFAULT_ARTIFACT_LABELS,
7
- useArtifactLabels,
8
- type ArtifactLabels,
9
- ArtifactButton,
10
- ArtifactLoading,
11
- ArtifactProblem,
12
- ArtifactSelect,
13
- ArtifactViewerHeader,
14
- artifactKindIcon,
15
- artifactKindSubtitle,
16
- artifactLoadErrorMessage,
17
- artifactLoadErrorView,
18
- type ArtifactKind,
19
- type ArtifactLoadErrorKind,
20
- type ArtifactLoadErrorView,
21
- ArtifactSandbox,
22
- type ArtifactSandboxProps,
23
- DeferredChatMedia,
24
- SiteView,
25
- type SiteViewProps,
26
- ChatInteractiveBlock,
27
- type ChatInteractiveBlockProps,
28
- type SiteSnapshotClient,
29
- type SiteToolBridgeFactory,
30
- type SiteToolScope,
31
- EditableArtifactView,
32
- type EditableArtifactRuntimes,
33
- type EditableArtifactViewProps,
34
- type OpenedEditableArtifact,
35
- SessionArtifactViewer,
36
- type SessionArtifactTarget,
37
- type SessionArtifactViewerLabels,
38
- type SessionArtifactViewerProps,
39
- } from "./components/artifacts";
40
3
  /** Public artifact surfaces. Import from `@opengeni/react/artifacts`. */
41
4
  export {
42
5
  ArtifactSurface,
@@ -60,12 +60,10 @@ export function EditableArtifactMessage({
60
60
  title,
61
61
  detail,
62
62
  retry,
63
- retryLabel = "Retry",
64
63
  }: {
65
64
  title: string;
66
65
  detail: string;
67
66
  retry?: (() => void) | undefined;
68
- retryLabel?: string | undefined;
69
67
  }) {
70
68
  return (
71
69
  <div className="grid h-full min-h-56 place-items-center bg-og-bg p-6 text-center">
@@ -78,7 +76,7 @@ export function EditableArtifactMessage({
78
76
  onClick={retry}
79
77
  className="mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent"
80
78
  >
81
- {retryLabel}
79
+ Retry
82
80
  </button>
83
81
  ) : null}
84
82
  </div>
@@ -6,7 +6,6 @@ import {
6
6
  } from "@opengeni/sdk/editable-artifacts";
7
7
  import { useCallback, useEffect, useRef, useState } from "react";
8
8
 
9
- import { useArtifactLabels } from "./artifact-chrome";
10
9
  import { EditableArtifactMessage } from "./editable-artifact-ui";
11
10
  import {
12
11
  EditableDocumentArtifactSurface,
@@ -134,7 +133,6 @@ export function EditableArtifactWorkbenchHost({
134
133
  }, [retryEpoch, sessionKey]);
135
134
 
136
135
  const retry = useCallback(() => setRetryEpoch((value) => value + 1), []);
137
- const labels = useArtifactLabels();
138
136
  const currentError = state.key === sessionKey ? state.error : null;
139
137
  if (state.key === sessionKey && state.session) {
140
138
  return (
@@ -148,10 +146,9 @@ export function EditableArtifactWorkbenchHost({
148
146
  }
149
147
  return (
150
148
  <EditableArtifactMessage
151
- title={currentError ? labels.editableErrors.transient.title : labels.opening}
152
- detail={currentError?.message ?? labels.startingEditor}
149
+ title={currentError ? "Could not open this artifact" : "Opening artifact"}
150
+ detail={currentError?.message ?? "Starting the secure editing session…"}
153
151
  retry={currentError ? retry : undefined}
154
- retryLabel={labels.retry}
155
152
  />
156
153
  );
157
154
  }
@@ -9,7 +9,6 @@ import {
9
9
  type EditableArtifactSession,
10
10
  } from "@opengeni/sdk/editable-artifacts";
11
11
  import { type ReactNode, useCallback, useEffect, useRef, useState } from "react";
12
- import { useLatestTaskRunner } from "./latest-task-runner";
13
12
 
14
13
  import {
15
14
  DocumentProjectionArtifactSurface,
@@ -88,7 +87,6 @@ export function EditableDocumentArtifactSurface({
88
87
  error: null,
89
88
  });
90
89
  const loadGeneration = useRef(0);
91
- const scheduleLoad = useLatestTaskRunner(session);
92
90
  const commandStateRef = useRef<DocumentCommandState | null>(null);
93
91
  if (commandStateRef.current?.session !== session) {
94
92
  commandStateRef.current = {
@@ -109,41 +107,45 @@ export function EditableDocumentArtifactSurface({
109
107
  ? { ...current, loading: true, error: null }
110
108
  : { session, projection: null, loading: true, error: null },
111
109
  );
112
- const superseded = () =>
113
- cancelled ||
114
- generation !== loadGeneration.current ||
115
- commandStateRef.current !== commandState;
116
- scheduleLoad(async () => {
117
- if (superseded()) return;
118
- await composeDocumentEditorProjection(session).then(
119
- (projection) => {
120
- if (superseded()) return;
121
- const nextParagraphText = paragraphTextById(projection);
122
- for (const [localId, canonicalId] of commandState.optimisticParagraphIds) {
123
- if (nextParagraphText.has(canonicalId)) continue;
124
- const optimisticText =
125
- commandState.paragraphText.get(canonicalId) ??
126
- commandState.paragraphText.get(localId);
127
- if (optimisticText !== undefined) nextParagraphText.set(canonicalId, optimisticText);
128
- }
129
- commandState.paragraphText = nextParagraphText;
130
- setState({ session, projection, loading: false, error: null });
131
- },
132
- (cause) => {
133
- if (superseded()) return;
134
- setState({
135
- session,
136
- projection: null,
137
- loading: false,
138
- error: asEditableArtifactError(cause, "Could not open this document"),
139
- });
140
- },
141
- );
142
- });
110
+ void composeDocumentEditorProjection(session).then(
111
+ (projection) => {
112
+ if (
113
+ cancelled ||
114
+ generation !== loadGeneration.current ||
115
+ commandStateRef.current !== commandState
116
+ ) {
117
+ return;
118
+ }
119
+ const nextParagraphText = paragraphTextById(projection);
120
+ for (const [localId, canonicalId] of commandState.optimisticParagraphIds) {
121
+ if (nextParagraphText.has(canonicalId)) continue;
122
+ const optimisticText =
123
+ commandState.paragraphText.get(canonicalId) ?? commandState.paragraphText.get(localId);
124
+ if (optimisticText !== undefined) nextParagraphText.set(canonicalId, optimisticText);
125
+ }
126
+ commandState.paragraphText = nextParagraphText;
127
+ setState({ session, projection, loading: false, error: null });
128
+ },
129
+ (cause) => {
130
+ if (
131
+ cancelled ||
132
+ generation !== loadGeneration.current ||
133
+ commandStateRef.current !== commandState
134
+ ) {
135
+ return;
136
+ }
137
+ setState({
138
+ session,
139
+ projection: null,
140
+ loading: false,
141
+ error: asEditableArtifactError(cause, "Could not open this document"),
142
+ });
143
+ },
144
+ );
143
145
  return () => {
144
146
  cancelled = true;
145
147
  };
146
- }, [commandState, invalidator, retryEpoch, scheduleLoad, session]);
148
+ }, [commandState, invalidator, retryEpoch, session]);
147
149
 
148
150
  const refresh = useCallback(() => setRetryEpoch((value) => value + 1), []);
149
151
  const writable = !readOnly && view.writable;
@@ -33,7 +33,6 @@ import {
33
33
  type PresentationSlideProjection,
34
34
  } from "./presentation-editor";
35
35
  import { ArtifactSurface } from "./artifact-surface";
36
- import { useLatestTaskRunner } from "./latest-task-runner";
37
36
  import {
38
37
  asEditableArtifactError,
39
38
  editableArtifactAccessRevoked,
@@ -106,35 +105,31 @@ export function EditablePresentationArtifactSurface({
106
105
  error: null,
107
106
  });
108
107
  const loadGeneration = useRef(0);
109
- const scheduleLoad = useLatestTaskRunner(session);
110
108
  const sceneNodes = useRef(new Map<string, PresentationArtifactEditorSceneNode>());
111
109
 
112
110
  useEffect(() => {
113
111
  const generation = ++loadGeneration.current;
114
112
  let cancelled = false;
115
113
  setState((current) => ({ ...current, loading: true, error: null }));
116
- scheduleLoad(async () => {
117
- if (cancelled || generation !== loadGeneration.current) return;
118
- await composePresentationEditorProjection(session).then(
119
- (composed) => {
120
- if (cancelled || generation !== loadGeneration.current) return;
121
- sceneNodes.current = new Map(composed.sceneNodes);
122
- setState({ composed, loading: false, error: null });
123
- },
124
- (cause) => {
125
- if (cancelled || generation !== loadGeneration.current) return;
126
- setState({
127
- composed: null,
128
- loading: false,
129
- error: asEditableArtifactError(cause, "Could not open this presentation"),
130
- });
131
- },
132
- );
133
- });
114
+ void composePresentationEditorProjection(session).then(
115
+ (composed) => {
116
+ if (cancelled || generation !== loadGeneration.current) return;
117
+ sceneNodes.current = new Map(composed.sceneNodes);
118
+ setState({ composed, loading: false, error: null });
119
+ },
120
+ (cause) => {
121
+ if (cancelled || generation !== loadGeneration.current) return;
122
+ setState({
123
+ composed: null,
124
+ loading: false,
125
+ error: asEditableArtifactError(cause, "Could not open this presentation"),
126
+ });
127
+ },
128
+ );
134
129
  return () => {
135
130
  cancelled = true;
136
131
  };
137
- }, [invalidator, retryEpoch, scheduleLoad, session]);
132
+ }, [invalidator, retryEpoch, session]);
138
133
 
139
134
  const refresh = useCallback(() => setRetryEpoch((value) => value + 1), []);
140
135
  const writable = !readOnly && view.writable;
@@ -1,44 +1,3 @@
1
- export {
2
- ArtifactBadge,
3
- ArtifactLabelsProvider,
4
- DEFAULT_ARTIFACT_LABELS,
5
- useArtifactLabels,
6
- type ArtifactLabels,
7
- ArtifactButton,
8
- ArtifactLoading,
9
- ArtifactProblem,
10
- ArtifactSelect,
11
- ArtifactViewerHeader,
12
- artifactKindIcon,
13
- artifactKindSubtitle,
14
- artifactLoadErrorMessage,
15
- artifactLoadErrorView,
16
- type ArtifactKind,
17
- type ArtifactLoadErrorKind,
18
- type ArtifactLoadErrorView,
19
- } from "./artifact-chrome";
20
- export { ArtifactSandbox, type ArtifactSandboxProps } from "./artifact-sandbox";
21
- export { DeferredChatMedia } from "./deferred-chat-media";
22
- export {
23
- ChatInteractiveBlock,
24
- type ChatInteractiveBlockProps,
25
- type SiteSnapshotClient,
26
- type SiteToolBridgeFactory,
27
- type SiteToolScope,
28
- } from "./chat-interactive-block";
29
- export { SiteView, type SiteViewProps } from "./site-view";
30
- export {
31
- EditableArtifactView,
32
- type EditableArtifactRuntimes,
33
- type EditableArtifactViewProps,
34
- type OpenedEditableArtifact,
35
- } from "./editable-artifact-view";
36
- export {
37
- SessionArtifactViewer,
38
- type SessionArtifactTarget,
39
- type SessionArtifactViewerLabels,
40
- type SessionArtifactViewerProps,
41
- } from "./session-artifact-viewer";
42
1
  export {
43
2
  ArtifactSurface,
44
3
  type ArtifactModality,
@@ -56,8 +56,6 @@ function focusedSelect(
56
56
 
57
57
  /** Human fallback for native popup windows missing from Chromium page frames. */
58
58
  export function BrowserSelectControl(props: {
59
- /** Older controllers need an explicit read to discover native popup options. */
60
- manualFallback?: boolean;
61
59
  activation?: {
62
60
  observation: BrowserObservation | null;
63
61
  anchor: { x: number; y: number } | null;
@@ -188,7 +186,6 @@ export function BrowserSelectControl(props: {
188
186
  if (current === request.current) setBusy(false);
189
187
  }
190
188
  };
191
- if (props.manualFallback === false && !open) return null;
192
189
  return (
193
190
  <div
194
191
  ref={popupRef}
@@ -202,7 +199,7 @@ export function BrowserSelectControl(props: {
202
199
  : { bottom: 12, left: 12 }
203
200
  }
204
201
  >
205
- {(props.manualFallback !== false && (!anchor || !open)) || error ? (
202
+ {!anchor || !open || error ? (
206
203
  <button
207
204
  type="button"
208
205
  className="rounded-og-sm border border-og-border bg-og-bg px-2 py-1 text-og-fg"