@opengeni/react 1.4.4 → 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.
Files changed (234) hide show
  1. package/README.md +17 -6
  2. package/dist/artifacts.d.ts +1 -0
  3. package/dist/artifacts.js +22 -15
  4. package/dist/artifacts.js.map +1 -1
  5. package/dist/{browser-viewer-5EEAS3IU.js → browser-viewer-CV23VIHB.js} +8 -6
  6. package/dist/chunk-3ZC6QPOM.js +174 -0
  7. package/dist/chunk-3ZC6QPOM.js.map +1 -0
  8. package/dist/{chunk-YVFRBXST.js → chunk-4BCVCJSU.js} +2 -2
  9. package/dist/{chunk-JHTIMBOL.js → chunk-5JSUNNQN.js} +26 -4
  10. package/dist/{chunk-JHTIMBOL.js.map → chunk-5JSUNNQN.js.map} +1 -1
  11. package/dist/{chunk-I6OY3MWC.js → chunk-6FOTSVWU.js} +2 -2
  12. package/dist/{chunk-IUHHPMAX.js → chunk-7RRBX5EM.js} +14 -85
  13. package/dist/chunk-7RRBX5EM.js.map +1 -0
  14. package/dist/{chunk-L2J3PU7A.js → chunk-7ZB7I3KP.js} +24 -98
  15. package/dist/chunk-7ZB7I3KP.js.map +1 -0
  16. package/dist/{chunk-LVS3MH5T.js → chunk-ATIRUHBZ.js} +128 -10
  17. package/dist/chunk-ATIRUHBZ.js.map +1 -0
  18. package/dist/chunk-BOFEQC6K.js +162 -0
  19. package/dist/chunk-BOFEQC6K.js.map +1 -0
  20. package/dist/{chunk-2OQA3CPB.js → chunk-CESBPQP5.js} +19 -5
  21. package/dist/chunk-CESBPQP5.js.map +1 -0
  22. package/dist/{chunk-IYQCWGU5.js → chunk-GHJU7XG7.js} +35 -62
  23. package/dist/chunk-GHJU7XG7.js.map +1 -0
  24. package/dist/{chunk-G6YRCIYJ.js → chunk-HNVWMDNN.js} +55 -60
  25. package/dist/chunk-HNVWMDNN.js.map +1 -0
  26. package/dist/{chunk-PHBFJCEU.js → chunk-I5EGRXXG.js} +110 -7
  27. package/dist/chunk-I5EGRXXG.js.map +1 -0
  28. package/dist/{chunk-PBCZL4JP.js → chunk-INIZSNXT.js} +2 -2
  29. package/dist/{chunk-XS67YG5R.js → chunk-IX3K4THH.js} +24 -3
  30. package/dist/chunk-IX3K4THH.js.map +1 -0
  31. package/dist/chunk-IZV5FTJC.js +55 -0
  32. package/dist/chunk-IZV5FTJC.js.map +1 -0
  33. package/dist/chunk-JDJJMBB3.js +1883 -0
  34. package/dist/chunk-JDJJMBB3.js.map +1 -0
  35. package/dist/{chunk-C5BF4L26.js → chunk-KHF2VRXF.js} +7 -7
  36. package/dist/{chunk-QMMCJGFI.js → chunk-L5OKM2VX.js} +2 -2
  37. package/dist/chunk-LHF6BVM4.js +83 -0
  38. package/dist/chunk-LHF6BVM4.js.map +1 -0
  39. package/dist/chunk-N7S72EXK.js +25 -0
  40. package/dist/chunk-N7S72EXK.js.map +1 -0
  41. package/dist/{chunk-CVYCLFMH.js → chunk-PEHTX3V7.js} +19 -1
  42. package/dist/chunk-PEHTX3V7.js.map +1 -0
  43. package/dist/chunk-R5R5RQQD.js +51 -0
  44. package/dist/chunk-R5R5RQQD.js.map +1 -0
  45. package/dist/chunk-RI42H5IU.js +326 -0
  46. package/dist/chunk-RI42H5IU.js.map +1 -0
  47. package/dist/{chunk-JH7V627O.js → chunk-SHLZMAJN.js} +2 -11
  48. package/dist/chunk-SHLZMAJN.js.map +1 -0
  49. package/dist/{chunk-EAOSEIXB.js → chunk-TZQSHCZN.js} +692 -1996
  50. package/dist/chunk-TZQSHCZN.js.map +1 -0
  51. package/dist/chunk-ZIB4H5LN.js +101 -0
  52. package/dist/chunk-ZIB4H5LN.js.map +1 -0
  53. package/dist/client.d.ts +9 -3
  54. package/dist/clipboard.js +1 -1
  55. package/dist/components/browser-viewer.d.ts +6 -0
  56. package/dist/components/composer.d.ts +3 -69
  57. package/dist/components/human-input-form.d.ts +3 -32
  58. package/dist/components/markdown.d.ts +8 -0
  59. package/dist/components/model-policy-picker.d.ts +4 -37
  60. package/dist/components/opper-mark.d.ts +7 -0
  61. package/dist/components/provider-recovery-notice.d.ts +15 -0
  62. package/dist/components/remark-soft-line-breaks.d.ts +38 -0
  63. package/dist/components/sandbox-workspace.d.ts +13 -0
  64. package/dist/components/session-chrome.d.ts +5 -3
  65. package/dist/components/session-conversation.d.ts +15 -3
  66. package/dist/composer-messages.d.ts +74 -0
  67. package/dist/composer-messages.js +9 -0
  68. package/dist/composer.js +15 -10
  69. package/dist/{computer-viewer-ELNLZGHI.js → computer-viewer-K4CKYRX6.js} +4 -4
  70. package/dist/connect-setup.d.ts +2 -0
  71. package/dist/connect.d.ts +1 -1
  72. package/dist/connect.js +21 -6
  73. package/dist/connect.js.map +1 -1
  74. package/dist/{embedded-voice-NIL4RDX3.js → embedded-voice-3ZFWWJ6O.js} +6 -4
  75. package/dist/{embedded-voice-NIL4RDX3.js.map → embedded-voice-3ZFWWJ6O.js.map} +1 -1
  76. package/dist/hooks/shared-machines-list.d.ts +4 -0
  77. package/dist/hooks/use-client-config-flags.d.ts +6 -0
  78. package/dist/hooks/use-goal.d.ts +2 -1
  79. package/dist/human-input-model.d.ts +40 -0
  80. package/dist/index.d.ts +4 -1
  81. package/dist/index.js +116 -73
  82. package/dist/index.js.map +1 -1
  83. package/dist/interaction.js +5 -5
  84. package/dist/{latest-question-2POFPYNB.js → latest-question-SWC6QEVN.js} +3 -3
  85. package/dist/lib/clipboard.d.ts +7 -0
  86. package/dist/lib/provider-recovery.d.ts +49 -0
  87. package/dist/machines.js +2 -2
  88. package/dist/model-mark-paths.d.ts +34 -0
  89. package/dist/model-mark-paths.js +16 -0
  90. package/dist/model-picker-model.d.ts +111 -0
  91. package/dist/model-picker-model.js +25 -0
  92. package/dist/model-picker-model.js.map +1 -0
  93. package/dist/{model-policy-picker-menu-WRNSRFQC.js → model-policy-picker-menu-NM4RPTY6.js} +6 -4
  94. package/dist/model-policy-picker-menu-NM4RPTY6.js.map +1 -0
  95. package/dist/model-policy.d.ts +10 -0
  96. package/dist/model-policy.js +5 -1
  97. package/dist/organization-model.d.ts +32 -0
  98. package/dist/organization-model.js +65 -0
  99. package/dist/organization-model.js.map +1 -0
  100. package/dist/{platform-activity-row-PJJVATTZ.js → platform-activity-row-NJ47YBXW.js} +7 -84
  101. package/dist/platform-activity-row-NJ47YBXW.js.map +1 -0
  102. package/dist/queue-presentation-model.d.ts +72 -0
  103. package/dist/queue-presentation-model.js +38 -0
  104. package/dist/queue-presentation-model.js.map +1 -0
  105. package/dist/{queue-surface-implementation-67FS7FUI.js → queue-surface-implementation-YPJFQ3O6.js} +24 -252
  106. package/dist/queue-surface-implementation-YPJFQ3O6.js.map +1 -0
  107. package/dist/realtime.js +5 -3
  108. package/dist/{sandbox-files-34CJJNOY.js → sandbox-files-RCVCMXG7.js} +5 -5
  109. package/dist/sandbox-files-RCVCMXG7.js.map +1 -0
  110. package/dist/sandbox-label-model.d.ts +23 -0
  111. package/dist/sandbox-label-model.js +28 -0
  112. package/dist/sandbox-label-model.js.map +1 -0
  113. package/dist/session-attention-model.d.ts +8 -0
  114. package/dist/session-attention-model.js +46 -0
  115. package/dist/session-attention-model.js.map +1 -0
  116. package/dist/session-feedback-model.d.ts +20 -0
  117. package/dist/session-feedback-model.js +56 -0
  118. package/dist/session-feedback-model.js.map +1 -0
  119. package/dist/session-list-model.d.ts +96 -0
  120. package/dist/session-list-model.js +219 -0
  121. package/dist/session-list-model.js.map +1 -0
  122. package/dist/session-status-model.d.ts +19 -0
  123. package/dist/session-ui.js +26 -17
  124. package/dist/session-ui.js.map +1 -1
  125. package/dist/session.js +8 -6
  126. package/dist/testing/session-scenarios.d.ts +10 -0
  127. package/dist/testing/session-scenarios.js +303 -0
  128. package/dist/testing/session-scenarios.js.map +1 -0
  129. package/dist/timeline/genie-copy.d.ts +3 -0
  130. package/dist/timeline/genie-loading.d.ts +11 -0
  131. package/dist/timeline/index.d.ts +1 -1
  132. package/dist/timeline/notice-presentation.d.ts +7 -0
  133. package/dist/timeline/patch-apply-command.d.ts +18 -0
  134. package/dist/timeline/platform-activity-presentation.d.ts +7 -0
  135. package/dist/timeline/presented-image.d.ts +6 -1
  136. package/dist/timeline/question-nav-model.d.ts +23 -0
  137. package/dist/timeline/registry.d.ts +10 -1
  138. package/dist/timeline/retained-loaders.d.ts +1 -1
  139. package/dist/timeline/tool-presentation.d.ts +172 -0
  140. package/dist/timeline/turn-summary-model.d.ts +90 -0
  141. package/dist/timeline/turn-summary.d.ts +4 -74
  142. package/dist/timeline/work-presentation.d.ts +42 -0
  143. package/dist/timeline-model.d.ts +24 -0
  144. package/dist/timeline-model.js +152 -0
  145. package/dist/timeline-model.js.map +1 -0
  146. package/package.json +47 -3
  147. package/src/artifacts.ts +1 -0
  148. package/src/client.ts +9 -3
  149. package/src/components/browser-viewer.tsx +23 -2
  150. package/src/components/claude-mark.tsx +2 -1
  151. package/src/components/composer.tsx +4 -144
  152. package/src/components/grok-mark.tsx +2 -1
  153. package/src/components/human-input-form.tsx +13 -124
  154. package/src/components/markdown.tsx +19 -1
  155. package/src/components/message-timeline.tsx +45 -99
  156. package/src/components/model-mark.tsx +2 -1
  157. package/src/components/model-policy-picker-menu.tsx +30 -85
  158. package/src/components/model-policy-picker.tsx +15 -148
  159. package/src/components/opper-mark.tsx +18 -0
  160. package/src/components/provider-recovery-notice.tsx +41 -0
  161. package/src/components/queue-surface-implementation.tsx +20 -349
  162. package/src/components/remark-soft-line-breaks.ts +166 -0
  163. package/src/components/sandbox-workspace.tsx +17 -1
  164. package/src/components/session-chrome.tsx +114 -99
  165. package/src/components/session-conversation.tsx +55 -6
  166. package/src/components/session-status.tsx +17 -16
  167. package/src/composer-messages.ts +150 -0
  168. package/src/connect-setup.tsx +45 -11
  169. package/src/connect.ts +1 -1
  170. package/src/hooks/shared-machines-list.ts +34 -1
  171. package/src/hooks/use-client-config-flags.ts +8 -0
  172. package/src/hooks/use-goal.ts +66 -10
  173. package/src/human-input-model.ts +147 -0
  174. package/src/index.ts +16 -0
  175. package/src/lib/clipboard.ts +29 -0
  176. package/src/lib/format.ts +7 -0
  177. package/src/lib/provider-recovery.ts +202 -0
  178. package/src/model-mark-paths.ts +53 -0
  179. package/src/model-picker-model.ts +330 -0
  180. package/src/model-policy.ts +43 -2
  181. package/src/organization-model.ts +118 -0
  182. package/src/queue-presentation-model.ts +464 -0
  183. package/src/sandbox-label-model.ts +41 -0
  184. package/src/session-attention-model.ts +59 -0
  185. package/src/session-feedback-model.ts +95 -0
  186. package/src/session-list-model.ts +327 -0
  187. package/src/session-status-model.ts +62 -0
  188. package/src/testing/session-scenarios.ts +326 -0
  189. package/src/timeline/activity-rail.tsx +5 -17
  190. package/src/timeline/genie-copy.ts +19 -0
  191. package/src/timeline/genie-loading.tsx +13 -18
  192. package/src/timeline/index.ts +1 -0
  193. package/src/timeline/notice-presentation.ts +22 -0
  194. package/src/timeline/patch-apply-command.tsx +135 -0
  195. package/src/timeline/platform-activity-presentation.ts +122 -0
  196. package/src/timeline/platform-activity-row.tsx +6 -96
  197. package/src/timeline/presented-image.ts +16 -2
  198. package/src/timeline/question-nav-model.ts +28 -0
  199. package/src/timeline/registry.ts +11 -1
  200. package/src/timeline/retained-loaders.ts +9 -4
  201. package/src/timeline/rolling-activity.tsx +7 -19
  202. package/src/timeline/tool-presentation.ts +1316 -0
  203. package/src/timeline/tool-renderers.tsx +226 -1025
  204. package/src/timeline/turn-summary-model.ts +338 -0
  205. package/src/timeline/turn-summary.tsx +21 -326
  206. package/src/timeline/work-presentation.ts +139 -0
  207. package/src/timeline-model.ts +108 -0
  208. package/styles/compiled.css +3 -0
  209. package/styles/connect.css +4 -0
  210. package/dist/chunk-2OQA3CPB.js.map +0 -1
  211. package/dist/chunk-CVYCLFMH.js.map +0 -1
  212. package/dist/chunk-EAOSEIXB.js.map +0 -1
  213. package/dist/chunk-G6YRCIYJ.js.map +0 -1
  214. package/dist/chunk-HXYOSSQO.js +0 -117
  215. package/dist/chunk-HXYOSSQO.js.map +0 -1
  216. package/dist/chunk-IUHHPMAX.js.map +0 -1
  217. package/dist/chunk-IYQCWGU5.js.map +0 -1
  218. package/dist/chunk-JH7V627O.js.map +0 -1
  219. package/dist/chunk-L2J3PU7A.js.map +0 -1
  220. package/dist/chunk-LVS3MH5T.js.map +0 -1
  221. package/dist/chunk-PHBFJCEU.js.map +0 -1
  222. package/dist/chunk-XS67YG5R.js.map +0 -1
  223. package/dist/platform-activity-row-PJJVATTZ.js.map +0 -1
  224. package/dist/queue-surface-implementation-67FS7FUI.js.map +0 -1
  225. /package/dist/{browser-viewer-5EEAS3IU.js.map → browser-viewer-CV23VIHB.js.map} +0 -0
  226. /package/dist/{chunk-YVFRBXST.js.map → chunk-4BCVCJSU.js.map} +0 -0
  227. /package/dist/{chunk-I6OY3MWC.js.map → chunk-6FOTSVWU.js.map} +0 -0
  228. /package/dist/{chunk-PBCZL4JP.js.map → chunk-INIZSNXT.js.map} +0 -0
  229. /package/dist/{chunk-C5BF4L26.js.map → chunk-KHF2VRXF.js.map} +0 -0
  230. /package/dist/{chunk-QMMCJGFI.js.map → chunk-L5OKM2VX.js.map} +0 -0
  231. /package/dist/{computer-viewer-ELNLZGHI.js.map → composer-messages.js.map} +0 -0
  232. /package/dist/{model-policy-picker-menu-WRNSRFQC.js.map → computer-viewer-K4CKYRX6.js.map} +0 -0
  233. /package/dist/{latest-question-2POFPYNB.js.map → latest-question-SWC6QEVN.js.map} +0 -0
  234. /package/dist/{sandbox-files-34CJJNOY.js.map → model-mark-paths.js.map} +0 -0
@@ -0,0 +1,162 @@
1
+ "use client";
2
+ import {
3
+ copyPendingTextToClipboard
4
+ } from "./chunk-PEHTX3V7.js";
5
+
6
+ // src/timeline/retained-image.ts
7
+ import { useCallback, useEffect, useRef, useState } from "react";
8
+ function useRetainedImageObjectUrl(artifact, load) {
9
+ const [state, setState] = useState({ kind: "loading" });
10
+ const [retrievalAttempt, setRetrievalAttempt] = useState(0);
11
+ const retry = useCallback(() => setRetrievalAttempt((attempt) => attempt + 1), []);
12
+ const artifactValue = retainedArtifactValue(artifact);
13
+ const stableArtifactRef = useRef({ value: artifactValue, artifact });
14
+ if (stableArtifactRef.current.value !== artifactValue) {
15
+ stableArtifactRef.current = { value: artifactValue, artifact };
16
+ }
17
+ const stableArtifact = stableArtifactRef.current.artifact;
18
+ useEffect(() => {
19
+ if (!load) {
20
+ setState({ kind: "unavailable", label: "retrieval is not configured" });
21
+ return;
22
+ }
23
+ const controller = new AbortController();
24
+ let objectUrl = null;
25
+ setState({ kind: "loading" });
26
+ void load(stableArtifact, controller.signal).then((source) => {
27
+ if (controller.signal.aborted) return;
28
+ if (!source) {
29
+ setState({ kind: "unavailable", label: "bytes are unavailable" });
30
+ return;
31
+ }
32
+ if (!(source instanceof Uint8Array)) {
33
+ if (!source.url.trim()) {
34
+ setState({ kind: "unavailable", label: "URL is unavailable" });
35
+ return;
36
+ }
37
+ setState({ kind: "ready", url: source.url });
38
+ return;
39
+ }
40
+ objectUrl = URL.createObjectURL(
41
+ new Blob([source], { type: stableArtifact.contentType })
42
+ );
43
+ setState({ kind: "ready", url: objectUrl });
44
+ }).catch((error) => {
45
+ if (controller.signal.aborted) return;
46
+ const status = error && typeof error === "object" && "status" in error ? Number(error.status) : null;
47
+ setState(
48
+ status === 404 ? { kind: "unavailable", label: "deleted" } : status === 410 ? { kind: "unavailable", label: "expired or unavailable" } : { kind: "error", message: "retrieval failed" }
49
+ );
50
+ });
51
+ return () => {
52
+ controller.abort();
53
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
54
+ };
55
+ }, [stableArtifact, load, retrievalAttempt]);
56
+ return { ...state, retry };
57
+ }
58
+ function retainedArtifactValue(artifact) {
59
+ return [
60
+ artifact.artifactId,
61
+ artifact.kind,
62
+ artifact.contentType,
63
+ artifact.originalBytes,
64
+ artifact.sha256,
65
+ artifact.retainedAt,
66
+ artifact.dimensions?.width ?? "",
67
+ artifact.dimensions?.height ?? "",
68
+ artifact.retention.policy,
69
+ artifact.retention.expiresAt ?? "",
70
+ artifact.retrieval.method,
71
+ artifact.retrieval.path,
72
+ artifact.retrieval.acceptRanges,
73
+ artifact.retrieval.maxRangeBytes
74
+ ].join("\0");
75
+ }
76
+
77
+ // src/timeline/patch-apply-command.tsx
78
+ import { CheckIcon, TerminalIcon } from "lucide-react";
79
+ import { useState as useState2 } from "react";
80
+ import { jsx, jsxs } from "react/jsx-runtime";
81
+ function shellQuote(value) {
82
+ return `'${value.replaceAll("'", `'\\''`)}'`;
83
+ }
84
+ function patchApplyCommand(url) {
85
+ return `curl -fsSL ${shellQuote(url)} | git apply`;
86
+ }
87
+ function applyCommandLifetime(expiresAt, now = Date.now()) {
88
+ const expires = expiresAt ? Date.parse(expiresAt) : Number.NaN;
89
+ const minutes = Number.isFinite(expires) ? Math.round((expires - now) / 6e4) : 5;
90
+ if (minutes <= 1) return "1 minute";
91
+ return `${minutes} minutes`;
92
+ }
93
+ var BUTTON_CLASS = "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1.5 text-og-sm font-medium text-og-fg transition-colors hover:border-og-border-strong hover:bg-og-surface-2 disabled:cursor-wait disabled:opacity-60";
94
+ function PatchApplyCommand({
95
+ artifact,
96
+ filename,
97
+ load
98
+ }) {
99
+ const [state, setState] = useState2({ kind: "idle" });
100
+ const copy = async () => {
101
+ if (!load) {
102
+ setState({ kind: "unavailable" });
103
+ return;
104
+ }
105
+ setState({ kind: "loading" });
106
+ let lifetime = "5 minutes";
107
+ const command = load(artifact, new AbortController().signal, { prefer: "url" }).then(
108
+ (source) => {
109
+ if (!source || source instanceof Uint8Array) throw new UnavailableError();
110
+ lifetime = applyCommandLifetime(source.expiresAt);
111
+ return patchApplyCommand(source.url);
112
+ }
113
+ );
114
+ const copied = copyPendingTextToClipboard(command);
115
+ try {
116
+ const text = await command;
117
+ if (await copied) setState({ kind: "copied", lifetime });
118
+ else setState({ kind: "manual", command: text, lifetime });
119
+ } catch (failure) {
120
+ setState({ kind: failure instanceof UnavailableError ? "unavailable" : "error" });
121
+ }
122
+ };
123
+ const label = state.kind === "loading" ? "Preparing\u2026" : state.kind === "copied" ? "Copied" : state.kind === "error" ? "Try again" : "Copy command to apply these changes";
124
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
125
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
126
+ "button",
127
+ {
128
+ type: "button",
129
+ onClick: () => void copy(),
130
+ disabled: state.kind === "loading",
131
+ className: BUTTON_CLASS,
132
+ children: [
133
+ state.kind === "copied" ? /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5", "aria-hidden": true }) : /* @__PURE__ */ jsx(TerminalIcon, { className: "size-3.5", "aria-hidden": true }),
134
+ label
135
+ ]
136
+ }
137
+ ) }),
138
+ /* @__PURE__ */ jsx("p", { className: "m-0 text-og-xs leading-relaxed text-og-fg-muted", role: "status", children: state.kind === "copied" ? `Copied. Paste it in a terminal in your project folder and press Enter. The link in it expires in ${state.lifetime}.` : state.kind === "manual" ? `Copy this command, then run it in your project folder. The link in it expires in ${state.lifetime}.` : state.kind === "unavailable" ? `Download ${filename}, then run git apply ${filename} in your project folder.` : state.kind === "error" ? "Couldn't prepare the command. Try again, or download the file and run git apply." : "Runs git apply in your project folder. Works on macOS, Linux and Git Bash." }),
139
+ state.kind === "manual" ? /* @__PURE__ */ jsx(
140
+ "input",
141
+ {
142
+ readOnly: true,
143
+ value: state.command,
144
+ "aria-label": "Command to apply these changes",
145
+ onFocus: (event) => event.currentTarget.select(),
146
+ className: "w-full min-w-0 rounded-og-sm border border-og-border bg-og-surface-2 px-2 py-1.5 font-mono text-og-xs text-og-fg"
147
+ }
148
+ ) : null
149
+ ] });
150
+ }
151
+ var UnavailableError = class extends Error {
152
+ constructor() {
153
+ super("A download URL is unavailable here");
154
+ this.name = "UnavailableError";
155
+ }
156
+ };
157
+
158
+ export {
159
+ useRetainedImageObjectUrl,
160
+ PatchApplyCommand
161
+ };
162
+ //# sourceMappingURL=chunk-BOFEQC6K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timeline/retained-image.ts","../src/timeline/patch-apply-command.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { RetainedArtifactReference } from \"@opengeni/sdk\";\nimport type { ToolRendererProps } from \"./registry\";\ntype RetainedImageState =\n | { kind: \"loading\" }\n | { kind: \"ready\"; url: string }\n | { kind: \"unavailable\"; label: string }\n | { kind: \"error\"; message: string };\n\nexport { isRetainedImageContentType } from \"./presented-image\";\n\nexport function useRetainedImageObjectUrl(\n artifact: RetainedArtifactReference,\n load: ToolRendererProps[\"loadRetainedArtifact\"],\n): RetainedImageState & { retry: () => void } {\n const [state, setState] = useState<RetainedImageState>({ kind: \"loading\" });\n const [retrievalAttempt, setRetrievalAttempt] = useState(0);\n // Retry only the immutable retained artifact; never issue a new capture or\n // rewrite the tool receipt/model history to repair a human preview.\n const retry = useCallback(() => setRetrievalAttempt((attempt) => attempt + 1), []);\n // Function outputs are commonly serialized JSON. Parsing them creates a new\n // object on every render, so depend on the immutable wire value rather than\n // object identity; otherwise the loader can refetch after its own setState.\n const artifactValue = retainedArtifactValue(artifact);\n const stableArtifactRef = useRef({ value: artifactValue, artifact });\n if (stableArtifactRef.current.value !== artifactValue) {\n stableArtifactRef.current = { value: artifactValue, artifact };\n }\n const stableArtifact = stableArtifactRef.current.artifact;\n useEffect(() => {\n if (!load) {\n setState({ kind: \"unavailable\", label: \"retrieval is not configured\" });\n return;\n }\n const controller = new AbortController();\n let objectUrl: string | null = null;\n setState({ kind: \"loading\" });\n void load(stableArtifact, controller.signal)\n .then((source) => {\n if (controller.signal.aborted) return;\n if (!source) {\n setState({ kind: \"unavailable\", label: \"bytes are unavailable\" });\n return;\n }\n if (!(source instanceof Uint8Array)) {\n if (!source.url.trim()) {\n setState({ kind: \"unavailable\", label: \"URL is unavailable\" });\n return;\n }\n setState({ kind: \"ready\", url: source.url });\n return;\n }\n objectUrl = URL.createObjectURL(\n new Blob([source as unknown as BlobPart], { type: stableArtifact.contentType }),\n );\n setState({ kind: \"ready\", url: objectUrl });\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n const status =\n error && typeof error === \"object\" && \"status\" in error\n ? Number((error as { status?: unknown }).status)\n : null;\n setState(\n status === 404\n ? { kind: \"unavailable\", label: \"deleted\" }\n : status === 410\n ? { kind: \"unavailable\", label: \"expired or unavailable\" }\n : { kind: \"error\", message: \"retrieval failed\" },\n );\n });\n return () => {\n controller.abort();\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n };\n }, [stableArtifact, load, retrievalAttempt]);\n return { ...state, retry };\n}\n\nfunction retainedArtifactValue(artifact: RetainedArtifactReference): string {\n return [\n artifact.artifactId,\n artifact.kind,\n artifact.contentType,\n artifact.originalBytes,\n artifact.sha256,\n artifact.retainedAt,\n artifact.dimensions?.width ?? \"\",\n artifact.dimensions?.height ?? \"\",\n artifact.retention.policy,\n artifact.retention.expiresAt ?? \"\",\n artifact.retrieval.method,\n artifact.retrieval.path,\n artifact.retrieval.acceptRanges,\n artifact.retrieval.maxRangeBytes,\n ].join(\"\\0\");\n}\n","import type { RetainedArtifactReference } from \"@opengeni/sdk\";\nimport { CheckIcon, TerminalIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { copyPendingTextToClipboard } from \"../lib/clipboard\";\nimport type { RetainedArtifactLoader } from \"./registry\";\n\nexport { isPatchFilename } from \"./presented-image\";\n\n/** POSIX single-quote one argument so the URL reaches curl unchanged. */\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n}\n\n/** One command that downloads this patch and applies it in the current folder. */\nexport function patchApplyCommand(url: string): string {\n return `curl -fsSL ${shellQuote(url)} | git apply`;\n}\n\n/** \"5 minutes\" from the signed URL's expiry; the default download URL lifetime otherwise. */\nexport function applyCommandLifetime(expiresAt: string | undefined, now = Date.now()): string {\n const expires = expiresAt ? Date.parse(expiresAt) : Number.NaN;\n const minutes = Number.isFinite(expires) ? Math.round((expires - now) / 60_000) : 5;\n if (minutes <= 1) return \"1 minute\";\n return `${minutes} minutes`;\n}\n\ntype ApplyState =\n | { kind: \"idle\" }\n | { kind: \"loading\" }\n | { kind: \"copied\"; lifetime: string }\n | { kind: \"manual\"; command: string; lifetime: string }\n | { kind: \"unavailable\" }\n | { kind: \"error\" };\n\nconst BUTTON_CLASS =\n \"inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1.5 text-og-sm font-medium text-og-fg transition-colors hover:border-og-border-strong hover:bg-og-surface-2 disabled:cursor-wait disabled:opacity-60\";\n\n/**\n * \"Copy command to apply these changes\": mints the existing short-lived,\n * authenticated download URL for this published patch (the same authority as\n * Download) and copies `curl -fsSL '<url>' | git apply`. The URL is minted on\n * click, so the copied command works for the URL's lifetime only.\n */\nexport function PatchApplyCommand({\n artifact,\n filename,\n load,\n}: {\n artifact: RetainedArtifactReference;\n filename: string;\n load: RetainedArtifactLoader | undefined;\n}) {\n const [state, setState] = useState<ApplyState>({ kind: \"idle\" });\n\n const copy = async () => {\n if (!load) {\n setState({ kind: \"unavailable\" });\n return;\n }\n setState({ kind: \"loading\" });\n let lifetime = \"5 minutes\";\n // Start the URL request inside the click so the clipboard write may wait for it.\n const command = load(artifact, new AbortController().signal, { prefer: \"url\" }).then(\n (source) => {\n if (!source || source instanceof Uint8Array) throw new UnavailableError();\n lifetime = applyCommandLifetime(source.expiresAt);\n return patchApplyCommand(source.url);\n },\n );\n const copied = copyPendingTextToClipboard(command);\n try {\n const text = await command;\n if (await copied) setState({ kind: \"copied\", lifetime });\n else setState({ kind: \"manual\", command: text, lifetime });\n } catch (failure) {\n setState({ kind: failure instanceof UnavailableError ? \"unavailable\" : \"error\" });\n }\n };\n\n const label =\n state.kind === \"loading\"\n ? \"Preparing…\"\n : state.kind === \"copied\"\n ? \"Copied\"\n : state.kind === \"error\"\n ? \"Try again\"\n : \"Copy command to apply these changes\";\n\n return (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n <div>\n <button\n type=\"button\"\n onClick={() => void copy()}\n disabled={state.kind === \"loading\"}\n className={BUTTON_CLASS}\n >\n {state.kind === \"copied\" ? (\n <CheckIcon className=\"size-3.5\" aria-hidden />\n ) : (\n <TerminalIcon className=\"size-3.5\" aria-hidden />\n )}\n {label}\n </button>\n </div>\n <p className=\"m-0 text-og-xs leading-relaxed text-og-fg-muted\" role=\"status\">\n {state.kind === \"copied\"\n ? `Copied. Paste it in a terminal in your project folder and press Enter. The link in it expires in ${state.lifetime}.`\n : state.kind === \"manual\"\n ? `Copy this command, then run it in your project folder. The link in it expires in ${state.lifetime}.`\n : state.kind === \"unavailable\"\n ? `Download ${filename}, then run git apply ${filename} in your project folder.`\n : state.kind === \"error\"\n ? \"Couldn't prepare the command. Try again, or download the file and run git apply.\"\n : \"Runs git apply in your project folder. Works on macOS, Linux and Git Bash.\"}\n </p>\n {state.kind === \"manual\" ? (\n <input\n readOnly\n value={state.command}\n aria-label=\"Command to apply these changes\"\n onFocus={(event) => event.currentTarget.select()}\n className=\"w-full min-w-0 rounded-og-sm border border-og-border bg-og-surface-2 px-2 py-1.5 font-mono text-og-xs text-og-fg\"\n />\n ) : null}\n </div>\n );\n}\n\nclass UnavailableError extends Error {\n constructor() {\n super(\"A download URL is unavailable here\");\n this.name = \"UnavailableError\";\n }\n}\n"],"mappings":"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","names":["useState","useState"]}
@@ -10,13 +10,13 @@ import {
10
10
  } from "./chunk-BNKV5ZLF.js";
11
11
  import {
12
12
  copyTextToClipboard
13
- } from "./chunk-CVYCLFMH.js";
13
+ } from "./chunk-PEHTX3V7.js";
14
14
  import {
15
15
  interactionHostPlatform
16
16
  } from "./chunk-ZUWF4NF7.js";
17
17
  import {
18
18
  formatBytes
19
- } from "./chunk-LVS3MH5T.js";
19
+ } from "./chunk-ATIRUHBZ.js";
20
20
  import {
21
21
  STREAM_CLOSE_REASON_NORMAL,
22
22
  STREAM_KIND_BROWSER,
@@ -2157,6 +2157,14 @@ function BrowserSelectControl(props) {
2157
2157
 
2158
2158
  // src/components/browser-viewer.tsx
2159
2159
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2160
+ var STALE_BROWSER_END_MAX_ATTEMPTS = 3;
2161
+ var STALE_BROWSER_END_RETRY_BASE_MS = 5e3;
2162
+ function staleBrowserEndRetryDelayMs(cause, failedAttempts) {
2163
+ const status = cause?.status;
2164
+ if (typeof status === "number" && status >= 400 && status < 500) return null;
2165
+ if (failedAttempts >= STALE_BROWSER_END_MAX_ATTEMPTS) return null;
2166
+ return STALE_BROWSER_END_RETRY_BASE_MS * 2 ** (failedAttempts - 1);
2167
+ }
2160
2168
  function BrowserViewer({
2161
2169
  sessionId,
2162
2170
  enabled = true,
@@ -2195,6 +2203,7 @@ function BrowserViewer({
2195
2203
  [registry.sessions]
2196
2204
  );
2197
2205
  const endedGenerationLossRef = useRef9(/* @__PURE__ */ new Set());
2206
+ const endStaleBrowserAttemptsRef = useRef9(/* @__PURE__ */ new Map());
2198
2207
  const endStaleBrowser = registry.end;
2199
2208
  useEffect9(() => {
2200
2209
  if (!enabled) return;
@@ -2204,8 +2213,12 @@ function BrowserViewer({
2204
2213
  }
2205
2214
  if (endedGenerationLossRef.current.has(session.id)) continue;
2206
2215
  endedGenerationLossRef.current.add(session.id);
2207
- void endStaleBrowser(session.id).catch(() => {
2208
- endedGenerationLossRef.current.delete(session.id);
2216
+ void endStaleBrowser(session.id).catch((cause) => {
2217
+ const attempts = (endStaleBrowserAttemptsRef.current.get(session.id) ?? 0) + 1;
2218
+ endStaleBrowserAttemptsRef.current.set(session.id, attempts);
2219
+ const delay = staleBrowserEndRetryDelayMs(cause, attempts);
2220
+ if (delay === null) return;
2221
+ setTimeout(() => endedGenerationLossRef.current.delete(session.id), delay);
2209
2222
  });
2210
2223
  }
2211
2224
  }, [enabled, endStaleBrowser, registry.sessions]);
@@ -4678,6 +4691,7 @@ export {
4678
4691
  useBrowserSession,
4679
4692
  useBrowserDownloads,
4680
4693
  useBrowserFrameStream,
4694
+ staleBrowserEndRetryDelayMs,
4681
4695
  BrowserViewer
4682
4696
  };
4683
- //# sourceMappingURL=chunk-2OQA3CPB.js.map
4697
+ //# sourceMappingURL=chunk-CESBPQP5.js.map